JavaFX ComboBox OnChangeListener rollback change



I’m trying to reset the selection of a ComboBox like follows:

// private ListView<MyEntityType> f_lItems

f_lItems.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>() {
    public void changed(ObservableValue<?> ov, Object t, Object t1) {
        if (t1 != null && t1 instanceof MyEntityType) {

            MyEntityType pv = (MyEntityType) t1;
            // do some condition testing
            if (condition) {
                // accept 
            } else 
                // roll back to previous item
                f_lItems.getSelectionModel().select((MyEntityType) t);

So, after trying to reset the list to the old value I get this Exception:

Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException
    at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.subList(Unknown Source)
    at javafx.collections.ListChangeListener$Change.getAddedSubList(Unknown Source)
    at com.sun.javafx.scene.control.behavior.ListViewBehavior.lambda$new$177(Unknown Source)
    at javafx.collections.WeakListChangeListener.onChanged(Unknown Source)
    at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(Unknown Source)

As it seems I don’t get the underlying behaviour of Lists / ObservableLists for this case.

Does anyone have suggestions how I could make this work?

Thanks in advance





Based on your comment what you want is: When the (selected) value of the ComboBox is changed, check for a condition and then if this condition is not met, set back the value of the ComboBox value to the previous one.

For this you can use for example the valueProperty of the ComboBox with a listener. The listener body is just to check for the condition and the value update is nested in a Platform.runLater{...} block.


In the example it is a ComboBox which can be set only to “Two”.

ComboBox<String> cb = new ComboBox<String>(FXCollections.observableArrayList("One", "Two", "Three", "Four"));

cb.valueProperty().addListener(new ChangeListener<String>() {

    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
        // If the condition is not met and the new value is not null: "rollback"
        if(newValue != null && !newValue.equals("Two")){

            Platform.runLater(new Runnable(){
                public void run() {

… or you can use the selectedItemProperty also with the same structure …

cb.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal)->{
    if(newVal != null && !newVal.equals("Two")){
        Platform.runLater(() -> cb.setValue(oldVal));

Note: This solution is not to “prevent” the selection, just as in the title: “roll-back” an already performed selection.


Facebook Comments

Post a comment