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/

相关文章:

java - IntelliJ IDEA - 错误 : JavaFX runtime components are missing,,需要运行此应用程序

JavaFX TextField.setPrefColumnCount() 不起作用

combobox - Excel VBA 组合框返回索引而不是值

java - 使用 javafxplugin 和 hibernate 时无法在 IDE 外部运行 JavaFX 应用程序

CSS组合框下拉位置

c# - 更改 ComboBox 项的格式

java - 如何设置多个 ImageView 的样式以不违反 JavaFX 11 中的 DRY

java - 菜单样式 CSS Java

更新到 Java 1.8u40 后,JavaFx/Swing 窗口无法打开

java - 如何使用maven项目在JavaFX中生成可执行jar