在定制Eclipse SWT组件中实现MVC

  Eclipse SWT(标准部件工具包)提供了丰富的 API 集来实现定制部件(widget)。在这篇文章中,作者简要介绍了 MVC(模型-视图-控制器)架构,以结构化查看器的形式解释了 MVC 的当前实现,并介绍了一种使用定制 SWT 部件的实现。

  什么是 MVC?

  MVC 架构(或设计模式)是图形用户界面(GUI)的设计样式,由三部分构成:模型、视图和控制器。MVC 把表示层从数据解耦出来,也把表示从数据的操作解耦出来。

  实现 MVC 架构与其他类型的应用程序有所不同。主要的区别来自如何放置和实现业务逻辑或查看呈现逻辑。与典型的 Web 应用程序不同,在这类程序中,程序员必须设计和实现所有 MVC 组件,而 Eclipse 提供的 API 可以替您做大部分控制或呈现工作。所以,不能严格地把 Eclipse 的 MVC 实现与 Web 或其他应用程序类型的 MVC 进行比较。

  Eclipse JFace

  Eclipse JFace 用内容提供者和标签提供者实现 MVC 架构。JFace API 包装了标准(并非不重要的)部件,例如表和树,并实现了结构化内容提供者和标签提供者。可以根据部件类型实现不同的内容提供者。面向列表的查看器会实现结构化查看器,而内容则以结构化(列表的)方式映射到部件条目上。

  基类叫做 Viewer,它是结构化查看器的一个扩展。查看器充当部件容器。内容提供者以结构化的方式得到数据;类似地,标签提供者获得对应的标签。JFace 查看器实现检索该数据,设置对应的关联,并用数据集更新用户界面(UI)组件。它还执行选择、过滤和排序。

  如何实现 JFace

  Eclipse View 和 Viewer 负责执行大部分 JFace 控制功能。Viewer 或者说 MVC 的视图部分,也充当部件容器;这是表示组件。

  Eclipse View 实例化 Viewer、内容提供者和标签提供者,并充当模型,容纳值对象,并在 Viewer 中把它们设置为 inputElement。

  要创建 View,请用 createPartControl() 方法实例化 Viewer。清单 1 实例化一个默认的树查看器;您也可以定制树,并用树对象作为参数,用构造函数实例化树查看器。

  清单 1. ExampleView 的 CreatePartControl 方法

  public class ExampleView extends ViewPart   { ... public void createPartControl(Composite parent)   { // define a grid layout   GridLayout layout = new GridLayout();   layout.numColumns = 1;   layout.marginHeight = 0;   layout.marginWidth = 0; l  ayout.horizontalSpacing = 0;   layout.verticalSpacing = 1;   parent.setLayout(layout);   // create widgets createActionBar(parent);   createTree(parent);   // add context menu and listeners  viewer.addDoubleClickListener(this); viewer.addSelectionChangedListener(openAction);   // register viewer so actions respond to selection getSite().setSelectionProvider(viewer);   hookContextMenu();   }  private void createTree(Composite parent)   {   viewer = new TreeViewer(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);  viewer.setContentProvider(new ExampleViewContentProvider()); viewer.setLabelProvider  (new ExampleViewLabelProvider());   viewer.setSorter(new ViewerSorter());   viewer.setInput(ModelManager.getExampleModel());   viewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));   } ... }   

  在另一个独立类中实现 ContentProvider,它是一个对象,用适合查看器类型的接口向视图提供数据。例如,您可以实现 IStructuredContentProvider 或 ITreeContentProvider 查看器。

  请在 ContentProvider 代码中实现以下一个方法,把 ContentProvider 与 Viewer 相关联:

  • getElements(Object parent)
  • getChildren(Object element)

  注意:JFace 框架将调用这些方法。

  清单 2. 创建定制的 ContentProvider

    public class ExampleViewContentprovide implements ITreeContentProvide {  

  MVC 架构通常包含多个视图和一个数据源。目前在 Eclipse 平台上,只能把一个视图与一个模型相关联。但是,也可以创建多个视图,用适配器视图访问同一数据。只要把 inputChanged() 方法包含在 ContentProvider 类中即可。只要 Viewer 有新的输入集,就会使用 inputChanged() 方法通知 ContentProvider。inputChanged() 方法接受 Viewer 作为输入参数,所以多个视图可以使用一个 ContentProvider。

  清单 3. 将 inputChanged 方法用于不同的查看器

  /** * Register content provider with model. */   public void inputChanged(Viewer viewer, Object oldInput, Object newInput)   {   if (newInput != null)      {   this.viewer = viewer;  this.model = (ExampleDelegate)newInput; this.model.addModelListener(this);   }   }  

  与 Eclipse SWT 结合使用 MVC

  在多数常见 GUI 应用程序中,创建布局来显示请求的数据,或完成表单(例如用户界面)来添加或修改数据。图 1 的示例应用程序演示了如何在定制表单中,用只读和可编写模式显示来自 XML 存储的数据。它还解释了每个组件相对于 MVC 架构的角色。

  图 1. 示例应用程序

图 2 显示了应用程序的类图,有助于更好地理解整体架构。

  图 2. 示例应用程序的类图

  创建控件

  ExampleView 充当整个应用程序的容器。它将在 createPartControl 方法中初始化应用程序。

  清单 4. CreatePartControl 方法初始化布局

  public void createPartControl(Composite parent) {  ExampleEditLayout _layout = new       ExampleEditLayout(parent,SWT.NONE,FieldMode.Read,new ExampleViewContentProvider());  }

  创建表单和布局

  基本布局类定义了不同的表单应用程序使用的全局方法和声明。有些充当回调机制的容器事件,也注册到了这里。

  清单 5. 布局的 CreateControl 方法

  public void createControls(int style) {  GridData    gridData;  Text                textFld, subjectFld;  Control            toLabel, ccLabel, bccLabel;  Control            fromDateTime;  Control            control;  Button durationText;  Button submit;  GridLayout layout = new GridLayout(2, false);  layout.marginWidth = 0;  layout.marginHeight = 4;  setLayout(layout);  //Label  gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL  | GridData.VERTICAL_ALIGN_CENTER);  gridData.horizontalIndent = 10;  LabelFactory.create(this,     Messages.getString("ExampleEditLayout.Title"), gridData); //$NON-NLS-1$  gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL  | GridData.VERTICAL_ALIGN_CENTER);  gridData.horizontalIndent = 40;  LabelFactory.create(this, "", gridData);  //Text  gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL  | GridData.VERTICAL_ALIGN_CENTER);  gridData.horizontalIndent = 10;  control = LabelFactory.create(this,     Messages.getString("ExampleEditLayout.Email"), gridData); //$NON-NLS-1$  gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING  | GridData.VERTICAL_ALIGN_CENTER);  gridData.horizontalIndent = 10;  control = TextFactory.create(this,    SWT.BORDER | SWT.V_SCROLL | SWT.WRAP, gridData, FieldMode.Edit); //$NON-NLS-1$  addField(new TextField(control, ExampleViewContentProvider.FIRST_INDEX));  //Combo  gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL  | GridData.VERTICAL_ALIGN_CENTER);  gridData.horizontalIndent = 10;  LabelFactory.create(this,     Messages.getString("ExampleEditLayout.Group"), gridData); //$NON-NLS-1$  gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING  | GridData.VERTICAL_ALIGN_CENTER);  gridData.horizontalIndent = 40;  control = ComboFactory.create(this,     FieldMode.Edit, false, gridData); //$NON-NLS-1$  addField(new ComboField(control,  ExampleViewContentProvider.SECOND_INDEX));  ...}  

  创建字段(视图)

  Field 是一个抽象类,它定义了包含各种用户界面控件的方法,还有全局地识别这些控件的相关 ID。每个用户界面控件都是 Field 的子类,并向内容提供者提供了读写能力。清单 6 用工厂模式,在 Layout 类中创建了 Field。

  清单 6. 用 Field 类创建文本对象

  public class TextField extends Field {      /**      * @param control      * @param id      */      public TextField(Control control, int id) {          super(control, id);      }      /* Based on the ID of the widget, values retrieved from        * the content provider are set.       */      public  void readFromContent(IExampleContentProvider content) {          String newText = (String )content.getElement(getId());          if (newText != null)              ((Text )_control).setText(newText);      }      /* Based on the ID of the widget, values retrieved from widget are        * sent back to the content provider.       */      public void writeToContent(IExampleContentProvider content) {          String newText = ((Text )_control).getText();          content.setElement(getId(), newText);      }  }

  简化内容提供者(模型)

  ExampleViewContentProvider 充当模型侦听器,后者扩展自 IStructuredContentProvider。它是 Eclipse API 的简单实现,提供了用于检索数据的回调。每个请求数据的条目都基于视图创建时在布局中为条目定义的惟一 ID。

  方法调用会返回与每个定义的全局 ID 关联的数据。在 清单 7 所示的内容提供者中,可以使用适配器从 XML 文件或数据库检索数据。

  清单 7. 在定制的 ContentProvider 中实现方法

  public Object getElement(int iIndex) {          switch (iIndex) {          case FIRST_INDEX: return "developer@ibm.com";          case SECOND_INDEX : return new Integer(1);          case FOURTH_INDEX : return new Boolean(true);          case THIRD_INDEX: return new Boolean(false);          case FIFTH_INDEX: return new Boolean(false);          }          return null;      }  

  创建了控件并初始化布局之后,表单会用控件 ID 要求内容提供者用数据填充表单控件。

  清单 8. 初始化布局并填充控件的表单

  public Form (Composite parent, int style, FieldMode mode, ExampleViewContentProvider content) {              super(parent, style);              _content = content;              _style = style;              setMode(mode);              init(style);      }         private void init(int style) {              createControls(style);          controlsCreated();      }  protected void controlsCreated() {              readFromContent();      }  

  结束语

  Web 应用程序是 MVC 架构样式的早期实现者。但是,随着像 Eclipse 这样的简单而强大的开发平台的到来,程序员可以轻易地用更短的时间和最小的复杂程度,开发出更丰富的用户界面。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索数据
, 视图
, 方法
, 应用程序
, nhanced attern ayout
, raphics inear ayout
, rawer ayout
, GridData
, contentprovider实例
组件样式定制
swt组件、swt组件注册快捷键、eclipse swt、org.eclipse.swt、org.eclipse.swt 64位,以便于您获取更多的相关知识。

时间: 2024-11-01 12:38:49

在定制Eclipse SWT组件中实现MVC的相关文章

在定制SWT组件中实现MVC

学习如何容易地把模型 - 视图 - 控制器与基于 Eclipse 的应用程序集成在 一起 简介: Eclipse SWT(标准部件工具包)提供了丰富的 API 集来实现定制部 件(widget).在这篇文章中,作者简要概括了 MVC(模型 - 视图 - 控制器) 架构,以结构化查看器的形式解释了 MVC 的当前实现,并介绍了一种使用定制 SWT 部件的实现. 什么是 MVC? MVC 架构(或设计模式)是图形用户界面(GUI)的设计样式,由三部分构成 :模型.视图和控制器.MVC 把表示层从数据

eclipse jface组件中如何隐藏TitleAreaDialog对话框右上方的关闭按钮

问题描述 请教一个问题,eclipse jface对话框组件中要想隐藏 TitleAreaDialog 类型对话框右上方的关闭按钮要如何处理.现在我是用的 @Override protected boolean canHandleShellCloseEvent() { return false; }来处理的,当用户点击关闭按钮时使之对应的关闭对话框的event失效.但是感觉很别扭,希望指点.谢谢! 解决方案 直接上代码了.public class TDialog extends TitleAre

如何eclipse jface组件中TitleAreaDialog对话框上方的关闭按钮进行置灰处理

问题描述 描述如下:第一个对话框:名称为A (TDialog.java)第二个对关闭按钮进行隐藏后的对话框:名称为B (TDialog1.java)原本想用隐藏就可以解决问题的.描述:点击 A中按钮,弹出B 存在的问题:点击A中按钮,弹出B 但是用鼠标点击B时,B就自动隐藏了,没法进行操作.最小化eclipse后,桌面上显示 B对话框,并且可以对其进行操作.(代码见附件,demo不存在此问题)所以我想要对关闭按钮进行置灰处理,不知道这样处理后能不能变通解决对上述问题.或者有什么更好的方法进行处理

Eclipse开发经典教程之常用SWT组件

在介绍组件之前,有必要介绍一下Control类.Control类是一个抽象类,它是所有窗口组 件(即在Windows中能获得句柄的部件)的基类. Control类的继承关系 Control类是为继承而设计的,所有窗口组件都继承于Control类,如图1所示. 开发经典教程之常用SWT组件-swt组件"> 图1 Control类的继承关系 Control的一个实例代表Windows中的一个窗口组件,它中有窗口名柄属性,但是在程序中 不能够直接访问. Control类的常用方法 Control

使用定制Eclipse信息中心为IT解决方案编制文档,第2部分

第2部分: 提升您捕捉和重用内容的能力 概述 在 使用定制 Eclipse 信息中心为 IT 解决方案编制文档,第 1 部分:创建您的第一个信息中心 中,您创建了自己的第一个解决方案信息中心,内含一个文件.在掌握了基础知识后,您就可以开始学习加速内容库内的文档的积累的技巧了,首先要做的是导入一个满载内容的示例解决方案信息项目. 从另外一个工具箱的用户导入内容 积累内容的第一种快捷途径是导入由其他用户创建的解决方案信息项目.若您的团队中有任何人捕捉到内容,那么团队中的所有人均可重用此内容.导入一个

使用定制Eclipse信息中心为IT解决方案编制文档,第1部分

第 1 部分: 创建您的第一个信息中心 概述 实现 IT 解决方案的过程涉及集成并定制各种软硬件组件.要针对已实现的解决方案整理一份 "维护指南",相关的文档和其他技术信息可能涉及多个作者.文档位置和文档格式 - 范围涉及传统的 teamrooms 和官方文档.论坛.博客和 wiki.收集.整理并向您的客户(或老板.团队)交付这些文档需要付出大量的劳动,如果您不擅长此类任务的话,则更是一项费力的工作.另一种选择就是提供不够充分的文档,而它的缺点就是增加了支持成本.不能有效利用生产力,并

定制Eclipse IDE之界面篇

为什么要定制IDE?      在工作时候,当公司有了自己的框架,给自己开放人员用,甚至是可以卖的时候,我们可以做成一个产品,而这个产品将包括框架本身.文档.工具.教程等等.工具之中最重要的莫过于开发工具(IDE).调试工具.      我在公司里面做的是一个hybrid框架,而一个配套的IDE是比不可少的,主要用来开发HTML5.这个IDE可以算是框架东西的聚合,可以将在线文档.工程模板.打包调试等功能都揉合在IDE.当我们提供给开发者东西时,我们只需要提供一个IDE,里面已经包含所有框架的东

java.util.list和org.eclipse.swt.widgets.list无法同时使用

问题描述 java.util.list和org.eclipse.swt.widgets.list无法同时使用 想合并两段代码,但是java.util.list和org.eclipse.swt.widgets.list两个包无法同时使用,怎么办?急,萌新求大神帮忙解决一下,谢谢! 解决方案 如果一个类文件中需要同时使用这两种类型的话,可以在定义变量的时候加上类的包名的全路径名称.例如: List l1 = new java.util.ArrayList(); 解决方案二: 写全路径 java.ut

org.eclipse.swt.SWTError: No more handles的解决办法

今天装了JBoss Tools 3.1 插件后,eclipse 打开jsp文件老是报错,或者要我关闭: org.eclipse.swt.SWTError: No more handles 网上找了两个解决方法: 方法一: 找到目录 eclipse\workspace\.metadata\.plugins\org.eclipse.ui.workbench 下面的 workbench.xml文件,删除在XML节点 <mruList> </mruList> 之间的所有内容,然后运行Ecl