JavaFX中的多重布尔绑定
我正在尝试将一个复选框绑定到多个复选框,如下所示:JavaFX中的多重布尔绑定,java,javafx,Java,Javafx,我正在尝试将一个复选框绑定到多个复选框,如下所示: private void bindPanelToPackages(CheckBox panel, CheckBox ...pkg){ BooleanProperty panelBinding = null; BooleanBinding binder = null; for(CheckBox p: pkg){ if(panelBinding == null){ panelBin
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”有多个项时允许双向组绑定。这样,当我选择我的包时,“面板”将自动被选中,或者如果我选择“面板”,所有“包装”将被选中/取消选中。我被困在:
panel.selectedProperty().bind(活页夹)
得到
“JavaFX应用程序线程”java.lang.RuntimeException:复选框。选中:无法设置绑定值
因为我为“活页夹”做了单向装订。有没有一种方法可以让我完成类似的任务
panel.selectedProperty().bind(活页夹)
我在文件里找不到它,或者我找的地方不对。谢谢 条件“所有复选框均已选中”只能表示为布尔绑定
,而不能表示为布尔属性
。基本上,问题在于使该条件为false
没有明确定义:有许多方法可以做到这一点(即使所有复选框的任何非空子集都未选中)。因此,不能使用双向绑定:必须在这两个条件中的每一个上使用侦听器
以下是一个实现:
// 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);
}
}
与这个问题也有些关联,虽然不同:谢谢你的帮助,但我无法让它发挥作用。选择所有包/项时,侦听器不会启动以选择窗格。我徒劳地尝试调试BooleanBinding以了解使用NetBeans时发生的情况,似乎5复选框映射正确,直到依赖项映射到与包或依赖项的值不同的复选框$2为止。我希望这是有意义的…仍在学习…尝试更新版本;我想装订被垃圾收集了。你说得对。好像是垃圾收集的。再次感谢!