JavaFX 8 filtered ComboBox throws IndexOutOfBoundsException when popup clicked [duplicate]

匆匆过客 提交于 2020-01-05 04:52:49

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!