科技行者

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

知识库

知识库 安全导航

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

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

  • 扫一扫
    分享文章到微信

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

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

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

关键字:

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

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

可用于行控制器的IWorkbenchAdapter接口

  IWorkBenchAdapter是Eclipse JDT中经常用到的一个接口,该接口通常用于不同类型的节点在树中的显示,如我们常见的Java包浏览器,从接口以及API文档中我们可以看到它的层次关系。图4的类阶层结构展示了Java包浏览器如何使用IWorkBenchAdapter对节点分类显示的。

  图4:IWorkBenchAdapter 的类阶层结构

  IWorkBenchAdapter 的类阶层结构

  图4中可以明显看见WorkBenchAdapter类会将每个对象(文件,文件夹,项目)适配包浏览器中的树节点,如果我们想象树中的每个节点代表每一行数据(一个只有一列的表),那么这样一种设计模式就是完全按行来控制的行控制器设计模式,我们可以为不同类型的行数据创建不同的适配器,精确控制这些数据的表现形式,如背景色、前景色、字体等,只要你愿意,还可以增加一些菜单或者打开编辑器等丰富的功能。本文将借鉴Eclipse的这一模式来设计TreeTable的行控制功能。图4显示了对File,Folder和Project这三种不同类型的数据做不同的控制,我们的构件中,将能够根据对象而不是类型做更为精确的控制。本文将参考WorkBenchAdapter的设计实现TreeTable的行控制器。

  3.创建可重用的TreeTable构件

  基于以上的研究,我们实现了一个高度可重用的TreeTable构件,限于篇幅,我们只实现了能够说明问题的最关键的功能

  使用IField实现列控制

  为了便于说明问题我们创建了一个简单版本的IField接口,参见图5。

  图5:简化后的IField接口

  简化后的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;
 }
}

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

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

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