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

作者:梁祺 (eclipsesbs@gmail.com)

来自: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显示的是一个树状结构,有根节点,父节点,子节点组成。

双击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指定如何显示这些对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值