Java 在侦听器中有效地使用侦听器?

Java 在侦听器中有效地使用侦听器?,java,javafx,Java,Javafx,如果我在表单上下文中有多个文本字段,“提交”按钮如何保持禁用状态,直到文本字段的任意数不为空为止 如果只有一个TextField在文本字段上有一个ChangeListener,这可以简单地实现,但是如何为xTextField实现呢? 其中x是一个大于1的数字 一个文本字段示例 按钮的.setDisable()方法通过TextField上的changeelistener检查字段是否为空来实现 这表现为: 当文本字段为空时,按钮被禁用 当文本字段包含某些内容时,按钮被启用 。。。正如所料 如果

如果我在表单上下文中有多个
文本字段
,“提交”按钮如何保持禁用状态,直到
文本字段
的任意数不为空为止

如果只有一个
TextField
在文本字段上有一个
ChangeListener
,这可以简单地实现,但是如何为x
TextField
实现呢?
其中x是一个大于1的数字

一个文本字段示例
按钮的
.setDisable()
方法通过
TextField
上的
changeelistener
检查字段是否为空来实现

这表现为:

  • 当文本字段为空时,按钮被禁用
  • 当文本字段包含某些内容时,按钮被启用
。。。正如所料

如果两个字段使用同一个侦听器(如下所示),则它们的行为就好像彼此独立一样。
例如如果其中任何一个包含某些内容,则该按钮被启用:

public void someMethod(){
    Dialog dialog = new Dialog();
    dialog.getDialogPane().getButtonTypes().addAll(ButtonType.APPLY, ButtonType.CANCEL);

    TextField textField1 = new TextField();
    textField1.setPromptText("field1");
    TextField textField2 = new TextField();
    textField2.setPromptText("field2");


    // add fields to gridpane
    GridPane gridPane = new GridPane();
    gridPane.add(textField1,0,0);
    gridPane.add(textField2,0,1);

    // add grid to dialog pane
    dialog.getDialogPane().setContent(gridPane);

    Node applyButton = dialog.getDialogPane().lookupButton(ButtonType.APPLY);
    applyButton.setDisable(true);

    ChangeListener<String> myChangeListener = new ChangeListener<String>() {
        @Override
        public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
            applyButton.setDisable(newValue.trim().isEmpty());
        }
    };

    textField1.textProperty().addListener(myChangeListener);
    textField2.textProperty().addListener(myChangeListener);

    dialog.showAndWait();
}
public void someMethod(){
Dialog=新建Dialog();
dialog.getDialogPane().getButtonTypes().addAll(ButtonType.APPLY,ButtonType.CANCEL);
TextField textField1=新的TextField();
textField1.setpromptext(“field1”);
TextField textField2=新的TextField();
textField2.setpromptext(“field2”);
//将字段添加到gridpane
GridPane GridPane=新建GridPane();
添加(textField1,0,0);
添加(textField2,0,1);
//将网格添加到对话框窗格
dialog.getDialogPane().setContent(gridPane);
节点applyButton=dialog.getDialogPane().lookupButton(ButtonType.APPLY);
applyButton.setDisable(true);
ChangeListener myChangeListener=新的ChangeListener(){
@凌驾

public void changed(observeValue您不需要在其他侦听器中添加额外的侦听器-您希望观察更改,而不管以前是否发生了更改

相反,每次更改都必须检查整个输入的有效性(所有文本字段均为非空)。这可以通过将所有
TextField
s传递给一个方法来完成:

private void setButtonTextFieldListeners(Button button, TextField... textFields) {
    ChangeListener<String> listener = (observable, oldValue, newValue) -> {
        for (int i=0; i<textFields.length; i++) {
            if (textFields[i].getText()==null || textFields[i].getText().trim().isEmpty()) {
                button.setDisable(true);
                return;
            }
        }
        button.setDisable(false);
    }
    for (TextField textField : textFields) {
        textField.textProperty().addListener(listener);
    }
}

我倾向于使用
布尔表达式的被动方法
,那么您也不必否定绑定。此外,您可以轻松地扩展此解决方案以实现更高级的表单验证。@beatngu13-需要注意的是,如果您使用
isEmpty
而不是
isNotEmpty
,则还必须将所有
s更改为
s。
    textField1.textProperty().addListener(new ChangeListener<String>() {
        @Override
        public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
            // add listener to textField 2
            textField2.textProperty().addListener(new ChangeListener<String>() {
                @Override
                public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                    applyButton.setDisable(newValue.trim().isEmpty());

                    // ... add listener to textField x
                }
            });
        }
    });
private void setButtonTextFieldListeners(Button button, TextField... textFields) {
    ChangeListener<String> listener = (observable, oldValue, newValue) -> {
        for (int i=0; i<textFields.length; i++) {
            if (textFields[i].getText()==null || textFields[i].getText().trim().isEmpty()) {
                button.setDisable(true);
                return;
            }
        }
        button.setDisable(false);
    }
    for (TextField textField : textFields) {
        textField.textProperty().addListener(listener);
    }
}
BooleanExpression b = textField1.textProperty().isNotEmpty()
                  .and(textField2.textProperty().isNotEmpty())
                  .and(...);
// b is True if and only if ALL text fields are not-empty. The button should be disabled when this ISN'T the case (enabled when b is True).
button.disableProperty().bind(b.not());