javafx CheckBoxTreeItem以编程方式更新父项

时间:2017-06-13 15:40:16

标签: javafx treeview javafx-8

我必须从我的数据库中检索一些数据,以动态创建TreeView并从此CheckBoxTreeItem中选择一些TreeView。此TreeView表示菜单结构的权限。

我怀疑的是,当我创建TreeView并根据用户的权限以编程方式从树中选择特定项目时,父项目没有任何状态更改(selected或{{1} })。但是当我直接从界面中选择任何项目时,父母会得到更新。

例如,当我以编程方式选择项目时,我的屏幕显示:

enter image description here

您可以看到我选择了两个菜单项,但父母不是。

在此图片上,我使用屏幕选择了相同的菜单项,如果我选择子菜单中的所有子项,则父级已更新为indeterminate状态或indeterminate

enter image description here

我已经浏览了文档,谷歌和Stack Overflow,但只找到了更新孩子的例子。

有没有办法以编程方式更新父项或在选择项目时调用从屏幕执行的事件?

修改

树中的所有项目都将selected属性设置为independent

2 个答案:

答案 0 :(得分:0)

我为此问题找到了解决方法。 我必须首先创建所有TreeView结构,并在使用此代码段后更改selected属性:

Platform.runLater(new Runnable() {
    @Override
    public void run() {
       selectItems();
    }
});

以下是验证TreeItem的代码:

private void selectItems(){
    TreeItem root = tree.getRoot();
    if (root != null) {
        selectChildren(root);
    }
}

private void selectChildren(TreeItem<TesteVO> root){
    for(TreeItem<TesteVO> child: root.getChildren()){
        // HERE I CHECK IF THE USER HAS PERMISSION FOR THE MENU ITEM
        // IF SO, I CHANGE THE SELECTED PROPERTY TO TRUE
        if (child.getValue().id == 4) {
            ((CheckBoxTreeItem) child).setSelected(true);
        }

        // IF THERE ARE CHILD NODES, KEEP DIGGING RECURSIVELY
        if(!child.getChildren().isEmpty()) {
            selectChildren(child);
        }
    }
}

如果有更简单的方法,请告诉我!

答案 1 :(得分:0)

事实并非如此。当您选择子项时,父项会自动设置为不确定状态。我不确定这是否从发布此问题时就得到了纠正,可能没有。

我的猜测是在如何选择节点或如何构造和初始化 TableView 方面存在编程错误。

这里有一些代码显示了我在做什么,而且它有效!就我而言,我使用 CheckBoxTreeItem 作为 TreeItem。

树视图是如何创建的

    treeView = new TreeView(root);
    treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
        @Override
        public void changed(ObservableValue observableValue, Object o, Object t1) {
            CheckBoxTreeItem<File> node = (CheckBoxTreeItem<File>)t1;
             if (node.getValue() != currentFile) {
                setFileDetail(node);
                showChildren(node);
            }
        }
    });
    treeView.setCellFactory(new CallBackWrapper());
    treeView.setShowRoot(false);

下面显示了 CallBackWrapper 类。

private class CallBackWrapper implements Callback<TreeView<File>, TreeCell<File>> {

    Callback<TreeView<File>, TreeCell<File>> theCallback;

    private CallBackWrapper() {
        theCallback = CheckBoxTreeCell.<File>forTreeView(getSelectedProperty, converter);
    }

    @Override
    public TreeCell<File> call(TreeView<File> fileTreeView) {
        return theCallback.call(fileTreeView);
    }

    final Callback<TreeItem<File>, ObservableValue<Boolean>> getSelectedProperty = (TreeItem<File> item) -> {
            if (item instanceof CheckBoxTreeItem<?>) {
                return ((CheckBoxTreeItem<?>) item).selectedProperty();
            }
            return null;
        };
    final StringConverter<TreeItem<File>> converter = new StringConverter<TreeItem<File>>() {

            @Override
            public String toString(TreeItem<File> object) {
                File item = object.getValue();
                return fileSystemView.getSystemDisplayName(item);
            }

            @Override
            public TreeItem<File> fromString(String string) {
                return new TreeItem<File>(new File(string));
            }
    };
}

最后这里有一些代码来进行选择:

boolean selectNode(CheckBoxTreeItem<File> parentNode, String name) {
    Object[]  children = parentNode.getChildren().toArray();
    for (Object child : children) {
        CheckBoxTreeItem<File> childItem = (CheckBoxTreeItem<File>) child;
        if (name.equals(childItem.getValue().getName())) {
            childItem.setSelected(true);
            //treeView.getSelectionModel().select(child); <-- this does not work!
            return true;
        }
    }
    return false;
}