Java CheckBoxTreeTableCell选择父事件下的所有子项

Java CheckBoxTreeTableCell选择父事件下的所有子项,java,treeview,javafx-8,Java,Treeview,Javafx 8,我正在尝试从父根中选择所有子复选框。选中父复选框时将调用该操作 以下是scenebuilder的伪/修改/缩短设置: @FXML private TreeTableView<Info> testTable; @FXML private TreeTableColumn<Info, Boolean> checkBoxCol; 控制器: checkBoxCol.setCellValueFactory(new TreeItemPropertyValueFactory("

我正在尝试从父根中选择所有子复选框。选中父复选框时将调用该操作

以下是scenebuilder的伪/修改/缩短设置:

@FXML
private TreeTableView<Info> testTable;
@FXML
private TreeTableColumn<Info, Boolean> checkBoxCol;
控制器:

    checkBoxCol.setCellValueFactory(new TreeItemPropertyValueFactory("onHold"));
    checkBoxCol.setCellFactory(CheckBoxTreeTableCell.forTreeTableColumn(checkBoxCol));
最终结果如下(单击父节点时):


我尝试了onEditCommit/start/cancel,但它们似乎只影响单元格,而不影响复选框。我不确定如何只为父节点获取侦听器,以便它可以检查下面的所有值(如果它们有子节点)。如果只允许父节点拥有侦听器太困难,那么所有复选框都可以拥有侦听器,我可以简单地检查是否有子节点:
node.getChildren().size()
您应该能够在模型中完全管理这一点

TreeTableView
由一个
TreeItem
根节点和一组子节点组成。只要安排在创建树项时向属性添加侦听器:

private TreeItem<Info> createTreeItem(Info info) {
    TreeItem<Info> item = new TreeItem<>(info);
    info.onHoldProperty().addListener((obs, wasOnHold, isNowOnHold) -> {
        if (isNowOnHold) {
            item.getChildren().forEach(child -> child.getValue().setOnHold(true));
        }
    });
    return item ;
}
private TreeItem createTreeItem(信息){
TreeItem=新的TreeItem(信息);
info.onHoldProperty().addListener((obs、wasOnHold、isnownhold)->{
如果(isnownhold){
item.getChildren().forEach(child->child.getValue().setOnHold(true));
}
});
退货项目;
}
完整示例:

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.CheckBoxTreeTableCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TreeTableViewInheritableCheckBoxes extends Application {

    @Override
    public void start(Stage primaryStage) {
        TreeTableView<Info> table = new TreeTableView<>();
        table.setEditable(true);

        TreeTableColumn<Info, Boolean> infoCol = new TreeTableColumn<>("Info");
        infoCol.setPrefWidth(200);

        infoCol.setCellValueFactory(cellData -> cellData.getValue().getValue().onHoldProperty());
        infoCol.setCellFactory(CheckBoxTreeTableCell.forTreeTableColumn(infoCol));
        table.getColumns().add(infoCol);

        TreeItem<Info> root = createTreeItem(new Info());

        buildTree(root, 0);

        table.setRoot(root);

        primaryStage.setScene(new Scene(new BorderPane(table), 250, 400));
        primaryStage.show();
    }

    private void buildTree(TreeItem<Info> parent, int depth) {
        if (depth > 2) return ;
        for (int i = 0; i < 5; i++) {
            TreeItem<Info> item = createTreeItem(new Info());
            parent.getChildren().add(item);
            buildTree(item, depth + 1);
        }
    }

    private TreeItem<Info> createTreeItem(Info info) {
        TreeItem<Info> item = new TreeItem<>(info);
        info.onHoldProperty().addListener((obs, wasOnHold, isNowOnHold) -> {
            if (isNowOnHold) {
                item.getChildren().forEach(child -> child.getValue().setOnHold(true));
            }
        });
        return item ;
    }

    public static class Info {
        private final BooleanProperty onHold;

        public Info(){
            this.onHold = new SimpleBooleanProperty(false);
        }
        public Boolean getOnHold(){
            return onHold.get();
        }
        public void setOnHold(Boolean onHold) {
            this.onHold.set(onHold);
        }
        public BooleanProperty onHoldProperty(){
            return onHold;
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
导入javafx.application.application;
导入javafx.beans.property.BooleanProperty;
导入javafx.beans.property.SimpleBoleAnProperty;
导入javafx.scene.scene;
导入javafx.scene.control.TreeItem;
导入javafx.scene.control.TreeTableColumn;
导入javafx.scene.control.TreeTableView;
导入javafx.scene.control.cell.CheckBoxTreeTableCell;
导入javafx.scene.layout.BorderPane;
导入javafx.stage.stage;
公共类TreeTableViewInheritableCheckbox扩展了应用程序{
@凌驾
公共无效开始(阶段primaryStage){
TreeTableView表=新的TreeTableView();
table.setEditable(true);
TreeTableColumn infoCol=新的TreeTableColumn(“Info”);
infoCol.setPrefWidth(200);
infoCol.setCellValueFactory(cellData->cellData.getValue().getValue().onHoldProperty());
infoCol.setCellFactory(CheckBoxTreeTableCell.forTreeTableColumn(infoCol));
table.getColumns().add(infoCol);
TreeItem root=createTreeItem(new Info());
buildTree(根,0);
表.setRoot(root);
设置场景(新场景(新边框窗格(表),250400));
primaryStage.show();
}
私有void构建树(树项父级,int深度){
如果(深度>2)返回;
对于(int i=0;i<5;i++){
TreeItem=createTreeItem(新信息());
parent.getChildren().add(项);
构建树(项目,深度+1);
}
}
私有树Item createTreeItem(信息){
TreeItem=新的TreeItem(信息);
info.onHoldProperty().addListener((obs、wasOnHold、isnownhold)->{
如果(isnownhold){
item.getChildren().forEach(child->child.getValue().setOnHold(true));
}
});
退货项目;
}
公共静态类信息{
私有最终布尔财产持有;
公共信息(){
this.onHold=新的SimpleBoleAnProperty(false);
}
公共布尔getOnHold(){
return-onHold.get();
}
公共无效设置保持(布尔值保持){
this.onHold.set(onHold);
}
公共布尔属性onHoldProperty(){
恢复搁置;
}
}
公共静态void main(字符串[]args){
发射(args);
}
}

如果要将侦听器附加到复选框,请转到表示此复选框的类并查看其方法。在那里,您会找到方法,陛下,就像stackoverflow中的javafx仙女教父一样。你让我们免于服用阿司匹林和过量咖啡因!:]
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.CheckBoxTreeTableCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TreeTableViewInheritableCheckBoxes extends Application {

    @Override
    public void start(Stage primaryStage) {
        TreeTableView<Info> table = new TreeTableView<>();
        table.setEditable(true);

        TreeTableColumn<Info, Boolean> infoCol = new TreeTableColumn<>("Info");
        infoCol.setPrefWidth(200);

        infoCol.setCellValueFactory(cellData -> cellData.getValue().getValue().onHoldProperty());
        infoCol.setCellFactory(CheckBoxTreeTableCell.forTreeTableColumn(infoCol));
        table.getColumns().add(infoCol);

        TreeItem<Info> root = createTreeItem(new Info());

        buildTree(root, 0);

        table.setRoot(root);

        primaryStage.setScene(new Scene(new BorderPane(table), 250, 400));
        primaryStage.show();
    }

    private void buildTree(TreeItem<Info> parent, int depth) {
        if (depth > 2) return ;
        for (int i = 0; i < 5; i++) {
            TreeItem<Info> item = createTreeItem(new Info());
            parent.getChildren().add(item);
            buildTree(item, depth + 1);
        }
    }

    private TreeItem<Info> createTreeItem(Info info) {
        TreeItem<Info> item = new TreeItem<>(info);
        info.onHoldProperty().addListener((obs, wasOnHold, isNowOnHold) -> {
            if (isNowOnHold) {
                item.getChildren().forEach(child -> child.getValue().setOnHold(true));
            }
        });
        return item ;
    }

    public static class Info {
        private final BooleanProperty onHold;

        public Info(){
            this.onHold = new SimpleBooleanProperty(false);
        }
        public Boolean getOnHold(){
            return onHold.get();
        }
        public void setOnHold(Boolean onHold) {
            this.onHold.set(onHold);
        }
        public BooleanProperty onHoldProperty(){
            return onHold;
        }
    }

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