如何正确使用CheckboxTreeViewer?
作者:互联网
我面临的问题是,一个实现的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);
}
}
}
编辑:我正在使用Eclipse Indigo
提前致谢!
解决方法:
除了选中和未选中之外,树中复选框的“灰色”状态只是另一种状态.你如何使用它取决于你,但通常它意味着“部分检查”状态.通常情况下,如果某个项目已选中某些子项而其他项目未选中,则父项将显示已检查的灰色状态.具体如何呈现取决于操作系统及其版本.在一些实现中,用户只能检查或取消选中树项,并且不能通过鼠标点击在项上显式设置灰色状态.它会根据已检查的孩子自动发生.有时候,有些应用程序也允许您单击复选框以使其选中为灰色以取消选中.在这种情况下,灰色状态通常意味着“默认”状态.无论如何这是依赖于实现的.
我不确定你面临的问题是什么,但如果我不得不猜测我会说在推出活动时,小部件在Debian vs Windows中表现不同.因为在你的实现中,每当检查一个项目时,你检查它的所有父项及其所有子项,所以可能是在Windows中的父项上调用treeViewer.setChecked()也开始抛出事件,并调用你的监听器来检查所有的子项所有父母因此一切都得到启用.测试一下,看看这是不是问题.要避免这种情况,请创建一个标志,在首次接收事件之前设置该标志,然后再修改任并且修改忽略所有checkStateChanged()事件调用,只要设置该标志,以便您不会以递归方式将对元素的更改应用于整个树.对一个项目检查/取消选中操作完成后,操作将重置该标志,以便再次处理用户事件.
private boolean ignoreCheckEvent = false;
@Override
public void checkStateChanged(final CheckStateChangedEvent event) {
if (ignoreCheckEvent)
return;
ignoreCheckEvent = true;
try {
// object checked
final TreePath path = ((ITreeSelection) this.treeViewer.getSelection()).getPaths()[0];
checkChildren(path, event.getChecked());
checkParents(path.getParentPath());
syncData();
}
finally {
ignoreCheckEvent = false;
}
}
标签:jface,java,checkbox,tree,swt 来源: https://codeday.me/bug/20190825/1724320.html