JavaFX组合框侦听器仅用于用户更改

JavaFX组合框侦听器仅用于用户更改,javafx,javafx-8,Javafx,Javafx 8,我尝试在组合框上实现一个侦听器,该侦听器验证用户的选择,如果选择无效,则将其重置为上一个值 我现在的问题是valueProperty或SelectEditeProperty上的侦听器还可以识别以编程方式进行的更改,例如,当用户选择另一个实体时,随后会更改ComboBox值 有没有办法实现一个只监听用户提交的更改的侦听器 stateComboBox.valueProperty().addListener(new ChangeListener<State>() {

我尝试在组合框上实现一个侦听器,该侦听器验证用户的选择,如果选择无效,则将其重置为上一个值

我现在的问题是valueProperty或SelectEditeProperty上的侦听器还可以识别以编程方式进行的更改,例如,当用户选择另一个实体时,随后会更改ComboBox值

有没有办法实现一个只监听用户提交的更改的侦听器

        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;
                    }
                });

            }

        }
    });

你需要这样的东西吗

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;
    }

}

你能提供一些代码吗?不。。你为什么需要它?编程更改只产生有效更改,因此无论验证程序是否正在运行,它都会传递消息。问题是,有效值会触发对数据库的更新并重新加载实体,这会导致死锁,因为组合框值再次更改。我想我可能会尝试使用标志,因为似乎没有用户选择事件。听起来你没有显示的代码中有错误-请阅读并按照提示操作-无论你想用runlater实现什么,它都是不可靠的:它只保证它稍后运行,而不指定它是什么!!你是对的,但它不太可能在正确的时间执行该代码片段,我真的没有看到任何情况下,它会导致严重的问题,但我愿意接受任何建议。我认为OP在他的设置中做了一些错误的事情,所以不需要抓住稻草;我个人的规则是永远不要在fx上下文中使用runlater,因为你根本不知道它什么时候会发生。但是当我们谈论它在某个毫秒范围内时,这在大多数情况下都无关紧要,特别是在JavaFx应用程序中,当你没有1k+用户时,等等。有几个地方我无法避免使用它。一个例子是这个答案,我没有找到更好的解决方案来防止用户在出现问题时选择错误的项目。如果你知道这个问题的任何更好的解决方案,我也会很感激:但是你正在试图解决一个OP没有的问题,至少在我读到它的时候-验证似乎是可以的,但是如果组合被重新加载,它就会抛出。。至于你对runlater的使用,我很高兴它能为你工作,但也很高兴我不必维护你用它编写的任何代码