【问题标题】:JavaFX ComboBox becomes unclickable after removal and re-addingJavaFX ComboBox 在删除和重新添加后变得不可点击
【发布时间】:2018-01-31 09:33:00
【问题描述】:

我想我可能在 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 中的选择时,它会从服务器接收新的值列表。此列表可能仍包含与网格中现有节点相对应的值。它们被重用而不是重新创建。

【问题讨论】:

  • 为什么要更改示例?请不要发布诸如移动子弹之类的问题..您可以免费获得我们的时间,因此请尽可能轻松地关注(或领导
  • @Michael 通常编辑不应该触及代码,除非是像格式化或修复错别字这样的小改动;)但我同意你的观点:你的例子是严格的,让 sillyfly(在对现在已删除的答案)正确猜测根本原因
  • 我更改了示例,因为它是错误的。这是一个较早的例子。我需要演示一个带有两个复选框的示例。编辑:所以你改变了我的例子。为什么,我以为我发错了。
  • 添加了第二个 ComboBox 以说明该组合框有效,而第一个组合框被锁定。如果您编辑其他人的示例,请对其添加评论...
  • @Michael 在答案中使用了您的最小示例,谢谢 :) 在 OP:是否有第二个组合或更改项目以及删除/读取与 IMO 无关

标签: java javafx javafx-8 javafx-9


【解决方案1】:

只是为了不松散理由和解决方案,作为对 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 队列中稍作搜索会发现 similar misbehaviour 添加显示组合,该组合在初始附加到场景时已修复,但错过了动态用例。后者提交a new issue

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-28
    • 2013-04-05
    • 1970-01-01
    相关资源
    最近更新 更多