javafx - 组合框在修改基础数据时触发操作事件

标签 javafx combobox javafx-11

我一直对这个问题感到困惑一段时间,只是想看看其他人之前是否遇到过这个问题,或者我是否做错了什么。
给定一个 javafx 实现,其中我们使用一个组合框,其项目是从 ObservableArrayList 设置的。可以更新、修改、替换等,还有一个带有 Action 监听器的组合框,只要它被触发就会注销。

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 修改基础数据时 Action 事件被触发。如果操作事件有某种方式来区分它是来自直接的用户交互还是来自对基础数据的编程更改,那么这会很好。
其他奇怪的行为,如果您选择“黑色”然后点击“按我”按钮,则不会触发 Action 事件,然后组合框将选择粉红色,因为它在列表中的位置相同 - 但然后选择红色甚至粉红色再次,您将分别获得 null、red、null 和 null、pink、null。
即使选择不再存在,我也希望组合框保留其值,并且我也不希望在修改可观察列表时触发这些事件 - 如果您需要/想要在可观察列表时监听事件修改后,您可以直接将监听器附加到它。

最佳答案

为了总结一下,请查看对该问题的评论以获取更多详细信息。
我们认为这是 javafx 11.0.2 中的一个错误 - 我已经通过 openjdk jira 提交了一个错误报告。
现在的解决方法是设置一个标志 bool 变量,并且仅在它为真时才在监听器中执行操作。
像添加一样简单的东西:

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;
});
这应该可以防止不必要地触发 Action 事件。

关于javafx - 组合框在修改基础数据时触发操作事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66674211/

相关文章:

c# - 更改 ComboBox 边框轮廓颜色

java - 如何使形状仅在for循环中出现一次?

vba - 在主窗体的子窗体中驱动 MS Access 查询

Javafx tableview 未在所有列中显示数据

Java swing gridbaglayout没有完全填满一行

JavaFX 11 不可编辑的 ComboBox 未正确显示组合项列表之外的值

java - Badass 运行时建议模块 NPE 问题

java - 无法在Windows上使用JavaFX 11运行Maven着色jar

mysql - javafx scenebuilder中的分页与tableview

css - 如何在JavaFX图表中动态更改符号/点的大小?