首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaFX:运行ChangeListener

JavaFX:运行ChangeListener
EN

Stack Overflow用户
提问于 2016-12-26 14:11:33
回答 1查看 9.2K关注 0票数 2

Ho可以在初始化时在ChangeListener内部运行change方法。因为它只在发生变化时才运行。例如,我有一个TextField,当它为空时,我想将它的值设置为0,我这样做:

代码语言:javascript
复制
textField.textProperty().addListener(new ChangeListener<String>() {
        @Override
        public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
            if (!newValue.matches("\\d*")) {
                textField.setText(newValue.replaceAll("[^\\d]", ""));
            }

            if (newValue.isEmpty())
                textField.setText("0");

        }
    });

但是,在应用程序开始时,未调用更改的方法。那么如何解决这个问题呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-26 15:23:59

无法访问添加到属性中的侦听器。显然,您可以保留对它的引用:

代码语言:javascript
复制
ChangeListener<String> textFieldListener = (observable, oldValue, newValue) -> {

    if (!newValue.matches("\\d*")) {
        textField.setText(newValue.replaceAll("[^\\d]", ""));
    }

    if (newValue.isEmpty())
        textField.setText("0");

};

textField.textProperty().addListener(textFieldListener);
textFieldListener.changed(null, null, textField.getText());

或者,也许更自然地,只需将实际的功能转移到另一种方法:

代码语言:javascript
复制
textField.textProperty().addListener((observable, oldValue, newValue) -> vetoTextFieldChanges());
vetoTextFieldChanges();

// ...

private void vetoTextFieldChanges() {
    String newText = textField.getText();
    if (!newText.matches("\\d*")) {
        textField.setText(newText.replaceAll("[^\\d]", ""));
    }

    if (newText.isEmpty())
        textField.setText("0");
}

请注意,如果更改与您的业务逻辑不一致,则监视更改然后对其进行修改的整个方法并不令人满意。例如,如果使用该属性注册了其他侦听器,他们可能会看到文本的中间值(无效)。支持的方法是使用TextFormatterTextFormatter允许您在textProperty()更新之前否决对文本请求的更改,并将文本转换为适当的值。所以在你的情况下你可以:

代码语言:javascript
复制
UnaryOperator<TextFormatter.Change> filter = change -> {

    // remove any non-digit characters from inserted text:
    if (! change.getText().matches("\\d*")) {
        change.setText(change.getText().replaceAll("[^\\d]", ""));
    }

    // if new text is empty, replace all text with "0":
    if (change.getControlNewText().isEmpty()) {
        change.setRange(0, change.getControlText().length());
        change.setText("0");
    }

    return change ;
};

TextFormatter<Integer> formatter = new TextFormatter<Integer>(new IntegerStringConverter(), 0, filter);
textField.setTextFormatter(formatter);

现在,您可以使用格式化程序直接通过格式化程序的value属性获取(数字)值,并将它们绑定到您的模型,等等:

代码语言:javascript
复制
// assume model is a data model and valueProperty() returns a Property<Integer>:
formatter.valueProperty().bindBidirectional(model.valueProperty());

请注意,这样的绑定将在模型更改时更新格式化程序(以及相应的文本字段),并根据模型值对其进行初始化(从而为您的原始问题提供解决方案)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41332483

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档