CheckBoxTreeTableCell选择父项下的所有子项

时间:2015-05-01 15:31:16

标签: java treeview javafx-8

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

这里是使用scenebuilder的伪/修改/缩短设置:

@FXML
private TreeTableView<Info> testTable;
@FXML
private TreeTableColumn<Info, Boolean> checkBoxCol;

型号:

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

控制器:

    checkBoxCol.setCellValueFactory(new TreeItemPropertyValueFactory("onHold"));
    checkBoxCol.setCellFactory(CheckBoxTreeTableCell.forTreeTableColumn(checkBoxCol));

结束结果将如下所示(单击父节点时):

enter image description here

我试过onEditCommit / start / cancel,但这些似乎只影响单元格而不是复选框。我不确定如何仅为父节点获取侦听器,以便它可以检查下面的所有值(如果它们有子节点)。如果只允许父节点只有监听器太难了,那么所有复选框都可以有监听器,我可以简单地检查是否有子节点:node.getChildren().size()

1 个答案:

答案 0 :(得分:1)

您应该能够在模型中完全管理它。

TreeTableView由一个带有一堆后代节点的TreeItem<Info>根组成。只需安排在创建树项时,就可以为属性添加一个监听器:

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

完整示例:

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