javafx - 修改基础数据时,组合框会触发动作事件
问题描述
我一直在为这个问题困惑了一段时间,只是想看看其他人之前是否遇到过这个问题,或者我是否做错了什么。
给定一个 javafx 实现,其中我们使用一个组合框,它的项目从一个ObservableArrayList
可以更新、修改、替换等的组合框和一个带有动作侦听器的组合框在触发时退出。
package sample;
import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
public class Main extends Application {
ObservableList<String> theList = FXCollections.observableArrayList();
@Override
public void start(Stage primaryStage) throws Exception{
primaryStage.setTitle("Sample");
FlowPane root = new FlowPane(Orientation.VERTICAL);
root.setVgap(20);
List<String> initialColors = Arrays.asList("red", "green", "blue", "black");
theList.addAll(initialColors);
ComboBox<String> theComboBox = new ComboBox<>();
theComboBox.setItems(theList);
theComboBox.setOnAction( event -> {
System.out.println(String.format("theComboBox action listener triggered, current value is %s", theComboBox.getValue()));
});
Button bttn1 = new Button("Press me");
bttn1.setOnAction(event -> {
List<String> someColors = Arrays.asList("red", "orange", "mauve", "pink", "blue", "salmon", "chiffon");
System.out.println("About to issue setAll against observable list");
theList.setAll(someColors);
});
root.getChildren().add(theComboBox);
root.getChildren().add(bttn1);
primaryStage.setScene(new Scene(root, 100, 150));
primaryStage.show();
System.out.println("Setting initial selection to \"blue\"");
theComboBox.setValue("blue");
}
public static void main(String[] args) {
launch(args);
}
}
我认为仅当用户通过直接操作更改组合框时才应触发操作事件,但我在修改 observablelist 时看到事件触发。
我们正在使用 javafx 版本 11.0.2
我应该将其记录为 Gluon 的错误吗?
编辑:更新示例
在此示例中,您可以看到每当通过setAll
操作事件修改基础数据时都会触发。如果动作事件有某种方式来区分它是来自直接用户交互还是来自对底层数据的编程更改,这将很好。
其他奇怪的行为,如果您选择“黑色”然后点击“按我”按钮,则不会触发动作事件,然后组合框将选择粉红色,因为它在列表中的相同位置 - 但然后选择红色甚至粉红色再次,您将分别得到 null、red、null 和 null、pink、null。
即使选择不再存在,我也希望组合框保持其值,并且我也不希望在修改可观察列表时触发这些事件 - 如果您需要/想要在可观察列表时监听事件已修改,您可以直接将侦听器附加到它。
解决方案
总结一下,请查看有关该问题的评论以获取更多详细信息。
我们认为这是 javafx 11.0.2 中的一个错误——我已经通过 openjdk jira 提交了一个错误报告。
目前的一种解决方法是设置一个标志布尔变量,并且仅当它为真时才在侦听器中执行操作。
像添加这样简单的东西:
private boolean actionEventsOn = true;
theComboBox.setOnAction( event -> {
if(actionEventsOn){
System.out.println(String.format("theComboBox action listener triggered, current value is %s", theComboBox.getValue()));
}
});
bttn1.setOnAction(event -> {
List<String> someColors = Arrays.asList("red", "orange", "mauve", "pink", "blue", "salmon", "chiffon");
System.out.println("About to issue setAll against observable list");
actionEventsOn = false;
theList.setAll(someColors);
actionEventsOn = true;
});
这应该可以防止不必要地触发动作事件。
推荐阅读
- python - 对于 sql 查询,如何考虑可能传递或不传递的参数?
- r - 是否可以在不给它一个对象的情况下运行一个函数?
- scala - 更新对象的 RDD
- xml - XSLT 条件比较不同元素之间的属性
- amazon-web-services - Azure DevOps 运行 Ansible Playbook
- sql - 如何在 SQL 中合并/合并/添加两个数组以形成一个新数组?
- python - 为什么我的瓶子服务器工作以命令 python 开始,而不是 python3?
- android - 从 xamarin Visual Studio 2019 上传发布版本时出错
- python - Python Requests 向任何 GET 或 POST 请求添加额外的标头
- excel - 将带有多个附件的电子邮件发送给多个收件人