科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Eclipse设计实现可重用的SWT构件

Eclipse设计实现可重用的SWT构件

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文从创建一个简单的SWT Tree Table开始,引入可重用的用户界面构件这个开发人员普遍关心的问题,然后分析Eclipse的用户界面的一些设计模式,循序渐进的向读者展示了如何设计实现一个精巧的高度可重用的TreeTable构件。

作者:翁长河 来源:论坛整理 2007年11月21日

关键字:

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共6页)

使用ITreeTableAdapter实现行控制

  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的关系

  TreeTableContentProvider和ITreeTableAdapter的关系

  如图6, 在这样的设计结构下,所有的适配器被适配器工厂统一管理,一旦行数据的模型发生改变,系统只需要增加相应的适配器就可以了,系统的结构完全是开放的,可扩展的,并且这种扩展关系是非侵入的,不会造成模型或者视图的代码膨胀。

  完整的TreeTable构件

  现在,基于以上的设计和分析,我们实现了TreeTable构件,如图7所示,该构件包装了一个使用TableLayout的Tree构件,在该tree的viewer中,我们使用到了特殊的ContentProvider和LabelProvider。如清单9所示,TreeTable使用IField控制table的列行为,使用ITreeTableAdapter控制行行为。虽然看起来比原来的简单实现复杂,但是结构清晰,便于维护和升级,我们可以轻易的增加新的功能而不会破坏良好的程序结构,我们将在第4部分向读者展示这一点。图7:TreeTable构件的类图

  图7:TreeTable构件的类图

  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。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章