2016-09-26 30 views
1

我正在運行Java 8u102。我有一個模式窗口,其中包含Combobox,其中的項目是從字符串列表創建的FilteredListComboBox是可編輯的,以便用戶可以輸入文本(自動轉換爲大寫)。彈出的ComboBox中的項目將被過濾,只有那些以輸入文本開頭的項目纔會保留。這很好。JavaFX 8已過濾組合框在彈出窗口單擊時拋出IndexOutOfBoundsException

問題是,當您單擊篩選彈出窗口中的項目時,所選項目將在組合框編輯器中正確顯示,並且彈出窗口將關閉,但會引發IndexOutOfBoundsException,可能從創建窗口的代碼開始在線 - stage.showAndWait()。以下是運行ComboBox的代碼。

任何解決方法的建議?我打算爲組合框添加更多功能,但我想首先處理這個問題。謝謝。

FilteredList<String> filteredList = 
    new FilteredList(FXCollections.observableArrayList(myStringList), p -> true); 
    cb.setItems(filteredList); 
    cb.setEditable(true); 

    // convert text entry to uppercase 
    UnaryOperator<TextFormatter.Change> filter = change -> { 
    change.setText(change.getText().toUpperCase()); 
    return change; 
    }; 
    TextFormatter<String> textFormatter = new TextFormatter(filter); 
    cb.getEditor().setTextFormatter(textFormatter); 

    cb.getEditor().textProperty().addListener((ov, oldValue, newValue) -> { 
    filteredList.setPredicate(item -> { 
     if (item.startsWith(newValue)) { 
      return true; // item starts with newValue 
     } else { 
      return newValue.isEmpty(); // show full list if true; otherwise no match 
     } 
    }); 
    }); 

回答

2

的問題是一樣this question:你可以用聽衆對textProperty內容爲Platform.runLater塊。

cb.getEditor().textProperty().addListener((ov, oldValue, newValue) -> { 
    Platform.runLater(() -> { 
     filteredList.setPredicate(item -> { 
      if (item.startsWith(newValue)) 
       return true; // item starts with newValue 
      else 
       return newValue.isEmpty(); // show full list if true; otherwise no match 
     }); 
    }); 
}); 

或者使用ternary operator總之形式是相同的:

cb.getEditor().textProperty().addListener((ov, oldValue, newValue) -> Platform.runLater(
     () -> filteredList.setPredicate(item -> (item.startsWith(newValue)) ? true : newValue.isEmpty()))); 
+0

偉大的答案。它支持我的初學者傾向,即當JavaFx中的某些事情有點「愚蠢」時,我是那些不認識併發問題並且應該考慮Platform.runLater(() - > {})的愚蠢者;有趣的是,同一天有人提出類似的問題(並由您回答)。非常感謝。 –

相關問題