http://www.tuicool.com/articles/e6fmE3R

contentprovider在插件开发和RCP(Rich Client Platform)开发中常常被用到,譬如你要创建一个TreeViewer(树形控件)就需要一个ITreeContentProvider,如果要实现一个TableViewer(表控件)就需要一个IStructuredContentProvider,contentprovider主要的作用就是返回当前界面中的数据。

1.内容提供器(ITreeContentProvider)

TreeViewer的内容提供器(ITreeContentProvider)构建树中比较复杂的部分,它为树的显示提供了内容,内容提供器要实现的方法如下。

(1)getElements。

此函数定义为“public Object[] getElements(Object inputElement);”,当程序开始构建树时,首先调用getElements返回一个对象的数组,此数组对象表示当前树的根节点,inputElement参数为TreeViewer的输入(setInput的输入数据)。

(2)hasChildren。

此函数定义为“public boolean hasChildren(Object element);”,当TreeViewer显示一个节点后,会调用hasChildren函数判断当前节点是否有子节点,如果有子节点则显示“+”,element参数为要判断是否有子节点的节点。

(3)getChildren。

此函数定义为“public Object[] getChildren(Object parentElement);”,当用户选择节点打开子节点时,会调用getChildren函数返回下一层子节点,parentElement参数为选择的节点。

(4)getParent。

此函数定义为“public Object getParent(Object element);”,可以通过此方法返回element的父节点。

(5)inputChanged。

此函数定义为“public void inputChanged(Viewer viewer, Object oldInput, Object newInput);”,当输入改变时调用此方法。

(6)dispose。

此函数定义为“public void dispose();”,当树销毁时被调用。

其中,getElements、hasChildren和getChildren是常用的方法,用户通过重写这几种方法构建一棵树,过程如下:通过getElements方法得到根,再通过hasChildren判断根下是否有子节点,如果有子节点,可以通过getChildren得到所有的子节点。如例程15-2为ITreeContentProvider接口的一个简单实现。

例程15-2  FileTreeContentProvider.java

class FileTreeContentProvider implements ITreeContentProvider {

public Object[] getChildren(Object arg0) {
//返回树的下一级节点
return ((File) arg0).listFiles();
} public Object getParent(Object arg0) {
//返回树的上一级节点
return ((File) arg0).getParentFile();
} public boolean hasChildren(Object arg0) {
Object[] obj = getChildren(arg0); //判断树是否有下一级节点,true为在节点显示"+"信息
return obj == null ? false : obj.length > 0;
} public Object[] getElements(Object arg0) { //打印出树的输入信息,通常用户可以通过输入信息构建树
System.out.println(arg0);
// File.listRoots()作为树的根节点
return File.listRoots();
}

上例内容提供器通过文件系统获得树的输入内容,从而使用户构造的树能显示磁盘文件的树结构。

2.标签器还比较简单,在TreeViewer中最主要和最复杂的是内容器,熟悉内容器是掌握TreeViewer的要点。

TreeViewer内容器的代码如下:

//内容器。由它决定哪些对象记录应该输出在TreeViewer里显示
public class TreeViewerContentProvider implements ITreeContentProvider {
// 由此方法决定树的“第一级”结点显示哪些对象。inputElement是用tv.setInput()方法
//输入的那个对象。Object[]是一个数组,数组中一个元素就是一个结点
public Object[] getElements(Object inputElement) {
if (inputElement instanceof List) {
List input = (List) inputElement;
return input.toArray();
}
return new Object[0]; // 空数组
} // 判断参数element结点是否有子结点
// 返回true表示element有子结点,则其前面会显示有“+”号图标
public boolean hasChildren(Object element) {
ITreeEntry entry = (ITreeEntry) element;
List list = entry.getChildren();
return !(list == null || list.isEmpty()); // 判断list是否有子结点
} // 当界面中单击某结点时,由此方法决定被单击结点应该显示哪些子结点
// parentElement就是被单击的结点对象。返回的数组就是应显示的子结点
public Object[] getChildren(Object parentElement) {
ITreeEntry entry = (ITreeEntry) parentElement;
List list = entry.getChildren();
//虽然通过界面单击方式,有子结点才会执行到此方法,但仍然要做非空判断,
//因为在调用TreeViewer的某些方法时其内部会附带调用此方法
if (list == null) return new Object[0];
return list.toArray();
} // --------------以下方法暂时无用,空实现----------------
public void dispose() {}//树被销毁时触发
public void inputChanged(Viewer v,Object oldInput, Object newInput){} //每次tv.setInput触发
public Object getParent(Object element) {return null;} //取得element的父结点。极少使用
}

程序说明:在内容器中最关键的是getElements、hasChildren、getChildren这3个方法。

getElements只在显示“第一级”结点时才会被执行。

hasChildren主要用于判断当前所显示的结点是否有子结点,如果有子结点则前面显示一个“+”号图标,而有“+”号的结点则可以单击展开其下一级的子结点。

当单击有“子”的结点时,才会执行getChildren方法。展开其子结点后,又会对子结点执行一遍hasChildren方法,以决定其各子结点前是否显示“+”图标。

图15.4给出了内容器在启动、单击结点、关闭窗口这3种情况时的方法执行的时序图。

下面以本实例来解释此图:

树界面启动时:先执行inputChanged方法。接着执行getElements方法,其inputElement参数就是由setInput传入的对象:包含所有实体对象的List。此List在getElements中被转化成一个数组,数组包含第一级结点的两个元素中国和美国,它们将首先显示在界面上。接下来执行两次hasChildren方法,判断中国和美国是否有子结点。它们都有子结点,故方法返回True,两结点前都显示“+”图标。

单击有子结点的中国:先执行一次getChildren方法,方法的parentElement参数就是中国结点对象。方法中把中国的子结点取出并转化成一个数组返回,此数组包含3个元素“北京、台湾、桂林”。接下来连续执行3次hasChildren方法来判断“北京、台湾、桂林”是否有子结点,如果有,则在结点前显示一个“+”图标。

单击没有子结点的桂林:不会执行内容器中的任何方法。

关闭窗口:会先后执行inputChanged和dispose方法。

转:Eclipse插件开发之TreeViewer的更多相关文章

  1. 插件开发之360 DroidPlugin源码分析(五)Service预注册占坑

    请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52264977 在了解系统的activity,service,broa ...

  2. 插件开发之360 DroidPlugin源码分析(四)Activity预注册占坑

    请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52258434 在了解系统的activity,service,broa ...

  3. Qgis插件开发之Qgis源码学习

    Qgis源码中的拖拽.zoomin/out等各个基础功能插件的实现位于qgis_app工程中. 具体头文件为: \QGIS\src\app\qgisapp.h 根据此类可以逐个找到Qgis的基础插件的 ...

  4. 插件开发之360 DroidPlugin源码分析(二)Hook机制

    转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52124397 前言:新插件的开发,可以说是为插件开发者带来了福音,虽然还很多坑要填补, ...

  5. 插件开发之360 DroidPlugin源码分析(一)初识

    转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52123450 DroidPlugin的是什么? 一种新的插件机制,一种免安装的运行机制 ...

  6. 新人大餐:2018最新Office插件开发之ExcelDNA开发XLL插件免费教学视频,五分钟包教包会

    原始链接:https://www.cnblogs.com/Charltsing/p/ExcelDnaVideoCourse.html QQ: 564955427 先解释一下,为什么要做这个视频: 我在 ...

  7. jQuery插件开发之boxScroll与marquee

    BoxScroll 常见图片轮播效果的简单实现.可以数字列表控制或者左右按键控制.逻辑很简单,下面的Marquee形成环,这个到了尽头得往回跑,看看注释就知道了. 图片轮播GitHub:https:/ ...

  8. jQuery插件开发之windowScroll

    回首望,曾经洋洋得意的代码现在不忍直视.曾经看起来碉堡的效果现在也能稍微弄点出来.社会在往前发展,人也得向前迈进. 参考于搜狗浏览器4.2版本首页的上下滚动效果.主要实现整个窗口的上下和左右滚动逻辑, ...

  9. jQuery插件开发之datalist

    HTML5中定义了一种input框很好看的下拉列表--datalist,然而目前它的支持性并不好(万恶的IE,好在你要渐渐退役了...).于是最近更据需求写了一个小型datalist插件,兼容到IE8 ...

随机推荐

  1. (转)How To Kill runaway processes After Terminating Concurrent Request

    终止EBS并发请求后,解锁相关的进程. 还有种方法可以在PLSQL->tools->session 中找到并且kill Every concurrent Request uses some ...

  2. java中log4j用法详细讲解和一些小总结

    0.Log4j的用法详解 首先,在项目中的classes 中新建立一个log4j.properties文件即可: 在实际编程时,要使Log4j真正在系统中运行事先还要对配置文件进行定义.定义步骤就是对 ...

  3. qt qml fuzzyPanel 毛玻璃效果

    毛玻璃效果,用qml来写代码真是简短,大爱qml:) [下载地址]http://download.csdn.net/detail/surfsky/8426641 [核心代码] Rectangle{ c ...

  4. uboot命令

    uboot是怎么启动kernel的呢? 先熟悉一下uboot的命令吧. 首先是md, 查看内存. OpenJTAG> md 000000000: ea000014 e59ff014 e59ff0 ...

  5. Java数据结构之字符串模式匹配算法---KMP算法2

    直接接上篇上代码: //KMP算法 public class KMP { // 获取next数组的方法,根据给定的字符串求 public static int[] getNext(String sub ...

  6. Xcode 如何删除过期的Provisioning Profile文件

    Xcode 中所有的Provisioning Profile文件,都在 ~/Library/MobileDevice/Provisioning Profiles  这个文件夹下:进入该文件夹,按照文件 ...

  7. Linux上从Java程序中调用C函数

    原则上来说,"100%纯Java"的解决方法是最好的,但有些情况下必须使用本地方法.特别是在以下三种情况: 需要访问Java平台无法访问的系统特性和设备: 通过基准测试,发现Jav ...

  8. C++中 OOP相关的类型转换

    我们都知道,在C++中有很多类型转换.今天在这里,我们不讨论普通变量的类型转换(比如int转换成double等等).本文主要讨论面向对象相关的类型转换:向上转换和向下转换. 首先,我们定义一个基类Ba ...

  9. USB 设备的PID-Product ID,VID-Vendor ID

    根据USB规范的规定,所有的USB设备都有供应商ID(VID)和产品识别码(PID),主机通过不同的VID和PID来区别不同的设备,VID 和PID都是两个字节长,其中,供应商ID(VID)由供应商向 ...

  10. Mac OSX上的软件包管理工具,brew 即 Homebrew

    brew 即 Homebrew,是Mac OSX上的软件包管理工具,能在Mac中方便的安装软件或者卸载软件, 只需要一个命令, 非常方便. brew类似ubuntu系统下的apt-get的功能. 安装 ...