问题
I am running Java 8u102. I have a modal window that contains a Combobox
whose items are a FilteredList
created from a list of Strings. The ComboBox
is editable so that the user can enter text (automatically converted to uppercase). The items in the ComboBox
popup are then filtered such that only those items that start with the entered text remain. This works great.
The problem is that when you click an item in the filtered popup, the selected item will be properly displayed in the combobox editor and the popup will close, but an IndexOutOfBoundsException
is thrown, probably starting in the code that created the window at the line - stage.showAndWait()
. Below is the code running the ComboBox
.
Any suggestions for a work-around? I plan to add more functionality to the combobox, but I'd like to deal with this issue first. Thanks.
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
}
});
});
回答1:
The problem is the same as in this question: You can wrap the content of the listener on the textProperty
into a Platform.runLater
block.
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
});
});
});
Or the same in short form using ternary operator:
cb.getEditor().textProperty().addListener((ov, oldValue, newValue) -> Platform.runLater(
() -> filteredList.setPredicate(item -> (item.startsWith(newValue)) ? true : newValue.isEmpty())));
来源:https://stackoverflow.com/questions/39712765/javafx-8-filtered-combobox-throws-indexoutofboundsexception-when-popup-clicked