如果我在表单的上下文中有多个TextField
,那么如何提交'按钮保持禁用状态,直到TextFields
的任意数字不为空?
如果文本字段中只有一个TextField
与ChangeListener
一起出现,可以很简单地完成此操作,但如何为 x TextField
& #39; S?
其中 x 是一个数字> 1.
一个TextField示例
如果字段为空,则在.setDisable()
上使用ChangeListener
实现按钮的TextField
方法。
这表现为:
......正如所料。
如果两个字段使用相同的监听器(如下所示),则它们表现得好像彼此独立。
例如如果任何一个包含某些内容,则启用该按钮:
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();
}
如果使用相同的过程将独立的Listener添加到每个字段,情况也是如此:
textField1.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
applyButton.setDisable(newValue.trim().isEmpty());
}
});
textField2.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
applyButton.setDisable(newValue.trim().isEmpty());
}
});
多次尝试
多重的一个解决方案是简单地“分层”。彼此内的听众。这样做符合预期,在启用按钮之前,两个TextField都必须包含某些内容。
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
}
});
}
});
这个过程看起来效率很低!
如果我有20 TextFields
怎么办?我应该分层吗? 20深?
这是唯一的方法吗?如果没有,该过程如何更有效?
答案 0 :(得分:1)
您不需要在其他侦听器中添加额外的侦听器 - 无论先前的更改是否发生,您都希望观察更改。
相反,您必须检查每次更改时整个输入的有效性(所有文本字段是否为空)。这可以通过将所有TextField
传递给一个方法来公平地完成:
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
and
建立所有条件,然后将按钮的disable
属性绑定到其否定位置:
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());