JavaFX TextField 对用户输入使用react,但对 setText() 不使用react

标签 javafx

如何为 JavaFX 文本字段编写 ChangeListener,它仅对用户输入使用react,而不对 setText 方法使用react?

textField.textProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> observable,
            String oldValue, String newValue) {

        // code is executed, when user changes text,
        // but also, when setText(..) is called
    }
});

最佳答案

这样的问题总是让我觉得你的设计有问题。文本代表一些数据;您正在注册一个监听器,因为您对数据何时更改感兴趣 - 它为什么更改并不重要。如果确实重要,您可能需要一个与文本字段固有的属性不同的属性来表示您的数据。

最后一点也给出了一个可能的解决方案:

final TextField textField = new TextField(); // or injected from FXML, etc

final StringProperty text = new SimpleStringProperty(textField.getText());
text.addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> obs, String oldValue, String newValue) {
        textField.setText(newValue);
    }
});

textField.textProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> obs, String oldValue, String newValue) {
        if (! newValue.equals(text.get())) { // textField's text was changed directly (i.e. by user)
            // perform whatever action you need...

            // update the text property so the two remain equal:
            text.set(newValue);
        }
    }
});

现在重要的是,您永远不要调用 textField.setText(...),而是始终调用 text.set(...)。这会导致通过第一个监听器以编程方式调用 textField.setText(...)。这将调用第二个监听器,但此时文本字段的新值将与自定义属性的值相同。

另一方面,如果用户在文本字段中键入内容,则会创建对 textField.textProperty().set(...) 的调用(文本字段内部),该调用调用你的监听器。这里的新文本字段值与您的自定义属性值不同,因此调用了代码的主要部分。

关于JavaFX TextField 对用户输入使用react,但对 setText() 不使用react,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28421122/

相关文章:

java - 加载到 JavaFX WebView 组件中的完整网页的屏幕截图,不仅仅是可见部分

java - 为什么在加载 FXML 文件时收到 javafx.fxml.LoadException?

CSS 在 javafx 中更改 TextField 的大小

javafx - 通过 ListView 获取 ListCell

java - 在浏览器中显示 HTML 字符串

java - Jackson -- 使用自定义反序列化器反序列化 JavaFX StringProperty 类型字段

JavaFX 场景生成器菜单对象不可拖动

javascript - 在 JavaFX WebView 中加载 MathJax

css - JavaFX 子类伪类

java - 在 JavaFX 中居中裁剪图像