3

我想我可能在 Java 中发现了一个错误,或者我做错了什么。

我根据一些接收到的数据填充了一个容器。容器有一个或多个组合框。在 ComboBox 选择更改时,我收到新数据。然后我清除 GridPane 并重新添加节点(新数据中仍然存在,和/或添加新节点)。

ComboBox 仍然有焦点,但我无法在点击时再次激活它。任何导致 ComboBox 失去焦点的事情(例如聚焦另一个组件)都会导致它再次工作。

这是一个简化的例子。尝试使用 jdk1.8.0_162 和 jdk-9.0.4

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ComboBoxTest extends Application {

    public static void main(String[] args) {
        ComboBoxTest.launch(args);
    }

    @Override
    public void start(Stage stage) {
        VBox root = new VBox();

        final ComboBox<String> choices = new ComboBox<>();
        choices.getItems().add("Test1");
        choices.getItems().add("Test2");
        root.getChildren().add(choices);

        choices.getSelectionModel().selectedItemProperty().addListener(
            (observable, oldValue, newValue) -> {
                root.getChildren().clear();
                root.getChildren().add(choices);
        });

        Platform.setImplicitExit(true);
        stage.setScene(new Scene(root));
        stage.show();
    }
}

设计是动态的。我有一个从服务器接收到的值列表。这用于在网格上创建和放置 ComboBox。当用户更改 ComboBox 中的选择时,它会从服务器接收一个新的值列表。此列表可能仍包含与网格中现有节点相对应的值。它们被重用而不是重新创建。

4

1 回答 1

2

只是为了不松散原因和解决方案,作为对 sillyfly 已删除答案的评论发布(发布您自己的,我将删除它:)

关于根本原因/问题的一点猜测 - 更改导致 ComboBox 在其列表(从技术上讲是不同的阶段)显示时消失。我的猜测是,这让它处于一个不确定的状态,它认为列表仍在显示,但它从不隐藏,所以它不会重置。在这种情况下,也许调用 ComboBox::hide 也可以

如果您通过键盘更改选择(在这种情况下下拉菜单未打开),您可以看到这个假设是正确的:仍然可以通过键盘和鼠标访问组合。因此,在删除之前隐藏下拉列表确实是解决方案。

在代码中(迈克尔编辑中的简化示例)

public class ReaddFocusedCombo extends Application {

    @Override
    public void start(Stage stage) {
        VBox root = new VBox();

        final ComboBox<String> choices = new ComboBox<>();
        choices.getItems().add("Test1");
        choices.getItems().add("Test2");
        root.getChildren().add(choices);

        choices.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            // guess by sillyfly: combo gets confused if popup still open 
            choices.hide();
            root.getChildren().clear();
            root.getChildren().add(choices);
            // suggested in answer: working but then the choice isn't focused
            //root.requestFocus();
            // doesn't work
            //  choices.requestFocus();
        });

        stage.setScene(new Scene(root));
        stage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }

}

更新:在 bug parade 中进行一点搜索发现了一个类似的错误行为,即添加了一个显示组合,该组合在初始附加到场景时是固定的,但错过了动态用例。为后者提交了一个新问题。

于 2018-01-31T11:25:50.117 回答