Java 如何正确使用CheckboxTreeViewer?

Java 如何正确使用CheckboxTreeViewer?,java,checkbox,tree,swt,jface,Java,Checkbox,Tree,Swt,Jface,我面临的问题是,一个已实现的CheckboxTreeViewer在Linux Debian上运行得很好,但在Windows下却不行。首先,我不理解“setGrayed()”的概念。。它是为了显示只选择了元素中的部分子元素吗 所以问题是:当我在Windows下检查一个项目时,它会检查树中的所有其他元素。不知何故,整个逻辑都被忽略了 这是我的代码,来自ICheckStateListener: @Override public void checkStateChanged(final CheckSta

我面临的问题是,一个已实现的
CheckboxTreeViewer
在Linux Debian上运行得很好,但在Windows下却不行。首先,我不理解“setGrayed()”的概念。。它是为了显示只选择了元素中的部分子元素吗

所以问题是:当我在Windows下检查一个项目时,它会检查树中的所有其他元素。不知何故,整个逻辑都被忽略了

这是我的代码,来自
ICheckStateListener

@Override
public void checkStateChanged(final CheckStateChangedEvent event) {
    // object checked
    final TreePath path = ((ITreeSelection) this.treeViewer.getSelection()).getPaths()[0];
    checkChildren(path, event.getChecked());
    checkParents(path.getParentPath());
    syncData();
}

public void checkParents(final TreePath path) {
    if (path == null) {
        return;
    }
    final IFieldElement<Object> treeElement = (IFieldElement<Object>) path.getLastSegment();
    if (treeElement != null) {
        boolean allChecked = true;
        boolean allUnchecked = true;
        for (final Object fieldElement : treeElement.getChildrenElements()) {
            allChecked = allChecked && this.treeViewer.getChecked(fieldElement);
            allUnchecked = allUnchecked && !this.treeViewer.getChecked(fieldElement);
        }
        if (allUnchecked) {
            this.treeViewer.setChecked(treeElement, false);
            this.treeViewer.setGrayed(treeElement, false);
        } else
        if (allChecked) {
            this.treeViewer.setChecked(treeElement, true);
            this.treeViewer.setGrayed(treeElement, false);
        } else
        if (!allUnchecked && !allChecked) {
            this.treeViewer.setChecked(treeElement, true);
            this.treeViewer.setGrayed(treeElement, true);
        }
    }
    checkParents(path.getParentPath());
}

public void checkChildren(final TreePath path, final boolean checked) {
    if (path == null) {
        return;
    }
    final Object element = path.getLastSegment();
    if (element != null) {
        this.treeViewer.setChecked(element, checked);
        this.treeViewer.setGrayed(element, false);
        this.treeViewer.setSubtreeChecked(element, checked);
        if (element instanceof EventMethod) {
            checkEventMethod(path, element, checked);
        }

    }
}
@覆盖
公共无效checkStateChanged(最终CheckStateChangeEvent事件){
//对象检查
最终树路径=((ITreeSelection)this.treeViewer.getSelection()).getPaths()[0];
checkChildren(路径,event.getChecked());
checkParents(path.getParentPath());
syncData();
}
公共无效检查父级(最终树路径){
if(路径==null){
返回;
}
最终的IFieldElement树元素=(IFieldElement)路径。getLastSegment();
如果(treeElement!=null){
布尔allChecked=true;
布尔allUnchecked=true;
for(最终对象fieldElement:TreeeElement.getChildrenElements()){
allChecked=allChecked&&this.treeViewer.getChecked(fieldElement);
allUnchecked=allUnchecked&!this.treeViewer.getChecked(fieldElement);
}
如果(勾选){
this.treeViewer.setChecked(treeElement,false);
this.treeViewer.setGrayed(treeElement,false);
}否则
如果(全部选中){
this.treeViewer.setChecked(treeElement,true);
this.treeViewer.setGrayed(treeElement,false);
}否则
如果(!allUnchecked&&!allChecked){
this.treeViewer.setChecked(treeElement,true);
this.treeViewer.setGrayed(treeElement,true);
}
}
checkParents(path.getParentPath());
}
公共void checkChildren(最终树路径,最终布尔值已选中){
if(路径==null){
返回;
}
最终对象元素=path.getLastSegment();
if(元素!=null){
this.treeViewer.setChecked(元素,选中);
this.treeViewer.setGrayed(元素,false);
此.treeViewer.setSubtreeChecked(元素,已检查);
if(元素实例of EventMethod){
checkEventMethod(路径、元素、选中);
}
}
}
编辑:我正在使用EclipseIndigo

提前谢谢

树中复选框的“灰色”状态只是选中和未选中之外的另一种状态。如何使用它取决于您,但通常它意味着“部分检查”状态。通常情况下,如果某个项目的某些子项已选中,而其他子项未选中,则父项将显示选中+灰色状态。具体呈现方式取决于操作系统及其版本。在某些实现中,用户只能选中或取消选中树项目,并且不能通过单击鼠标显式设置项目的灰色状态。它会根据选中的子项自动发生。但是,有时也有一些应用程序允许您单击复选框,使其选中为灰色或未选中。在这种情况下,灰色状态通常意味着“默认”状态。无论如何,这取决于实现

我不太确定您面临的问题是什么,但如果我不得不猜测的话,我会说,在Debian和Windows中,当抛出事件时,小部件的行为是不同的。因为在您的实现中,每当检查一个项时,您都会检查它的所有父项以及它的所有子项,因此在Windows中对父项调用
treeViewer.setChecked()
也会开始抛出事件,并且您的侦听器会被调用,从而检查所有父项的所有子项,因此一切都会被启用。测试一下,看看这是否是问题所在。为了避免这种情况,请在修改任何内容之前,在第一次接收事件时创建一个标志。在修改ignore all
checkStateChanged()
事件调用时,只要设置了该标志,对元素的更改就不会递归应用于整个树。一旦一项已检查/未检查操作完成,请重置标志,以便再次处理用户事件

private boolean ignoreCheckEvent=false;
@凌驾
公共无效checkStateChanged(最终CheckStateChangeEvent事件){
如果(忽略检查事件)
返回;
ignoreCheckEvent=true;
试一试{
//对象检查
最终树路径=((ITreeSelection)this.treeViewer.getSelection()).getPaths()[0];
checkChildren(路径,event.getChecked());
checkParents(path.getParentPath());
syncData();
}
最后{
ignoreCheckEvent=false;
}
}

试试org.eclipse.ui.dialogs.ContainerCheckedTreeViewer

说明: CheckboxTreeViewer在容器(非叶)节点上具有选中/灰色状态的特殊行为:灰色状态用于可视化其子节点的选中状态。检查容器,如果检查了所有包含的叶片,则为非灰色。如果选中了部分但不是所有叶,则容器将变灰