gpt4 book ai didi

java - JavaFX 中的多个 boolean 值绑定(bind)

转载 作者:行者123 更新时间:2023-11-29 06:31:46 36 4
gpt4 key购买 nike

我正在尝试将一个复选框绑定(bind)到多个复选框,如下所示:

private void bindPanelToPackages(CheckBox panel, CheckBox ...pkg){

BooleanProperty panelBinding = null;
BooleanBinding binder = null;

for(CheckBox p: pkg){
if(panelBinding == null){
panelBinding = p.selectedProperty();
}
else{
binder = panelBinding.and(p.selectedProperty());
}
}

if(binder != null){
panel.selectedProperty().bind(binder);
}
else if(panelBinding != null){
panel.selectedProperty().bindBidirectional(panelBinding);
}
}

我想要的是当“pkg”有多个项目时允许双向组绑定(bind)。这样当我选择我的包时,“面板”将自动被选中,或者如果我选择“面板”,所有的“pkg”将被选中/取消选择。我被困在了:

panel.selectedProperty().bind(binder);

得到了

"JavaFX Application Thread" java.lang.RuntimeException: CheckBox.selected : A bound value cannot be set.

因为我为“ Binder ”做了一个单向绑定(bind)。有没有一种方法可以执行与此等效的操作?:

panel.selectedProperty().bindBidirectional(binder);

我似乎无法在文档中找到它,或者我没有找到正确的地方。谢谢!

最佳答案

条件“所有复选框都被选中”只能表示为 BooleanBinding,不能表示为 BooleanProperty。基本上,问题是使该条件 false 没有明确定义:有很多方法可以做到这一点(即取消选中所有复选框的任何非空子集)。因此,您不能使用双向绑定(bind):您必须在两种情况下都使用监听器。

这是一种实现方式:

// must keep a reference to the Binding to prevent premature
// garbage collection:

BooleanBinding allSelected ;

private void bindPanelToPackages(CheckBox pane, CheckBox... packages) {

// BooleanBinding that is true if and only if all check boxes in packages are selected:
allSelected = Bindings.createBooleanBinding(() ->
// compute value of binding:
Stream.of(packages).allMatch(CheckBox::isSelected),
// array of thing to observe to recompute binding - this gives the array
// of all the check boxes' selectedProperty()s.
Stream.of(packages).map(CheckBox::selectedProperty).toArray(Observable[]::new));

// update pane's selected property if binding defined above changes
allSelected.addListener((obs, wereAllSelected, areAllNowSelected) ->
pane.setSelected(areAllNowSelected));

// use an action listener to listen for a direct action on pane, and update all checkboxes
// in packages if this happens:
pane.setOnAction(e ->
Stream.of(packages).forEach(box -> box.setSelected(pane.isSelected())));

}

和一个 SSCCE:

import java.util.stream.IntStream;
import java.util.stream.Stream;

import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class MultipleCheckBoxSelection extends Application {

private BooleanBinding allSelected ;

@Override
public void start(Stage primaryStage) {
CheckBox selectAll = new CheckBox("Select all");
int numBoxes = 5 ;
CheckBox[] boxes = IntStream
.rangeClosed(1, numBoxes)
.mapToObj(i -> new CheckBox("Item "+i))
.toArray(CheckBox[]::new);

bindPanelToPackages(selectAll, boxes);


VBox root = new VBox(10, selectAll);
root.setStyle("-fx-padding: 15;");
Stream.of(boxes).forEach(box -> box.setStyle("-fx-padding: 0 0 0 10;"));
Stream.of(boxes).forEach(root.getChildren()::add);
Scene scene = new Scene(root, 250, 400);
primaryStage.setScene(scene);
primaryStage.show();
}

private void bindPanelToPackages(CheckBox pane, CheckBox... packages) {

// BooleanBinding that is true if and only if all check boxes in packages are selected:
allSelected = Bindings.createBooleanBinding(() ->
// compute value of binding:
Stream.of(packages).allMatch(CheckBox::isSelected),
// array of thing to observe to recompute binding - this gives the array
// of all the check boxes' selectedProperty()s.
Stream.of(packages).map(CheckBox::selectedProperty).toArray(Observable[]::new));

// update pane's selected property if binding defined above changes
allSelected.addListener((obs, wereAllSelected, areAllNowSelected) ->
pane.setSelected(areAllNowSelected));

// use an action listener to listen for a direct action on pane, and update all checkboxes
// in packages if this happens:
pane.setOnAction(e ->
Stream.of(packages).forEach(box -> box.setSelected(pane.isSelected())));

}

public static void main(String[] args) {
launch(args);
}
}

关于java - JavaFX 中的多个 boolean 值绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32192963/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com