第三天:那么TreeViewer怎么实现?

作者:梁祺 ([email protected])

来自:http://www.benisoft.net/day3/index.html

 

今天我们来看一下TreeViewer,同样是使用“Plug-in with a view”模版,不过在向导的最后一页改用Tree viewer。

启动Eclipse前,先把eclipse.tutorial.day2的项目关闭,免得出现两个Sample View。启动Eclipse后, 找到Sample View,现在Sample View显示的是一个树状结构,有根节点,父节点,子节点组成。

第三天:那么TreeViewer怎么实现?

双击Package Explorer View里的plug-in.xml,打开Plug-in Editor的Extensions子页, 你会发现内容和前面的例子一模一样。点击class打开Java类。

在Sample View里,TableViewer改成了TreeViewer了,多了一个DrillDownAdapter, DrillDownAdapter这里就不介绍了。

public  class SampleView  extends ViewPart {

     /**
     * The ID of the view as specified by the extension.
     */

     public  static  final String ID = \ "eclipse.tutorial.day3.views.SampleView\";

     private TreeViewer viewer;
     private DrillDownAdapter drillDownAdapter;
     private Action action1;
     private Action action2;
     private Action doubleClickAction;

还多了TreeObject和TreeParent两个内部类,这两个类比较简单,值得一提的是TreeObject实现IAdaptable接口。 对这个例子而言,这不是必须的。使用IAdaptable可以避免将真正的Model对象放在树上, 甚至可以更换Model对象而不用重新生成树。IAdaptable提供很高的灵活性。

     class TreeObject  implements IAdaptable {
         private String name;
         private TreeParent parent;
        ...
         public Object getAdapter(Class key) {
             return  null;
        }
    }

ViewContentProvider实现了新接口ITreeContentProvider。 当需要显示TreeViewer的内容时,第一个调用的方法是getElement(),它接受参数parent, 这样根据不同的父节点parent,getElement()可以返回相应的子节点。 如果parent是getViewSite()返回的viewSite(就是viewer.setInput()时设置的对象),就返回根节点, 否则返回父节点的子节点。接下来getParent(),getChildren()和hasChildren()这三个方法必须行为一致, 否则随着TreeViewer使用,有可能碰到一些非常难以调试的问题,比如想要高亮选中某个节点,可能会不工作。

     class ViewContentProvider  implements IStructuredContentProvider, 
                                           ITreeContentProvider {
         private TreeParent invisibleRoot;

         public  void inputChanged(Viewer v, Object oldInput, Object newInput) {
        }
         public  void dispose() {
        }
         public Object[] getElements(Object parent) {
             if (parent.equals(getViewSite())) {
                 if (invisibleRoot== null) initialize();
                 return getChildren(invisibleRoot);
            }
             return getChildren(parent);
        }
         public Object getParent(Object child) {
             if (child  instanceof TreeObject) {
                 return ((TreeObject)child).getParent();
            }
             return  null;
        }
         public Object [] getChildren(Object parent) {
             if (parent  instanceof TreeParent) {
                 return ((TreeParent)parent).getChildren();
            }
             return  new Object[0];
        }
         public  boolean hasChildren(Object parent) {
             if (parent  instanceof TreeParent)
                 return ((TreeParent)parent).hasChildren();
             return  false;
        }
        ...
    }

LabelProvider实现了getImage()方法, 为每个节点指定图标。

     class ViewLabelProvider  extends LabelProvider {

         public String getText(Object obj) {
             return obj.toString();
        }
         public Image getImage(Object obj) {
            String imageKey = ISharedImages.IMG_OBJ_ELEMENT;
             if (obj  instanceof TreeParent)
               imageKey = ISharedImages.IMG_OBJ_FOLDER;
             return PlatformUI.getWorkbench().getSharedImages().getImage(imageKey);
        }
    }

Eclipse还提供了IColorProvider和IFontProvider使得我们可以为某些节点指定不同的颜色和字体。 IColorProvider提供getForeground(...)和getBackground(...)两个方法,分别用于指定前景色和背景色。 IFontProvider提供getFont(...)方法,指定显示时使用的字体。

     class ViewLabelProvider  extends LabelProvider  implements IColorProvider, IFontProvider {

         public String getText(Object obj) {
             return obj.toString();
        }
         public Image getImage(Object obj) {
            String imageKey = ISharedImages.IMG_OBJ_ELEMENT;
             if (obj  instanceof TreeParent)
               imageKey = ISharedImages.IMG_OBJ_FOLDER;
             return PlatformUI.getWorkbench().getSharedImages().getImage(imageKey);
        }
         public Font getFont(Object element) {
             if (element  instanceof TreeParent) 
                 return getSite().getShell().getDisplay().getSystemFont();
             return  null;
        }
         public Color getForeground(Object element) {
             if (element  instanceof TreeParent) 
                 return getSite().getShell().getDisplay().getSystemColor(SWT.COLOR_RED);
             return  null;
        }
         public Color getBackground(Object element) {
             if (element  instanceof TreeParent) 
                 return getSite().getShell().getDisplay().getSystemColor(SWT.COLOR_CYAN);
             return  null;
        }
    }

到这里,我们看了如何创建TreeViewer,TreeViewer和TableViewer一样,关键就是Content Provider, Content Provider提供需要显示的对象,Label Provider指定如何显示这些对象。

你可能感兴趣的:(java,eclipse,开发,教程,plug-in)