YellowSub
YellowSub

Reputation: 179

JavaFX Combobox listener for user changes only

I tried to implement a listener on a ComboBox that validates the user's selection and resets it to the previous value if the selection is invalid.

My problem now is that the listener on valueProperty or selectedItemProperty also recognizes programmatically made changes e.g. when the user selects another entity, which subsequently changes the ComboBox value.

Is there any way to implement a listener that only listens for changes committed by the user?

        stateComboBox.valueProperty().addListener(new ChangeListener<State>() {

        @Override
        public void changed(ObservableValue<? extends State> observable, State oldValue,
                State newValue) 
        {
            if(stateCheckActive==false) return;
            if(newValue==null||oldValue.equals(newValue)) return;

            currentDocument.getBean().setStatus(oldValue);      

            if(service.changeStateAllowed(currentDocument.getBean(), newState.getId().getNr(), true))
            {
                stateCheckActive=false;

                newDocument=service.updateDocument(currentDocument.getBean());
                currentDocument.setBean(newDocument);

                stateCheckActive=true;
            }
            else 
            {
                Platform.runLater(new Runnable() {

                    @Override
                    public void run() 
                    {
                        stateCheckActive=false;
                        statusComboBox.setValue(oldValue);
                        stateCheckActive=true;
                    }
                });

            }

        }
    });

Upvotes: 1

Views: 3309

Answers (1)

Sunflame
Sunflame

Reputation: 3186

Do you need something like this?

public class Controller implements Initializable {

    @FXML
    private ComboBox<String> comboBox;

    private ChangeListener<? super String> listener = (observable, oldValue, newValue) -> {
        if (!newValue.matches("[A-Z]*")) { // put your validation here
            comboBox.getSelectionModel().selectedItemProperty().removeListener(getListener());
            Platform.runLater(() -> {
                comboBox.getSelectionModel().select(oldValue);
                comboBox.getSelectionModel().selectedItemProperty().addListener(getListener());
            });
        }
    };

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        ObservableList<String> items = FXCollections.observableArrayList();
        items.add("VALID");
        items.add("MATCHES");
        items.add("NotMatches");
        items.add("RandomValue");
        comboBox.setItems(items);
        comboBox.getSelectionModel().select(0);
        comboBox.getSelectionModel().selectedItemProperty().addListener(getListener());
    }

    private ChangeListener<? super String> getListener() {
        return listener;
    }

}

Upvotes: 1

Related Questions