如何在SWT / Tree和/或JFace / TreeViewer中扩展给定路径?

时间:2014-02-13 19:42:40

标签: java eclipse treeview swt jface

我写了一个非常大的懒树模型,无法通过给定路径以编程方式扩展它

以下是整个ViewPart代码。

树以交互方式运行良好,即我可以打开最多10级的所有级别。但我不能以编程方式执行此操作。

我写了自定义ViewElementComparer来比较元素。

package try_13_expandtreeview;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.viewers.IElementComparer;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

public class View extends ViewPart {

    public static final String ID = "Try_13_ExpandTreeView.view";

    private TreeViewer viewer;

    private Action action1;

    /**
     * Each model element is a "triad", i.e. new Object[3]
     * 
     * First element of a triad is a parent element
     * 
     * Second number is a level, numbered from leafs to root
     * 
     * Third number is numeric value (content) of an element
     * 
     * @author dims
     *
     */
    class ViewContentProvider implements ITreeContentProvider {
        public void inputChanged(Viewer v, Object oldInput, Object newInput) {
        }

        public void dispose() {
        }

        public Object[] getElements(Object parent) {
            return getChildren(parent);
        }

        @Override
        public Object[] getChildren(Object parent) {
            Object[] triade = (Object[]) parent;
            if( ((int)triade[1]) > 0 ) {
                Object[] children = new Object[10];
                Object[] child;
                for(int i=0; i<10; ++i) {
                    child = new Object[3];
                    child[0] = parent;
                    child[1] = ((int)triade[1])-1;
                    child[2] = i;
                    children[i] = child;
                }
                return children;
            }
            else {
                return new Object[0];
            }
        }

        @Override
        public Object getParent(Object element) {
            Object[] triade = (Object[]) element;
            return triade[0];
        }

        @Override
        public boolean hasChildren(Object element) {
            Object[] triade = (Object[]) element;
            return ((int)triade[1]) > 0;
        }
    }

    class ViewLabelProvider extends LabelProvider {
        @Override
        public String getText(Object element) {
            Object[] triade = (Object[]) element;
            return ((Integer)triade[2]).toString();
        }
    }

    class ViewElementComparer implements IElementComparer {

        @Override
        public boolean equals(Object a, Object b) {
            Object[] triade_a = (Object[]) a;
            Object[] triade_b = (Object[]) b;
            return ((int)triade_a[2]) == ((int)triade_b[2]); 
        }

        @Override
        public int hashCode(Object element) {
            Object[] triade = (Object[]) element;
            return ((int)triade[2]);
        }

    }

    /**
     * This is a callback that will allow us to create the viewer and initialize
     * it.
     */
    public void createPartControl(Composite parent) {
        viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
                | SWT.V_SCROLL);

        viewer.setContentProvider(new ViewContentProvider());
        viewer.setLabelProvider(new ViewLabelProvider());
        viewer.setComparer(new ViewElementComparer());

        viewer.setInput(new Object[] {null, 10, 0});

        action1 = new Action() {
            public void run() {


                TreePath[] treePaths = {
                        new TreePath(new Object[] {
                                new Object[] {null, 0, 2},
                                new Object[] {null, 0, 7},
                                new Object[] {null, 0, 4}
                        })
                };

                // viewer.setExpandedTreePaths(treePaths); // does not work 
                viewer.expandToLevel(treePaths[0], TreeViewer.ALL_LEVELS);





                //viewer.setExpandedElements(new Object[] { viewer.getTree().getItems()[3].getData()});
            }
        };
        action1.setText("Action 1");
        action1.setToolTipText("Action 1 tooltip");
        action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
            getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));

        getViewSite().getActionBars().getToolBarManager().add(action1);
    }

    /**
     * Passing the focus request to the viewer's control.
     */
    public void setFocus() {
        viewer.getControl().setFocus();
    }

}

2 个答案:

答案 0 :(得分:0)

这些调用的TreePath参数只是对象模型中的对象数组(由内容提供者提供)。数组从树中的顶级对象开始(内容提供者getElements调用返回的对象之一)。数组中的第二个条目是顶级元素的子元素,依此类推每个要扩展的子元素。

您显示的getTreePathFromItem代码从它想要展开的树的“叶子”开始,并通过项父项返回到树的顶部。由于树路径需要从上到下,因此构建的列表是相反的。

调用TreeViewer.setUseHashlookup(true)可帮助树查看器查找这些对象。

使用internalGetWidgetToSelect输入更新TreePath操作,检查空路径后我们有电话:

Widget[] candidates = findItems(treePath.getLastSegment());

从评论中可以看出,同一模型对象可能有多个树项目 - 我不确定何时使用它,但我不认为这是常见的。如果你有多个树项,那么TreePath是不明确的,因此代码会依次查看每个项目的父树路径以查找匹配项。

因此,在正常情况下,对于模型对象只有一个叶项,这可能比从树路径的根开始并找到每个子项更快,因为搜索匹配模型对象的树项的次数较少。

答案 1 :(得分:0)

只需在查看器上执行 expandAll,然后检查 getExpandedTreePaths 的结果。

如果您有以下树...

N1
  N1B
    N1C
N2
N3
..

...并且您想让 N1C 可见,您必须使用三个 TreePath 的数组来执行 setExpandedPaths

tp1 = new TreePath({N1});
tp2 = new TreePath({N1, N1B});
tp3 = new TreePath({N1, N1B, N1C});
// viewer.expandAll()
viewer.setExpandedTreePaths({tp1, tp2, tp3});