利用视图链接使Eclipse应用程序更丰富

程序|链接|视图

  丰富的 GUI 中的视图可以以各种方式显示信息,从而改善用户体验。非常自然,UI 视图之间是相互依赖的,需要进行交互。Eclipse 简化了链接 UI 视图的工作,并提供了将视图链接应用到非 UI 场景的方式。

  简介

  Eclipse 平台允许使用可插入组件 —— 插件 —— 帮助创建丰富的图形用户界面(graphical user interface,GUI)应用程序。例如,插件可以向 GUI 提供视图。但是,在现实的应用程序中,UI 视图不能是孤立的。它们需要根据其他视图的状态进行交互和对本身进行更新。

  一个简单的例子是描述世界各地的主要旅游目的地的 GUI 应用程序。这个 GUI 可能有一个 Select City 视图,用于显示旅游景点和公共交通信息。


图 1. 视图链接的例子
  本文介绍在 Eclipse 中结合视图的方式以及如何对其他视图的状态做出响应。还讨论链接视图方式在哪些情况下可能比其他方式合适。

  Eclipse 开发人员可以依赖以下方法对视图进行链接:

  选择提供器 - 选择监听器(selection provider-selection listener)模式,从而让视图对其他视图中的选择做出反应
  IAdaptable 接口,与某些事件结合使用
  属性改变监听器,它允许视图将属性改变事件告之已注册的监听器

  选择提供器 - 选择监听器范型

  选择提供器 - 选择监听器模式能够方便地创建对其他视图中的改变做出响应的视图。例如,当用户点击代表城市名的 UI 项时,另一个视图可能需要显示这个城市的景点详情。这样的视图可以使用 UI 选择对象(可能是代表城市名的字符串对象)中包含的信息,并使用它从模型中获取和显示其他信息。

  视图应该能够识别并利用 UI 选择事件。org.eclipse.ui.ISelectionListener 是接收 UI 选择事件的监听器接口。选择监听器必须注册到工作台页面。工作台页面实现 org.eclipse.ui.ISelectionService 接口定义的服务,从而将 UI 选择事件告之监听器。选择监听器必须注册到选择服务。

  用于显示可选择的 UI 项的视图还应该能够公布 UI 选择。视图通过将 “选择提供器” 注册到它们各自的工作台站点来实现这一点。Eclipse 中的每个 UI 部分通过 org.eclipse.ui.IWorkbenchPartSite 引用与工作台站点联络。选择提供器注册到工作台站点。

  在使用选择提供器 - 选择监听器模式链接视图时,视图可以将本身作为监听器添加到工作台页面,而希望公布选择的其他视图必须将选择提供器添加到它们各自的工作台站点。org.eclipse.ui.ISelectionListener 接口如下所示。

public void selectionChanged(IWorkbenchPart part, ISelection selection);

  要使视图能够监听选择改变,视图必须实现 ISelectionListener 接口并必须将自己注册到工作台页面。清单 1 显示一个例子。

  清单 1. 将选择监听器添加到工作台页面

public class MyView extends ViewPart implements ISelectionListener{

public void createPartControl(Composite parent) {

// add this view as a selection listener to the workbench page
getSite().getPage().addSelectionListener((ISelectionListener) this);

}

// Implement the method defined in ISelectionListener, to consume UI selections
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
//Examine selection and act on it!
}

}

  使用 UI 选择的更好的方法是,将消费者视图作为监听器注册到特定的视图部分。正如在下面的例子中可以看到的,源视图部分的视图 ID 在注册选择监听器期间被作为一个参数。

getSite().getPage().addSelectionListener("SampleViewId",(ISelectionListener)this);

  这种方式可以避免对消费者视图进行多余的回调,如果视图被注册为非特定的监听器,就会出现这种情况。 清单 2 中的代码片段显示一个视图的 createPartControl() 方法,这个方法创建一个 JFace TableViewer 并将它作为选择提供器添加到工作台站点。这些代码使 TableViewer 中的任何 UI 选择改变能够传播到页面,并最终传播到对这种事件感兴趣的消费者视图。

  清单 2. 设置选择提供器

public void createPartControl(Composite parent) {
// Set up a JFace Viewer
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
viewer.setContentProvider(new ViewContentProvider());
viewer.setLabelProvider(new ViewLabelProvider());
viewer.setSorter(new NameSorter());
viewer.setInput(getViewSite());

// ADD the JFace Viewer as a Selection Provider to the View site.
getSite().setSelectionProvider(viewer);

}

  这个视图将它创建的 JFace TableViewer 注册为选择提供器有两个原因:

  这个视图打算使用这个 TableViewer 显示信息,而且用户将与 TableViewer 进行交互。

  TableViewer 实现了选择提供器接口并能够向工作台部分站点传播选择事件。

  因为 JFace 查看器是选择提供器,所以在大多数情况下就不必创建选择提供器了。视图只需使用众多的 JFace 查看器之一来显示信息,并将 JFace 查看器注册为选择提供器。

  另一种链接方式

  某些情况需要另一种视图链接方式:

  信息量可能太大,由于内存使用量增加,UI 选择对象无法有效地容纳它。

  视图可能希望公布其他信息,而不只是公布可视化选择信息。公布的信息可能是根据选择进行某些后期处理的结果。

  视图可能希望使用来自另一个插件的信息,而这个插件可能根本没有提供视图(使用包含的 JFace 查看器)。在这种情况下,使用基于 UI 选择的链接是不可能的。

  可以使用 org.eclipse.core.runtime.IAdaptable 接口来缓解第一个问题,这个接口使选择对象能够在需要时传播更多信息。第二个和第三个问题需要用手工方式解决,属性改变监听器模式是合适的解决方案。

  使用 IAdaptable 接口

  实现 IAdaptable 接口的类能够动态地返回某些类型的适配器,然后可以使用这些适配器获取更多信息。如果查看器中的选择对象实现了 IAdaptable 接口,那么根据它们可以返回的适配器类型,可以有效地获取更多信息或相关信息。org.eclipse.core.runtime.IAdaptable 接口如下所示。

public void object getAdapter(Class adapter);

  显然,调用者应该知道它期望选择返回的适配器接口类型。考虑一个 JFace TreeViewer,它在一个单层的树中显示城市。代表城市的对象是 CityClass 类型的。CityClass 对象应该包含关于此城市的基本信息,并只在需要时返回详细信息。在清单 3 中要注意,CityClass 支持的适配器类型使调用者能够在需要时获得更多信息。

  清单 3. JFace TreeViewer 中的 CityClass

class CityClass implements IAdaptable {
 private String cityName;

 public CityClass(String name) {
  this.name = name;
 }
 public String getName() {
  return name;
 }
 public CityClass getParent() {
  return parent;
 }
 public String toString() {
  return getName();
 }
 public Object getAdapter(Class key) {
  if (key.getName().equals("ITransportationInfo"))
   return CityPlugin.getInstance().getTransportAdapter();
  else (key.getName().equals("IPlacesInfo"))
   return CityPlugin.getInstance().getPlacesAdapter();
  return null;
 }
}

  熟悉 Eclipse IDE 工作台的开发人员都了解 Outline 视图,这个视图提供了编辑器中打开的文件的结构化视图。这个 Outline 视图展示了 IAdaptable 接口如何与某些事件类型结合使用,从而有效地根据其他视图的内容对视图进行初始化。编辑器必须为用户打开的文件创建一个 Content Outline 页面。Content Outline 页面符合 IContentOutlinePage 接口。编辑器还必须实现 IAdaptable 接口,这样就能够向编辑器查询 IContentOutlinePage 类型的适配器。使用这个适配器来获取和显示文件的大纲信息。

  IAdaptable 接口的另一个例子是 Properties 视图。Properties 视图跟踪对活动部分的选择,并调用当前选择对象上的 getAdapter 方法。查询的适配器类型是 IPropertySource。然后,Properties 视图使用 IPropertySource 适配器来获取要显示的信息。

  在这些视图链接例子中,应用程序在接到 Selection Changed 或 Part Activation 通知时,通过 IAdaptable 获取信息。因此,如果选择对象实现了 IAdaptable,那么与从选择对象本身获取的信息量相比,用户可以通过适配器获得多得多的信息。

  属性改变监听器范型

  可以使用属性改变监听器类型的交互来解决前面提到的另外两个问题:视图如何使用来自未提供视图的插件的信息,以及视图如何公布在可视化选择之后某些处理所生成的信息?

  可以建立一个插件来接受属性改变监听器的注册,并在需要时通知注册的监听器。应用程序可以将定制的事件告之监听器,事件中还可以包含要共享的信息。

  与选择提供器的情况不同,属性改变提供器不需要实现特定的接口。您必须决定将监听器注册到提供器的语义。清单 4 中的代码片段是一些方法,它们允许在属性提供器视图或插件类中添加或删除属性改变监听器。

  清单 4. 添加和删除属性改变监听器

//To add a listener for property changes to this notifier:

public void addPropertyChangeListener(IPropertyChangeListener listener);

//To remove the given content change listener from this notifier:

public void removePropertyChangeListener(IPropertyChangeListener listener);

  属性提供器应该使用 org.eclipse.jface.util.PropertyChangeEvent 来创建一个可以有效填充和传播的事件。另外,属性提供器要负责维护监听器列表并对它们进行回调。

  作为一个例子,请考虑一个每小时调用 World Weather Web Service 来查询主要城市的气象的插件,它要使这些信息可供其他插件和视图使用。CityWeatherPlugin 可以公开一个称为 CitiesWeatherXML 的属性,消费者可以将本身作为 PropertyChange 监听器注册到 CityWeatherPlugin。为此,监听器必须了解 CityWeatherPlugin 中的注册方法,这样才能将本身注册为气象数据事件的监听器。CityWeatherPlugin 应该跟踪并通知监听器。它使用 PropertyChangeEvent 向监听器提供数据。

  清单 5. 创建属性提供器

class CityPopulationPlugin {
 ArrayList myListeners;

 // A public method that allows listener registration
 public void addPropertyChangeListener(IPropertyChangeListener listener) {
  if(!myListeners.contains(listener))
   myListeners.add(listener);
 }

 // A public method that allows listener registration
 public void removePropertyChangeListener(IPropertyChangeListener listener) {
  myListeners.remove(listener);
 }

 public CityPopulationPlugin (){
  // method to start the thread that invokes the population \
  web service once every hour
  // and then notifies the listeners via the propertyChange() callback method.
  initWebServiceInvokerThread( myListeners );
 }

 void initWebServiceInvokerThread(ArrayList listeners) {
  // Code to Invoke Web Service Periodically, and retrieve information

  // Post Invocation, inform listeners
  for (Iterator iter = listeners.iterator(); iter.hasNext();) {
   IPropertyChangeListener element = (IProperty\
   ChangeListener) iter.next();
   element.propertyChange(new PropertyChangeEvent(this, \"CitiesWeatherXML" , null , CityWeatherXMLObj));
  }
 }
}

  属性改变监听器必须实现 org.eclipse.jface.util.IPropertyChangeListener 接口,以便允许属性改变提供器对它进行回调。这个接口有一个方法 public void propertyChange(PropertyChangeEvent event)。

  清单 6. 实现 IPropertyChangeListener

class MyView implements IPropertyChangeListener {

 public void createPartControl() {
  //register with a Known Plugin that sources Population Data
  CityPopulationPlugin.getInstance().addPropertyChangeListener(this);
 }

 public void propertyChange(PropertyChangeEvent event) {

  //This view is interested in the Population Counts of the Cities.
  //The population data is being sourced by another
  plugin in the background.

  if( event.getProperty().equals("CitiesWeatherXML")) {
   Object val = event.getNewValue();
   // do something with val
  }
 }
}

  这种方式的灵活性在于,应用程序可以在需要时通知监听器,并根据各种场景向它们传递信息。传递的信息不必直接与 UI 选择相关;这些信息可以是某些后期处理的结果。另外,它可以与其他后台作业的状态相关,或者是定期从模型中获取的最新信息。例如,City Selector View 可能不只是传播选择的城市,还使用 PropertyChange 范型将当前选择的城市的气象信息异步地传播给其他消费者。

  结束语

  本文讨论了使视图相互协作和响应的各种方式。如果 UI 选择本身不够,可以使用 IAdaptable 接口加强它们。属性改变监听器也为满足非 UI 场景提供了更大的灵活性。

时间: 2024-10-26 18:12:56

利用视图链接使Eclipse应用程序更丰富的相关文章

利用Scala语言开发Spark应用程序

利用Scala语言开发Spark应用程序[转:董的博客 http://www.dongxicheng.org] Spark内核是由Scala语言开发的,因此使用Scala语言开发Spark应用程序是自然而然的事情.如果你对Scala语言还不太熟悉,可以阅读网络教程A Scala Tutorial for Java Programmers或者相关Scala书籍进行学习. 本文将介绍3个Scala Spark编程实例,分别是WordCount.TopK和SparkJoin,分别代表了Spark的三种

从C#到Objective-C,循序渐进学习苹果开发(5)--利用XCode来进行IOS的程序开发

本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台苹果开发的一系列感想和体验历程,本系列文章是在起步阶段逐步积累的,希望带给大家更好,更真实的转换历程体验.前面几篇随笔主要介绍C#和Objective-C之间的差异,本片开始介绍利用XCode来进行IOS的程序开发,对比和C#利用VS进行开发的差异,以便我们更快的融入到IOS开发的阵营. 在介绍利用XCode来开发项目前,我自己消化了几本IOS开发的书籍,以及苹果开发网站的一些自认为重要文章介绍,学习了一些视频的内容,包括网易里面

集成Windows本地应用到Eclipse RCP程序中

Windows 应用程序非常丰富,而有时我们的 Eclipse RCP 程序所需要的一些功能已经有一些现有的 Windows 本地应用程序的实现,我们希望能够在我们的 RCP 程序中重用这些功能.一种最简单的重用方法就是直接在我们 RCP 窗口中嵌入本地应用程序窗口.要使得一个 Windows 本地应用程序能够在我们的 RCP 程序中运行,我们可以使用 Windows 提供的 reparent 机制.利用这种机制实现窗口嵌入的主要过程是:首先要在我们的程序中启动要嵌入的 Windows 程序,然

【AI系统首次实现真正自主编程】利用遗传算法,完爆初级程序员

本文讲的是利用遗传算法,完爆初级程序员,让AI自动编程一直是计算机科学家的梦想.目前这个方面的成果还非常有限,比如让AI自动补完编程语言,或者执行简单的加法程序.今天我们要介绍的这项工作,号称是第一个能够全自动生成完整软件程序的机器学习系统"AI Programmer". 研究人员表示,他们用这个系统证明了长久以来的假设,那就是功能完备的程序确实能够被自动生成.具体到这项工作,AI Programmer利用机器学习中的遗传算法,模拟复杂的指令.虽然现在AI Programmer生成的程

系统-利用免费空间开发CS客户端程序

问题描述 利用免费空间开发CS客户端程序 最近小弟想做一个CS客户端软件,其实也算不上CS架构,因为大部分运算都在客户端完成,只是这个软件需要基本的用户登陆.注册系统. 但是现在网上服务器好像都不太便宜,小弟想初期先运行"内测"一段时间,如果比较火受欢迎再考虑增加投入,所以目前不想花钱来做测试. 于是我想到了免费空间,现在网上有不少地方可以申请到免费的网站空间,只是小弟只是对C#和VB略知一二,对网页编程就是小白一个. 不知道各位大神能否指点一二,给个方向让小弟摸索学习? 需求概括:利

Eclipse客户端程序中多线程的使用

简介:本文分析了Eclipse中多线程程序的实现,讨论了在Eclipse客户端程序开发中应用多线程的方 法和要注意的问题,同时也讨论了多线程程序的一些调试和问题解决的方法. Eclipse作为一个开发平台,使用越来越广泛,基于Eclipse Rich Client Platform开发的客户端程序 也越来越多.在当今越来越复杂的应用环境中,我们的客户端程序不可避免的要同时进行多任务的处理. 一个优异的客户端程序都会允许用户同时启动多个任务,从而大大提高用户的工作效率以及用户体验.本 文中我们来谈

利用JMail组件快速构建邮件程序(下)

上文<利用JMail组件快速构建邮件程序(上)>中介绍了邮件的发送,本文将介绍邮件的接收过程,示例代码运行效果图如下: 三.邮件接收篇 3.1 利用IPOP3接收邮件 接收邮件时用到的接口是IPOP3, 首先连接上邮件服务器,从Messages中得到邮件信息集合,然后就可以通过遍历集合取得每条Message中的具体内容. 请看如下代码: jmail::IPOP3Ptr pPOP3("JMail.POP3"); // 非必须,设置超时时间为60秒,默认为120秒 pPOP3-

eclipse中程序一直意外停止

问题描述 eclipse中程序一直意外停止 解决方案 很多错误信息,对应分析一下

c语言-如何使C语言程序实现可视化?

问题描述 如何使C语言程序实现可视化? 要做一个实现光谱计算啥的程序,并把它做成一个可视化窗口形式,就是可以用鼠标点击,有输入数据和输出数据的...求大神帮助...新手一个,也没有C币,但求一大神.., 解决方案 找个人用C#给你做吧,C语言做界面比较麻烦,估计你搞不定... 解决方案二: 纯 C?是什么编译环境?以前最早在 Turbo C 2.0 +Dos 下都可以做到,只是编程复杂很多. 如果是在 Windows/Linux 平台下,最好是使用可视化的编程工具.否则,要学习的东东很多! 解决