首页 > 解决方案 > 如果 TextField 输入无效,如何使用 JavaFX 绑定禁用按钮

问题描述

我从The Definitive Guide to Modern Java Clients with JavaFX 中获得了以下代码:

updateButton.disableProperty()
    .bind(listView.getSelectionModel().selectedItemProperty().isNull()
            .or(wordTextField.textProperty().isEmpty())
            .or(definitionTextArea.textProperty().isEmpty()));

我想修改它,如果输入的字符串frequencyTextField不是非负整数,则禁用按钮。我在连词中添加了一个术语,如下所示:

updateButton.disableProperty()
    .bind(listView.getSelectionModel().selectedItemProperty().isNull()
            .or(isLegalFrequency(frequencyTextField.textProperty()).not())
            .or(wordTextField.textProperty().isEmpty())
            .or(definitionTextArea.textProperty().isEmpty()));

虽然它可能不相关,但这里是测试有效性的方法:

    private BooleanProperty isLegalFrequency(StringProperty sp) {
        System.out.println("isLegalFrequency(" + sp.get() + ")");
        try {
            int value = Integer.parseInt(sp.get());
            return new SimpleBooleanProperty(value >= 0);
        } catch (NumberFormatException e) {
            return new SimpleBooleanProperty(false);
        }
    }

我的问题是按钮总是被禁用。我已经确定isLegalFrequency()只在创建场景时调用一次。这是有道理的,因为我正在传递frequencyTextField.textProperty(),而不是在其上调用方法(这可能在幕后设置了一个侦听器)。

有没有办法在不添加显式侦听器的情况下修改程序,使其行为符合我的意愿,或者是否有必要创建一个ChangeListeneron frequencyTextField.textProperty

标签: javafx

解决方案


Very generally, you can create an arbitrary method:

private Boolean validate() {
    // arbitrary implementation here...
    // in your case something like
    if (listView.getSelectionModel().getSelectedItem() == null) return false ;
    if (wordTextField.getText().isEmpty()) return false ;
    if (definitionTextArea.getText().isEmpty()) return false ;
    if (! isLegalFrequency(frequencyTextField.getText())) return false ;
    return true ;
}

and then do

updateButton.disableProperty().bind(Bindings.createBooleanBinding(
    () -> ! validate(),
    listView.getSelectionModel().selectedItemProperty(),
    frequencyTextField.textProperty(),
    wordTextField.textProperty(),
    definitionTextArea.textProperty()));

The parameters to the createBooleanBinding() method are a Callable<Boolean> (i.e. a method taking no parameters and returning a Boolean) followed by zero or more instances of javafx.beans.Observable (any property or ObservableList, etc, will work). You should include any property (or other observable) here that should trigger a recalculation of the disableProperty() when it changes.


推荐阅读