3

我在我的 GMF 编辑器中使用了一个带有 CheckboxTreeViewer 的自定义对话框,到目前为止效果很好,如下所示:

复选框Treeviewer

关闭对话框后,选择的元素保存至今。现在我的问题:

当我再次打开对话框时,所有元素都未选中。所以我认为告诉 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);
4

1 回答 1

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”进行比较。


编辑:在这种情况下,元素是不可变的(由于某种原因它们无法更改),并且不接受将对象包装在树节点中的解决方案(请参阅评论)。

在这种情况下,您可以将用户检查操作保存在地图中,并在设置检查/未检查状态时,搜索任何以前的用户检查操作。我认为假设地图很简单并且不会增长太多是合理的。用户必须检查很多节点才能使其变大:)

我更新了代码片段以跟踪用户检查。

于 2013-10-31T07:41:47.903 回答