【问题标题】:How to prevent JavaFX ListView from being preselected?如何防止 JavaFX ListView 被预选?
【发布时间】:2014-10-31 19:24:01
【问题描述】:

我是 JavaFX 新手,所以这可能是一个微不足道的问题。我在用户单击菜单按钮时显示的对话框中有一个 ListView。问题是当对话框显示时,ListView 中的第一项已被选中。当用户选择一个项目时,我将listView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<NewChoices>()) 作为监听器,但由于第一个项目已经被选中,所以当我点击第一个项目时没有任何反应。我需要找到一种方法来确保对话框显示时没有选择任何项目。我在显示对话框之前尝试使用listView.getSelectionModel().clearSelection(),但是如果程序丢失然后重新获得焦点,则会再次选择第一项而不被单击。如何防止第一个项目或任何项目被预选?

代码如下:

    Pane rootPane = new Pane();
    ObservableList<NewChoices> listChoices = FXCollections.observableArrayList(NewChoices.values());
    ListView<NewChoices> listView = new ListView<NewChoices>();
    listView.setItems(listChoices);
    rootPane.getChildren().add(listView);
    Stage newDialog = new Stage(StageStyle.UTILITY);
    newDialog.initModality(Modality.APPLICATION_MODAL);
    newDialog.setTitle("New");
    Scene newDialogScene = new Scene(rootPane);
    newDialog.setScene(newDialogScene);
    newDialog.show();

【问题讨论】:

  • 您使用什么 API 来显示对话框? JDK8_40?控制FX?自定义场景?除了该对话框上的列表之外,还有其他控件吗?
  • 我认为我正在使用 JDK8_24。我现在不在我的电脑旁,所以我不记得确切的那个了,但它是 JDK8_2something。不,它只是对话框中的列表视图。
  • 由于直到 8u40 之前还没有对话,我认为你所说的对话只是一个常规场景。如果那里只有一个列表(没有关闭所谓对话框的按钮?),我的猜测是当场景获得焦点时,因为唯一可聚焦的节点是列表,它的第一项被选中。添加一些确定/取消按钮可能会有所帮助,因为它们可以获得焦点。也许你可以添加一个MCVE
  • 对话框只是一个普通的舞台和场景,但它的右上角只有一个退出按钮,它会阻止对程序其余部分的输入。我将尝试添加一些确定/取消按钮,看看是否有效。如果我仍然遇到问题,我会在此处发布代码,以便您了解我哪里出错了。
  • 我尝试添加一个按钮,但没有帮助。我现在将发布一些代码。

标签: java listview user-interface javafx


【解决方案1】:

应该在 8u40 中修复 - 请参阅 https://javafx-jira.kenai.com/browse/RT-38517

【讨论】:

  • 现在对我没用了。
【解决方案2】:

由于您的新场景只有一个列表,没有按钮,因此当场景获得焦点时,由于唯一可聚焦的节点是列表,因此它的第一项被选中。

添加一些确定/取消按钮可能会有所帮助,因为它们可以获得焦点,但为此它们需要首先获得焦点。

这两个选项中的任何一个都可以:

  • 将按钮放在首位,使其成为第一个可聚焦节点:

    listView.setItems(listChoices);
    Button button = new Button("Ok");
    
    VBox rootPane = new VBox(10, button, listView);
    
    Stage newDialog = new Stage(StageStyle.UTILITY);
    newDialog.initModality(Modality.APPLICATION_MODAL);
    newDialog.setTitle("New");
    Scene newDialogScene = new Scene(rootPane);
    newDialog.setScene(newDialogScene);
    newDialog.show();
    
  • 暂时移除列表的可聚焦属性:

    listView.setItems(listChoices);
    listView.setFocusTraversable(false);
    
    Button button = new Button("Ok");
    VBox rootPane = new VBox(10, listView, button);
    Stage newDialog = new Stage(StageStyle.UTILITY);
    newDialog.initModality(Modality.APPLICATION_MODAL);
    newDialog.setTitle("New");
    Scene newDialogScene = new Scene(rootPane);
    newDialog.setScene(newDialogScene);
    newDialog.show();
    
    listView.setFocusTraversable(true);
    

无论如何,两者都需要一个额外的节点。无论如何,您需要它来关闭模态阶段,对吧?

如果您仍然想不使用按钮,您可以使用已解决问题的 JDK 8u40 早期版本,正如@wzberger 指出的那样,或者如果这不可能,请使用 ControlsFX 新的Dialogs API(一个 fork JDK 8u40 中的 API),您不会有任何问题。

    listView.setItems(listChoices);
    final Dialog dialog = new Dialog();
    dialog.getDialogPane().setContent(listView);

    Optional<ButtonType> result = dialog.showAndWait();

【讨论】:

  • 我不需要额外的节点来关闭模态阶段。它已经有一个退出按钮。理想情况下,我不必有额外的节点。你确定没有其他方法可以解决这个问题吗?
  • 我没有看到那个按钮,你把它放在哪里?
  • 不是我自己放进去的,它是自动存在的,就像普通舞台上的最大化/最小化按钮一样。
  • 正如@wzberger 所说,这是一个错误......我已经向您展示了三种不同的解决方法。如果你问我,我不会有一个没有确定/取消按钮的模式窗口。所以在底部添加一个来关闭舞台对你来说应该不是问题。
猜你喜欢
  • 2015-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
相关资源
最近更新 更多