我在GMF编辑器中使用带有CheckboxTreeViewer的自定义Dialog,到目前为止工作正常,如下所示:
关闭对话框后,到目前为止保存了所选元素。现在我的问题:
当我再次打开对话框时,所有元素都未选中。所以我认为告诉treeViewer最初应该检查特定元素会很容易。
但事实证明这并不容易,因为树最初是由根元素组成的。在树展开之前,不会添加其他元素。通过调用ContentProvider的 getChildren(Object parentElement)添加元素。
因此,似乎我最初无法检查特定元素,而是必须提供动态方法。我正在寻找像元素添加的监听器之类的东西,但似乎没有一个存在。
这是我正在创建CheckboxTreeViewer
的部分Composite container = (Composite) super.createDialogArea(parent);
tv = new CheckboxTreeViewer(container, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL);
tv.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
tv.setAutoExpandLevel(2);
tv.setContentProvider(new FeaturePropertyDialogContentProvider(this));
tv.setLabelProvider(new FeaturePropertyDialogLabelProvider());
tv.setInput(productLine);
tv.setExpandPreCheckFilters(true);
return container;
这是我的ContentProvider的getChildren方法:
@Override
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof PL) {
PL p = (PL) parentElement;
return new Object[] { p.getPropertyList() };
}
else if (parentElement instanceof PropertyList) {
PropertyList propertyList = (PropertyList) parentElement;
return propertyList.getGeneralPlatforms().toArray();
} else if (parentElement instanceof GeneralPlatform) {
GeneralPlatform platform = (GeneralPlatform) parentElement;
return platform.getHardwareElements().toArray();
}
} else {
return null;
}
}
有关于此的任何想法吗?
--------------------解---------------------
我自己找到了以下解决方案,到目前为止对我来说效果很好:
tv.expandAll();
tv.setCheckedElements(preSelectedProperties.toArray());
tv.collapseAll();
tv.expandToLevel(2);
答案 0 :(得分:1)
您应该在树查看器上添加一个侦听器,以便在节点扩展时获取通知(TreeViewer上的方法addTreeListener())。那时,节点已经在树中,您可以选中复选框。
这是一个树的片段,用于在树展开时设置检查状态:
public class Snippet {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
final Map<String, Boolean> userChecks = new HashMap<>();
final CheckboxTreeViewer tv = new CheckboxTreeViewer(shell, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
GridData gridData = new GridData(GridData.FILL_BOTH);
tv.getTree().setLayoutData(gridData);
final FeaturePropertyDialogContentProvider provider = new FeaturePropertyDialogContentProvider(tv);
tv.setContentProvider(provider);
tv.setInput("root");
tv.addCheckStateListener(new ICheckStateListener() {
@Override
public void checkStateChanged(CheckStateChangedEvent event) {
userChecks.put((String) event.getElement(), event.getChecked());
}
});
tv.addTreeListener(new ITreeViewerListener() {
@Override
public void treeCollapsed(TreeExpansionEvent event) {
}
@Override
public void treeExpanded(TreeExpansionEvent event) {
final Object element = event.getElement();
final Object[] children = provider.getChildren(element);
for (Object child : children) {
if (userChecks.containsKey(child)) {
tv.setChecked(child, userChecks.get(child));
} else if (child.equals("b")) {
tv.setChecked(child, true);
}
}
}
});
shell.setSize(200, 200);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
private static class FeaturePropertyDialogContentProvider implements ITreeContentProvider {
final CheckboxTreeViewer tv;
private FeaturePropertyDialogContentProvider(CheckboxTreeViewer tv) {
this.tv = tv;
}
@Override
public Object[] getElements(Object inputElement) {
return this.getChildren(inputElement);
}
@Override
public Object[] getChildren(Object parentElement) {
switch ((String) parentElement) {
case "root":
return new String[]{"1"};
case "1":
return new String[]{"a", "b", "c"};
default:
return new String[0];
}
}
@Override
public Object getParent(Object element) {
return null;
}
@Override
public boolean hasChildren(Object element) {
return this.getChildren(element).length > 0;
}
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
}
在这个例子中,我只将节点值与字符串“b”进行比较。
编辑:在此上下文中,元素是不可变的(由于某种原因,它们无法更改),并且不接受在树节点中包装对象的解决方案(请参阅注释)。
在这种情况下,您可以在地图中保存用户检查操作,并在设置选中/取消选中状态时,搜索以前的任何用户检查操作。我认为假设地图很简单并且不会增长太多是合理的。用户必须检查很多节点以使其变大:)
我更新了代码段以跟踪用户检查。