【问题标题】:Select Node in TreeViewer在 TreeViewer 中选择节点
【发布时间】:2018-03-04 02:42:27
【问题描述】:

这个非常简单的功能缺乏文档令人不安。我有一个TreeViewer 并想选择一个节点。唯一有意义的方法是,如果树将所有元素扩展到所选内容,否则用户将看不到它。

public class TreeWindow extends ApplicationWindow {

    public static void main(String[] args) {
        new TreeWindow().open();
    }

    public TreeWindow() {
        super(null);
        setBlockOnOpen(true);
    }

    @Override
    protected Control createContents(Composite parent) {
        final TreeViewer treeViewer = new TreeViewer(parent);
        treeViewer.setContentProvider(new FileTreeContentProvider());
        treeViewer.setLabelProvider(new LabelProvider() {
            @Override
            public String getText(Object element) {
                String result = ((File) element).getName();
                if (result.isEmpty()) {
                    result = ((File) element).getPath(); // root like C:\
                }
                return result;
            }
        });
        treeViewer.setInput(File.listRoots());

        // expand
        final File fileToExpand = new File("src");
        System.out.println("Expand to file: " + fileToExpand.getAbsolutePath());
        return treeViewer.getControl();
    }

    static class FileTreeContentProvider extends ArrayContentProvider implements ITreeContentProvider {

        @Override
        public Object[] getChildren(Object parentElement) {
            return ((File) parentElement).listFiles();
        }

        @Override
        public Object getParent(Object element) {
            return ((File) element).getParentFile();
        }

        @Override
        public boolean hasChildren(Object element) {
            return ((File) element).isDirectory();
        }

    }
}

我尝试了什么:

treeViewer.setSelection(new StructuredSelection(fileToExpand));
System.out.println("Selection: " + treeViewer.getSelection());

选择未设置。 (我多次看到使用了TreeViewer#setSelection(ISelection, boolean),但JavaDoc 指出“目前不支持reveal 参数,因为Tree 不提供仅选择一个项目而不将其滚动到视图中的API”)。

treeViewer.expandToLevel(fileToExpand, AbstractTreeViewer.ALL_LEVELS);

这个方法……什么都不做?

final Tree tree = treeViewer.getTree();
final TreeItem[] items = tree.getSelection();
for (int i = 0; i < items.length; ++i) {
    final TreeItem item = items[i];
    TreeItem treeParent = item.getParentItem();
    while (treeParent != null) {
        treeParent.setExpanded(true);
        treeParent = treeParent.getParentItem();
    }
}

可能有用吗?但是选择没有设置,所以...

treeViewer.expandAll();

这种方法通常可以,但我认为在上面的示例中尝试它不是一个好主意。它没有做我想做的事,所以无论如何这是一个有争议的问题。

问题似乎是 TreeItem 是懒惰地创建的。要检查您是否可以尝试以下操作:

for (final TreeItem item : this.treeViewer.getTree().getItems()) {
    System.out.println(item.getData() + " " + item.getItemCount());
}

如果项目有子项,则此方法输出 1,否则输出 0,但不是实际项目数。另外,如果您尝试获取孩子的数据,则为null

如何选择未展开的节点?如何将树扩展到选择/指定节点?

可能重复: How to expand a specific node in TreeViewer(org.eclipse.jface)(我不确定这是否是同一个问题,但无论哪种方式都没有解决方案)

【问题讨论】:

  • 对于expandToLevel,请尝试使用TreePath,其中包含从树到元素的完整路径,而不仅仅是元素。
  • @greg-449 但是我如何获得路径?这个例子有一个getParent(Object) 方法,但是没有这个方法是完全有效的(据我所知更常见)。
  • 如果您想将 expandToLevel 与 TreePath 一起使用,那么您必须能够以某种方式计算出路径。 expandToLevel 的问题在于,如果树的一个分支从未展开过,那么查看器就没有关于该分支中内容的信息,因此仅指定单个元素是行不通的。

标签: java swt jface


【解决方案1】:

我能够让它在 JFace 3.13.2 上工作:

// element is any object of your tree content provider data model,
// in your case a File.
treeViewer.expandToLevel(element, 0);
treeViewer.setSelection(new StructuredSelection(element));

上面的代码将使所有节点展开到所选元素的级别,将树的相关部分滚动到视图中并将元素标记为选中。

在我的例子中,树有四层深,所选元素是叶节点。如果您想在选定节点下方展开层级,您可以将高于 0 的层级作为第二个参数提供给 expandToLevel,或 TreeViewer.ALL_LEVELS 以展开子树中的所有层级。

【讨论】:

  • 感谢分享,但我的用例中无法展开所有节点::(
  • @SteffiS.,如果不展开上面的所有节点,如何显示选定的节点?除非父节点展开,否则所选节点将不可见...
  • 是的,选中节点的父节点需要展开。不是整棵树。 (顺便说一句。我在问题正文中有这些方法,解释了为什么它们对我不起作用。)
  • 如何突出显示父节点的子节点?
猜你喜欢
  • 1970-01-01
  • 2015-10-06
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
  • 2012-04-12
相关资源
最近更新 更多