javafx:如何使用动态创建的复选框绑定禁用按钮?
我想用动态创建的复选框绑定按钮的javafx:如何使用动态创建的复选框绑定禁用按钮?,javafx,Javafx,我想用动态创建的复选框绑定按钮的禁用。如果选中复选框,则应启用按钮 这是我的密码 public class DietTabPageController { @FXML private FlowPane parent; @FXML private Button okButton; private ObservableList<CheckBox> checkBoxes=FXCollections.observableArrayList();
禁用
。如果选中复选框,则应启用按钮
这是我的密码
public class DietTabPageController {
@FXML
private FlowPane parent;
@FXML
private Button okButton;
private ObservableList<CheckBox> checkBoxes=FXCollections.observableArrayList();
@FXML
private void initialize() {
ObservableList<Diet> diets = DietDAO.getDiets();
diets.forEach(diet -> checkBoxes.add(new CheckBox(diet.getName())));
//checkboxes added in parent Flowpane
parent.getChildren().addAll(checkBoxes);
}
}
公共类DietTabPageController{
@FXML
私有流窗格父级;
@FXML
私人按钮;
私有ObservableList复选框=FXCollections.observableArrayList();
@FXML
私有void初始化(){
ObservableList饮食=DietDAO.getDiets();
forEach(diet->CheckBox.add)(新复选框(diet.getName()));
//在父流窗格中添加的复选框
parent.getChildren().addAll(复选框);
}
}
有什么建议吗?谢谢您需要将侦听器添加到
复选框的所有选定的属性中。每次更改一个属性时,如有必要,请修改按钮的禁用属性。顺便说一句:使复选框可见似乎没有必要:
private List<CheckBox> checkBoxes;
@FXML
private void initialize() {
ObservableList<Diet> diets = DietDAO.getDiets();
checkBoxes = new ArrayList<>(diets.size());
ChangeListener<Boolean> listener = (o, oldValue, newValue) -> {
if (newValue) {
// activate button since at least one CheckBox is selected
okButton.setDisable(false);
} else {
// disable button, if the last CheckBox was unselected
for (CheckBox cb : checkBoxes) {
if (cb.isSelected()) {
return; // don't do anything, if there still is a selected CheckBox
}
}
okButton.setDisable(true);
}
};
for (Diet diet : diets) {
CheckBox cb = new CheckBox(diet.getName());
cb.selectedProperty().addListener(listener);
checkBoxes.add(cb);
}
//checkboxes added in parent Flowpane
parent.getChildren().addAll(checkBoxes);
}
私有列表复选框;
@FXML
私有void初始化(){
ObservableList饮食=DietDAO.getDiets();
复选框=新的ArrayList(diets.size());
ChangeListener侦听器=(o,oldValue,newValue)->{
如果(新值){
//激活按钮,因为至少选中了一个复选框
确定按钮。设置禁用(假);
}否则{
//如果未选中最后一个复选框,则禁用按钮
用于(复选框cb:复选框){
if(cb.isSelected()){
return;//如果仍有选中的复选框,则不执行任何操作
}
}
确定按钮。设置禁用(真);
}
};
用于(饮食:饮食){
复选框cb=新复选框(diet.getName());
cb.selectedProperty().addListener(listener);
复选框。添加(cb);
}
//在父流窗格中添加的复选框
parent.getChildren().addAll(复选框);
}
您可以使用JavaFX非常好的绑定
-class!
试试这个:
okButton.disableProperty().bind(
Bindings.createBooleanBinding(
()->!checkBoxes.stream().anyMatch(CheckBox::isSelected),
checkBoxes.stream().map(x->x.selectedProperty()).toArray(Observable[]::new)
)
);
这将创建一个新的绑定,它将侦听每个复选框,然后调用给定的函数来计算属性的值。
补充阅读:
关于你的评论:
我不知道你可以编辑多少你的饮食类,但如果你可以,有一个非常简单的方法来显示你的复选框和添加按钮绑定。请看以下示例:
ListView<Diet> dietsView = new ListView<>(diets);
dietsView.setCellFactory(CheckBoxListCell.forListView(diet ->
diet.selectedProperty()));
btn.disableProperty().bind(
Bindings.createBooleanBinding(
() -> !diets.stream().anyMatch(diet->diet.isSelected()),
diets.stream().map(x->x.selectedProperty())
.toArray(Observable[]::new)
)
);
我是否正确理解了这一点:如果至少选中了一个复选框,您想将ok按钮的disable
属性设置为false
?是的,在fxmlin中disable按钮是真的,这不是破坏了拥有fx属性的整个想法吗?@HalkoKarr Sajtarevic-Huh????我不明白你的意思。您需要响应(取消)选择复选框
es以动态设置禁用属性
。并非所有事情都需要通过绑定完成。唯一可能出错的是初始值,但由于按钮被禁用且未选中复选框,因此UI处于一致状态。在这种情况下,使用绑定只会降低代码的可读性。是的,但是JavaFX中的所有内容都是一个属性,每个属性都可以有绑定,那么为什么要编写一些内置的东西?@HalkoKarr Sajtarevic为什么只为了使用绑定而创建3个以上的对象?顺便说一句,如果我用下面不太可读、效率较低的代码,(使用<代码> OkButo.StDeable(复选框.Surrand)(非EMATCH(复选框::IS选中)<代码>))如果你认为这是质量标准的话,代码也比你的短1行…是的,但是你的代码只执行1次?如果用户再次取消选中复选框怎么办?绑定在这里是为了将本来应该在一起的东西粘在一起。我认为绑定版本更具可读性。您第一眼就知道,这段代码将以任何方式修改禁用状态。关于你的版本,我不能这么说……我编写了一个方法speciesdiao.getDietsBySpecies(Species-Species)
。此方法检索可观察列表
,具体取决于物种。是否可以设置speciesdiao.getDietsBySpecies(Speciesspecies)
中选定的复选框,而不破坏绑定思想?我用代码2嵌套,我想没有更好的主意了。对不起,我的英语不好
private final BooleanProperty selected = new SimpleBooleanProperty();
public final BooleanProperty selectedProperty() {
return this.selected;
}
public final boolean isSelected() {
return this.selectedProperty().get();
}
public final void setSelected(final boolean on) {
this.selectedProperty().set(on);
}