2014-02-13 51 views
2

我寫了非常大的懶漢樹模型,並不能給出路徑編程展開如何擴展SWT/Tree和/或JFace/TreeViewer中的給定路徑?

下面是整個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(); 
    } 

} 

回答

0

TreePath參數這些呼叫是剛剛從對象模型的對象(如由內容提供者提供的)的陣列。該數組從樹中頂層對象開始(由內容提供者getElements調用返回的一個對象)。數組中的第二個條目是頂級元素的子項,對於每個要擴展的子項都是如此。

您顯示的getTreePathFromItem代碼是以樹的'葉'開始的,它想要擴展並通過父項到樹的頂部工作。由於樹形路徑需要從頂部到底部,因此建立的列表是相反的。

調用TreeViewer.setUseHashlookup(true)可幫助查看器查看這些對象。

更新:有TreePath輸入internalGetWidgetToSelect操作,檢查空路徑之後,我們有電話:

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

這似乎從註釋中,它可能具有相同的模型對象的多個樹項目 - 我不確定何時使用,但我不認爲這是正常的。如果您確實有多個樹項目,那麼TreePath不明確,因此代碼依次查看每個項目的父樹路徑以查找匹配項。

因此,在模型對象只有一個葉子項的正常情況下,這可能比從樹的根路徑開始並查找每個子樹更快,因爲搜索與樹模型對象匹配的樹項的次數更少。

+0

好吧我理解了方法的正確性,但不明白它的有效性。假設我有明確的路徑,但末尾有許多相同的葉子。爲什麼從最後開始搜索?這將會給無數的候選人!爲什麼不從根到葉搜索? – Dims

+0

添加了一些關於如何閱讀內部操作的更多信息 –

+0

它對我無效。庫代碼看起來很奇怪;就好像它瀏覽的不是我的樹層次結構,而是視覺控件層次結構。有時'org.eclipse.jface.viewers.StructuredViewer.findItems(Object)'不起作用。 – Dims