Combobox清算价值问题

时间:2012-08-27 13:01:55

标签: combobox javafx-2 javafx-8 selectionmodel

我在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”按钮再次打开窗格时,我注意到只有“固定项目”组合框已清除其选择,动态填充的组合框显示最后选择的项目,尽管选择本身的值为{ {1}}。这看起来像是一个图形错误,或者我做错了什么?

是否有解决此问题的方法或重置组合框的最佳方法是什么?

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

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

null

8 个答案:

答案 0 :(得分:17)

我遇到了几乎完全相同的情况,并在寻找解决方案时遇到了你的问题。幸运的是,我想出了一个强制ComboBoxes重置的解决方法。重置窗格中的数据时,而不是执行以下操作:

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

做这样的事......

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

您还需要在ComboBox上再次执行setItems(),以便填充新的。这不是一个理想的解决方案,但它似乎正在工作,因为我期望提供clearSelection()方法。

答案 1 :(得分:17)

很简单。您只需使用ComboBox的value属性即可。你去吧....

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

我希望这适合你:-D

答案 2 :(得分:9)

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

cboVet.getItems().removeAll(cboVet.getItems());

答案 3 :(得分:3)

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

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

希望有所帮助:)

答案 4 :(得分: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实现也是可能的

答案 5 :(得分:1)

我遇到了与ComboBox相同的问题。当我更改ComboBox的项目时,ComboBox的buttonCell未正确更新。这看起来像一个图形错误。

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

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

这是我发现的最佳解决方案,无需重新创建ComboBox。

答案 6 :(得分: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中找到,但请注意,如果应用程序中的每个自定义组件都已经有一个带入口的入口点类(Satge),则不需要CustomControlExample类阶段)方法。

如何通过自定义组件控制器类引用到主控制器类来解决可能的错误,请参见JavaFx: how to reference main Controller class instance from CustomComponentController class?

答案 7 :(得分:1)

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

 List<Object> list = new ArrayList<>(comboBox.getItems());
 comboBox.getItems().removeAll(list);
 comboBox.getItems().addAll(list);