2014-09-27 49 views
1

我有一个ComboBox cbObservableList<StringProperty> data 我已绑定的cbItemsdata如下:组合框不示出界限值

Bindings.bindContent(cb.getItems(), data); 

假设data有以下三个项目:str1, str2, str3, str4

当我改变了data,组合框获得了新的列表没有任何问题。 但是,如果在cb中选择了str3,并且我在数据中将str3的值更改为NewStr3,则该更改不会显示在cb中。有时显示的列表也是错误的(它显示str3而不是NewStr3),尽管它所引用的基础数据是正确的。

如何在组态框更改时强制组合框显示新值?

+0

选择行为并不完全直观和错误:明确的设置是故意的拒绝https://javafx-jira.kenai.com/browse/RT-19820(虽然未注释,@James_D明白了非常正确,国际海事组织),行为更新是越野车https://javafx-jira.kenai.com/browse/RT-38394。不总是显示弹出窗口中的变化听起来像一个虚假的bug:https://javafx-jira.kenai.com/browse/RT-29709被关闭,因为cannotreproduce - 如果你有一个例子,证明这种不正当行为 – kleopatra 2014-09-28 12:02:53

回答

2

组合框中的选定项目不需要是组合框项目列表的一个元素。 (例如,在一个可编辑的组合框中,您可以输入一个不在列表中的项目。)如果从这个角度考虑您的示例,它就像您描述的那样行事并不奇怪。

如果您希望在列表可能更改时强制将选定值作为基础列表的元素,则需要定义如果列表以不再包含该列表的方式进行更改时,所选项目应如何更改选择的项目(这是不明显的,你会怎么做,可能取决于你的应用程序逻辑)。一旦你知道你想做什么,你可以用ListChangeListener实现它:

cb.getItems().addListener((ListChangeListener.Change change) -> { 
    String newSelectedItem = ... ; // figure item that should be selected instead 
    cb.setValue(newSelectedItem); 
}); 

最简单的实现将只是cb.setValue(null);,这意味着没有项目被选中,如果列表改变,使其不再含有当前选定的项目。

+0

感谢您的解释。我甚至不必写这个听众。刚刚添加并从列表中删除了一个虚拟对象,它会自动获取更改。你可以编辑你的答案来包含这个。接受你的回答,因为它在理想世界中指向正确的方向 – sinu 2014-09-28 08:50:35

+0

@sinu,你可以实现一个自定义选择模型来封装你所需要的任何东西 - 不幸的是,选择行为的实现在选择框,它的外观和choiceboxSelectionModel上被抹掉,重新编写(就像我的git中的ChoiceBoxX,这是作为一个明确区分责任的优点的POC) – kleopatra 2014-09-28 12:08:37

-1

哎呀......误读下拉框中的choiceBox - 而这个答案的基础知识,同时适用于combo-和choiceBox,我没有定制ComboBoxX - 但:-)

基本上, SelectionModel有责任对项目的更改进行更新。核心中实现的预期行为是完全清除选择 - 即,将selectedItem归零并将selectedIndex设置为-1 - 如果旧项目是selectedItem并被替换或删除。自定义的行为典型的解决方案是实现一个自定义选择模型,并将其设置:

/** 
* A SelectionModel that updates the selectedItem if it is contained in 
* the data list and was replaced/updated. 
* 
* @author Jeanette Winzenburg, Berlin 
*/ 
public static class MySelectionModel<T> extends ChoiceBoxSelectionModel<T> { 

    public MySelectionModel(ChoiceBoxX<T> cb) { 
     super(cb); 
    } 

    @Override 
    protected void itemsChanged(Change<? extends T> c) { 
     // selection is in list 
     if (getSelectedIndex() != -1) { 
      while (c.next()) { 
       if (c.wasReplaced() || c.wasUpdated()) { 
        if (getSelectedIndex() >= c.getFrom() 
          && getSelectedIndex() < c.getTo()) { 
         setSelectedItem(getModelItem(getSelectedIndex())); 
         return; 
        } 
       } 
      } 
     } 
     // super expects a clean change 
     c.reset(); 
     super.itemsChanged(c); 
    } 
} 

// usage 
myChoiceBox.setSelectionModel(new MySelectionModel(myChoiceBox)); 

不幸的是,核心choiceBox不按照规则玩 - 它严重与模型的职责(可能是因为模型实现没有按”干扰不需要承担其职责),这需要完整地重写整个合作者堆栈(choiceBox, - 皮肤,复制 - 行为),例如ChoiceBoxX - 我只是想了解一下,尝试删除它的一些气味,修复一些错误。