IWorkBenchAdapter是Eclipse JDT中经常用到的一个接口,该接口通常用于不同类型的节点在树中的显示,如我们常见的Java包浏览器,从接口以及API文档中我们可以看到它的层次关系。图4的类阶层结构展示了Java包浏览器如何使用IWorkBenchAdapter对节点分类显示的。
图4:IWorkBenchAdapter 的类阶层结构
图4中可以明显看见WorkBenchAdapter类会将每个对象(文件,文件夹,项目)适配包浏览器中的树节点,如果我们想象树中的每个节点代表每一行数据(一个只有一列的表),那么这样一种设计模式就是完全按行来控制的行控制器设计模式,我们可以为不同类型的行数据创建不同的适配器,精确控制这些数据的表现形式,如背景色、前景色、字体等,只要你愿意,还可以增加一些菜单或者打开编辑器等丰富的功能。本文将借鉴Eclipse的这一模式来设计TreeTable的行控制功能。图4显示了对File,Folder和Project这三种不同类型的数据做不同的控制,我们的构件中,将能够根据对象而不是类型做更为精确的控制。本文将参考WorkBenchAdapter的设计实现TreeTable的行控制器。
3.创建可重用的TreeTable构件
基于以上的研究,我们实现了一个高度可重用的TreeTable构件,限于篇幅,我们只实现了能够说明问题的最关键的功能。
使用IField实现列控制
为了便于说明问题我们创建了一个简单版本的IField接口,参见图5。
图5:简化后的IField接口

同时实现一个通用的TreeTableLabelProvider类,它使用IField接口控制列的行为。
清单4:TreeTableLabelProvider的代码
| public class TreeTableLabelProvider extends LabelProvider implements ITableLabelProvider { private IField[] fields; public TreeTableLabelProvider(IField[] fields) { this.fields = fields; } public Image getColumnImage(Object element, int columnIndex) { if (element == null || fields == null || columnIndex < 0 || columnIndex >= fields.length || fields[columnIndex] == null) { return null; } return fields[columnIndex].getImage(element); } public String getColumnText(Object element, int columnIndex) { if (element == null || fields[columnIndex] == null || fields == null || columnIndex < 0 || columnIndex > fields.length) { return ""; } return fields[columnIndex].getValue(element); } } |
我们还实现了一个TreeTableViewer,如清单5所示,TreeTableViewer会根据IField来创建TreeTable的column。
清单5:TreeTableViewer的代码
| public class TreeTableViewer extends CheckboxTreeViewer { private IField[] fields; public TreeTableViewer(Tree tree,IField[] fields, ITreeTableAdapterFactory adapterFactory) { super(tree); this.fields =fields; super.setContentProvider(new TreeTableContentProvider(adapterFactory)); super.setLabelProvider(new TreeTableLabelProvider(fields)); createColumns(); } public void setTableInput(Object[] input) { super.setInput(input); } protected void createColumns() { IField[] fields = getFields(); for (int i = 0; i < fields.length; i++) { if (fields[i] != null) { TreeColumn tc = new TreeColumn(getTree(), SWT.NONE); tc.setText(fields[i].getColumnHeaderText()); tc.setWidth(fields[i].getPreferredWidth()); tc.setData(fields[i]); } } } public IField[] getFields() { return fields; } } |
TreeTableViewer 的构造函数中需要一个 ITreeTableAdapterFactory作为参数,这是一个适配器工厂(参见《设计模式:可复用面向对象软件的基础》中的适配器工厂模式),主要根据每一行的对象获取到相应的ITreeTableAdapter作为行控制器。这个控制器主要用在了默认的TreeTableContentProvider中,详见清单6。
清单6:TreeTableContentProvider的代码
| public class TreeTableContentProvider extends ArrayContentProvider implements ITreeContentProvider { private ITreeTableAdapterFactory adapterfactory; public TreeTableContentProvider(ITreeTableAdapterFactory adapterfactory) { this.adapterfactory = adapterfactory; } public Object[] getChildren(Object parentElement) { return ((ITreeTableAdapter) adapterfactory.getAdapter(parentElement)) .getChildren(parentElement); } public Object getParent(Object element) { return ((ITreeTableAdapter) adapterfactory.getAdapter(element)) .getParent(element); } public boolean hasChildren(Object element) { return getChildren(element).length > 0; } } |
相关专题
- Eclipse应用技术 (515篇文章)
- J2SE综合:浅谈java程序发布之 jre 篇 (11次浏览)
- JAVA代码中使用魔法数值 (8次浏览)
- Hibernate缓存管理 (6次浏览)
- JAVA代码应该流畅和结构化 (5次浏览)
- Java JVM设置对性能的影响 (4次浏览)
- 开发框架:深入了解 Struts Validator (3次浏览)
- Java中的通信机制及与C/C API的集成 (1次浏览)
- 用Hibernate实现领域对象的自定义字段 (1次浏览)
- Java语言入门 简述Java语言回收机制 (0次浏览)
- 2008年Java开发者最迫切的五个期望 (0次浏览)




