23

我偶然发现了 javafx2.2 中 Comboboxes 的问题。这是场景:

  • 用户单击“editFile”按钮。
  • 另一个窗格变得可见(使用 setVisible 方法)。

此窗格包含 6 个组合框。其中三个有固定项目:cboReport、cboSales、cboSend。其中三个从 db (ObservableList) 获取数据并在窗格可见时填充:cboFile、cboCustomer、cboVet

  • 用户从 cboFile 中选择一个文件号。其余的组合框正在设置正确的值。
  • 用户按下保存按钮,文件按预期保存。
  • 接下来,用户按下关闭按钮。

当窗口关闭时,窗格上的数据通过 resetGUI_editFilePane() 方法重置。有这样的行:

...
cboReport.getSelectionModel().clearSelection();
cboSales.getSelectionModel().clearSelection();
cboSend.getSelectionModel().clearSelection();
cboFile.getSelectionModel().clearSelection();
cboCustomer.getSelectionModel().clearSelection();
cboVet.getSelectionModel().clearSelection();

cboFile.getItems().clear();
cboCustomer.getItems().clear();
cboVet.getItems.clear();
...

当用户通过按下“editFile”按钮再次打开窗格时,我注意到只有“固定项目”组合框已清除其选择,动态填充的组合框显示最后选择的项目,尽管选择本身的值为null. 这对我来说看起来像是一个图形错误,还是我做错了什么?

有没有办法解决这个问题或者重置组合框的最佳方法是什么?

编辑 2014/08/27:
这正式不是错误(clearSelection() 不清除值):
https ://bugs.openjdk.java.net/browse/JDK-8097244

官方的“解决方法”是清除选择后清除ComboBox的值。

cb.getSelectionModel().clearSelection();
// Clear value of ComboBox because clearSelection() does not do it
cb.setValue(null);
4

8 回答 8

25

这很简单。您只需要使用 ComboBox 的 value 属性。干得好 ....

ComboBox c;
c.valueProperty().set(null);

我希望这对你有用:-D

于 2013-12-06T09:48:44.853 回答
20

I ran into nearly the exact same situation and came across your question while looking for a solution. Fortunately, I came up with a workaround that forces the ComboBoxes to reset. When you reset the data on your pane, instead of doing something like:

cboVet.getSelectionModel().clearSelection();
cboVet.getItems.clear();

do something like this...

parentNode.getChildren().remove(cboVet);
cboVet = new ComboBox();  // do whatever else you need to format your ComboBox
parentNode.add(cboVet);

You'll also need to do a setItems() again on your ComboBox so the new one will be populated. This is not an ideal solution but it seems to be working as I expect the provided clearSelection() method would.

于 2012-11-09T19:26:28.290 回答
8

您可以检索这些项目并将它们全部删除:

cboVet.getItems().removeAll(cboVet.getItems());
于 2013-01-06T14:43:42.427 回答
3

我刚刚使用 Java JDK 1.7.11 测试了一个可行的解决方案:

combobox.setSelectedItem(null);
combobox.setValue(null);

希望能帮助到你 :)

于 2013-03-14T17:09:20.183 回答
2

我使用反射直接操作 ComboBox 皮肤中的 buttonCell 字段:

@SuppressWarnings({ "rawtypes", "unchecked" })
public static <T> void resetComboBox(ComboBox<T> combo) {
    Skin<?> skin = combo.getSkin();
    if(skin==null){
        return;
    }
    combo.setValue(null);
    Field buttonCellField;
    try {
        buttonCellField = skin.getClass().getDeclaredField("buttonCell");
        buttonCellField.setAccessible(true);
        ListCell buttonCell = (ListCell) buttonCellField.get(skin);
        if(buttonCell!=null){
            StringProperty text = buttonCell.textProperty();
            text.set("");
            buttonCell.setItem(null);
        }
    } catch (NoSuchFieldException 
            | SecurityException 
            | IllegalArgumentException 
            | IllegalAccessException e) {
        e.printStackTrace();
    }

}

我认为也可以通过 buttonCellFactory 属性提供自己的 buttonCell 实现

于 2012-11-19T15:39:56.630 回答
1

我对组合框有同样的问题。当我更改 ComboBox 的项目时,ComboBox 的 buttonCell 未正确更新。这看起来像一个图形错误。

我使用 ComboBox 中 buttonCell 字段的直接操作。

combo.getButtonCell().setText("");
combo.getButtonCell().setItem(null);

这是我在不重新创建 ComboBox 的情况下找到的最佳解决方案。

于 2013-03-01T16:17:46.713 回答
1

要清除 SelectionModel 我发现没有比创建 Combobox 的新实例更好的了(以前的答案更新):

myParentNode.getChildren().remove(myCombobox);
myCombobox = new ComboBox();
myParentNode.add(myCombobox);

但是这个解决方案会产生其他问题:如果你使用 fxml,这个组合框将被放置在错误的位置和错误的参数。一些 fxml 参数很难直接从您的控制器类代码中复制,每次您需要清除组合框时都这样做很糟糕。

解决方案是使用自定义组件,而不是直接在主控制器类代码中创建实例,即使这些组件是标准的。这也有助于释放主控制器类中的某些行,方法是将组件相关的事件方法和其他方法移动到单独的类文件中,在其中使用对主控制器类的引用。

如何在 JavaFX FXML 应用程序中创建自定义组件可以在http://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm中找到,但请注意,如果您的应用程序中的每个自定义组件都不需要 CustomControlExample 类,则它已经有一个带有 start(Satge stage) 方法的入口点类。

如何解决从自定义组件控制器类到主控制器类的引用可能出现的错误可以在JavaFx 中找到:如何从 CustomComponentController 类中引用主控制器类实例?

于 2013-07-08T16:32:36.573 回答
1

我需要清除组合框的选择。这段代码对我有用:

 List<Object> list = new ArrayList<>(comboBox.getItems());
 comboBox.getItems().removeAll(list);
 comboBox.getItems().addAll(list);
于 2018-07-03T19:20:04.287 回答