Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javafx:如何使用动态创建的复选框绑定禁用按钮?_Javafx - Fatal编程技术网

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);
}