首页 文章

Combobox清算 Value 问题

提问于
浏览
19

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

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

EDIT 2014/08/27:
这正式不是bug(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);

8 回答

  • 16

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

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

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

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

    希望能帮助到你 :)

  • 1

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

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

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

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

  • 15

    我使用反射直接操作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实现也是可能的

  • 3

    我遇到了几乎完全相同的情况,并在寻找解决方案时遇到了你的问题 . 幸运的是,我想出了一个强制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()方法 .

  • 2

    要清除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中找到,但请注意,如果应用程序中的每个自定义组件都已经有一个带有start(Satge stage)方法的入口点类,则不需要CustomControlExample类 .

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

  • 0

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

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

    我希望这适合你:-D

  • 9

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

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

相关问题