ITreeTableAdapter的接口很简单,它参考了IworkbenchAdapter接口的设计,实现了TreeTable中的行逻辑的控制,详见清单7。
清单7:ITreeTableAdapter的代码
| public interface ITreeTableAdapter { public Object[] getChildren(Object o); public Object getParent(Object o); public Color getBackgroundColor(Object element); } |
为什么TreeTableContentProvider一定需要一个ITreeTableAdapterFactory来作为参数构造呢? 我们考虑一些复杂的情况,一个Table的行,可能会有多种类型的控制方式(还记得第二部分的IWorkbenchAdapter有三个实现吗?)因此我们会为每种类型的行数据创建一个特殊的行控制器,ITreeTableAdapterFactory可以为ContentProvider提供多个ITreeTableAdapter以实现不同类别的行数据的控制逻辑可以单独在一个类中实现,有效的隔离了代码,使得应用程序结构比较清晰。如果你的程序足够简单,你只需要实现一个ITreeTableAdapter,然后使用FixedTreeTableAdapterFactory就可以了,如清单8所示,FixedTreeTableAdapterFactory的接口非常简单,就是返回一个固定的适配器。
清单8:FixedTreeTableAdapterFactory的代码
| public class FixedTreeTableAdapterFactory implements ITreeTableAdapterFactory{ private ITreeTableAdapter adapter; public FixedTreeTableAdapterFactory(ITreeTableAdapter adapter){ this.adapter=adapter; } public ITreeTableAdapter getAdapter(Object treeitemdata) { return adapter; } } |
通常的适配器模式,被适配的对象需要实现IAdaptable的接口,显然这里我们不能采用侵入方式的adapter模式。我们的对象模型是纯净的对象模型,因此我们需要适配器工厂模式,通过工厂取得适配器对象。根据对象获取适配器可以更为精确的控制你的程序,例如我们的示例中,如果不同的部门在table中的行为需要严格控制,或者出生年龄在一定区间的员工需要特殊显示,那么我们可以为每种有特定需求的行数据对象建一个适配器,根据判断行数据的属性来找到具体的适配器。相比较IWorkBenchAdapter, ITreeTableAdapter做了一些修改,不需要提供Label和Image,我们的ITreeTableAdapter更关注行的控制。TreeTableContentProvider和ITreeTableAdapter的关系详见图6所示。
图6:TreeTableContentProvider和ITreeTableAdapter的关系
如图6, 在这样的设计结构下,所有的适配器被适配器工厂统一管理,一旦行数据的模型发生改变,系统只需要增加相应的适配器就可以了,系统的结构完全是开放的,可扩展的,并且这种扩展关系是非侵入的,不会造成模型或者视图的代码膨胀。
完整的TreeTable构件
现在,基于以上的设计和分析,我们实现了TreeTable构件,如图7所示,该构件包装了一个使用TableLayout的Tree构件,在该tree的viewer中,我们使用到了特殊的ContentProvider和LabelProvider。如清单9所示,TreeTable使用IField控制table的列行为,使用ITreeTableAdapter控制行行为。虽然看起来比原来的简单实现复杂,但是结构清晰,便于维护和升级,我们可以轻易的增加新的功能而不会破坏良好的程序结构,我们将在第4部分向读者展示这一点。图7:TreeTable构件的类图
图7:TreeTable构件的类图
清单9:TreeTable的代码
| public class TreeTable { protected Composite parent; protected Tree tree; protected TreeTableViewer treeViewer; protected ViewForm form; private ITreeTableAdapterFactory adapterFactory; public TreeTable( Composite parent,int style,IField[] fields, ITreeTableAdapterFactory adapterFactory) { this.parent=parent; this.adapterFactory=adapterFactory; initTable( parent , style); treeViewer= new TreeTableViewer(tree,fields,adapterFactory); form.setContent(tree); } private void initTable( Composite parent , int style) { form = new ViewForm(parent, style); form.setLayout(new FillLayout()); form.setBorderVisible(false); form.marginHeight = 0; form.marginWidth = 0; GridData gd = new GridData(SWT.FILL,SWT.FILL,true,true); form.setLayoutData(gd); initTree(form,style); } private void initTree(Composite parent, int style) { tree=new Tree(parent,style); tree.setHeaderVisible(true); tree.setLinesVisible(true); tree.setEnabled(true); tree.setLayout(new TableLayout()); } public void setInput(Object[] inputs){ if(treeViewer!=null) treeViewer.setTableInput(inputs); } public Tree getTree() { return tree; } public TreeTableViewer getTreeViewer() { return treeViewer; } } |
本部分的所有代码我们已经打包于附件中的common.reuse.ui_1.0.0.jar。
URL查看 http://www.qqread.com/java/2008/02/r399149.html相关专题
- 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次浏览)





