2014-09-27 51 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 - 我只是想了解一下,嘗試刪除它的一些氣味,修復一些錯誤。