我有一个TextField和两个连续的按钮。一个按钮(“添加按钮”)添加TextField的另一行和另一对添加和删除按钮,另一按钮删除该行。当前行是唯一行时,删除按钮被禁用,因此不能有行。
仅当当前行的文本字段不为空并且它是最后一个文本字段时,才启用添加按钮。因此,除了最后一行,每一行都有一个禁用的“添加按钮”。
现在我的问题是如何将“添加按钮” disableProperty绑定到存在的所有文本字段,并检查它们是否为空。事实上,我认为我只需要检查最后一个文本字段,如果它为空,那么我将禁用最后一个“添加按钮”。 。
我找到了一种解决方法,将按钮绑定到文本字段,然后如果我添加另一行,则取消绑定按钮,禁用它,如果删除一行,则仅启用最后一个按钮,然后再次将其绑定到文本字段。这个解决方案似乎很笨拙,我想知道是否有一个更优雅的带有属性绑定的解决方案。
我的代码(具有解决方法,因此您可以看到我想要做什么):
public class Controller {
@FXML
private VBox VBox;
public ObservableList<TextField> oList = FXCollections.observableArrayList();
public ObservableList<Button> bList = FXCollections.observableArrayList();
public void initialize(){
createRow();
}
private void createRow(){
HBox box = new HBox(10);
TextField textField = new TextField();
Button addButton = new Button("Add row");
Button deleteButton = new Button("Delete");
box.getChildren().addAll(textField, addButton, deleteButton);
VBox.getChildren().add(box);
oList.add(textField);
bList.add(addButton);
addButton.disableProperty().bind(Bindings.isEmpty(textField.textProperty()));
addButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
addButton.disableProperty().unbind();
createRow();
textField.setDisable(true);
addButton.setDisable(true);
}
});
deleteButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
int idx = oList.indexOf(textField);
oList.remove(idx);
bList.remove(idx);
VBox.getChildren().remove(idx);
for(TextField tf : oList){
int i = oList.indexOf(tf);
if(oList.size()-1 == i){
tf.setDisable(false);
bList.get(i).disableProperty().bind(Bindings.isEmpty(tf.textProperty()));
}
}
}
});
}
}
还有两个屏幕截图:
添加了4行,所有“添加按钮”均已禁用,最后一个BC文本字段中未写入任何内容
在这里,我删除了test1行,并且空行和所有“添加按钮”仍被禁用,除了最后一个,因为在文本字段中有文本
谢谢你的帮助!
PS:我知道我的代码中没有ObservableList,但是我正在尝试并允许它们进入,因为我忘记了...
BooleanExpression
如果TextField
列表中的所有s为空,则可以创建一个返回true的。请注意,您需要重新创建该表达式作为ObservableList<TextField>
'change 的内容:
oList.addListener((ListChangeListener<? super TextField>) c -> {
addButton.disableProperty().unbind();
BooleanExpression allEmpty = oList.stream()
.map(tf -> BooleanExpression.booleanExpression(tf.textProperty().isEmpty()))
.reduce(new SimpleBooleanProperty(true), BooleanExpression::and);
addButton.disableProperty().bind(allEmpty);
});
每次TextField
添加或删除新内容时,TextField
列表中的每个内容都会映射到that BooleanExpression
的empty
属性TextField
。然后,所有表达式将被合并在一起。
Note: The same way can also be done using a loop instead of a stream.
Note: You need to add this listener before adding any element to the list.
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句