简介

Eclipse平台的插件机制可以使用户方便的创建GUI程序。例如,插件可以给GUI提供Views(查看器)。这些UI的View需要和其他组件关联才能真正发挥发挥作用,否则将形成“孤岛”。

以下图所示的一个旅游景点介绍的GUI应用程序为例,这个GUI程序将景点列表View和景点介绍View关联在一起,当在景点列表View中选择不同的旅游景点时,景点介绍View会显示相应的介绍。

本文将介绍Eclipse中的View如何与其他View进行交互的三种方式,并分析在不同的情况下这几种方式的优劣。Eclipse开发人员可以使用下面这三种方式来关联View:

1 “选择提供者 -- 选择监听者”模式。

2 结合一些事件(Events)使用IAdapatble接口

3 属性变化监听器,它可以在属性变化事将事件推送(Push)到注册的监听器中。

选择提供者 -- 选择监听者”模式

“选择提供者 -- 选择监听者”模式可以使一个View来响应其他View的变化。例如,当用户点击景点列表View的一个城市名时,其他view想获得这个悬着事件并作出响应。这些VIew需要UI Selection对象中的信息(比如表示城市名称的一个String)并使用这些信息来从模型中获取其他相关信息。

View应该具备识别和使用UI Selection事件对象的能力。org.eclipse.ui.ISelectionListener是一个用于监听UI选择事件的监听器接口。选择事件监听器必须在workbench page中注册。Workbench page实现了rg.eclipse.ui.ISelectionService接口定义的service,将UI Selection事件发送到监听器中。选择事件监听器必须和一个选择服务一起注册。

能被选择的UI View具备发布UI selection事件的能力,view可以通过在他们各自的workbench site中注册“selection provider”来实现这一点。Eclipse中的每一个UI View都通过org.eclipse.ui.IWorkbenchPartSite 与workbench site相关联。Selection provider是在workbench site中注册的。

在views使用“选择提供者 -- 选择监听者”模式关联起来之后,一个view在workbench page中注册为监听器,其他的view若要发布selection事件,则需在各自的workbench site中注册为selection provider。org.eclipse.ui.ISelectionListener 接口签名如下所示:

  public void selectionChanged(IWorkbenchPart part, ISelection selection);

若要使一个view可以监听选择变化事件,此View必须实现ISelectionListener 接口并在workbench中进行注册,如下面的代码所示:

public class MyView extends ViewPart implements  ISelectionListener{public void createPartControl(Composite parent) {// add this view as a selection listener to the workbench pagegetSite().getPage().addSelectionListener((ISelectionListener) this);
}// Implement the method defined in ISelectionListener, to consume UI selectionspublic void selectionChanged(IWorkbenchPart part, ISelection selection) {//Examine selection and act on it!}
}

更好的方式是指定所监听的View,只需将目标View的ID作为第一个参数传递过去就可以实现,如下所示:

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

下面的代码展示了如何将一个view中的tableviewer注册为workbench site中的selection provider。注册后在view中的tableviewer的UI selection变化将被相应的监听器获得。

public void createPartControl(Composite parent) {// Set up a JFace Viewerviewer = 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);
}

这个view将它创建的TableViewer注册为selection provider是因为:

1 这个view将使用tableviewer来显示信息,用户将与TableViewer交互

2 TableViewer实现了selection provider接口,可以将选择事件发布到workbench part site中。

JFace viewer都是选择事件提供者,因此您在使用它们时不需要创建一个选择事件提供者。一个View仅仅需要在其中使用JFace Viewer并将其注册为selection provider即可实现选择事件的发布。

我们需要不同的关联方法

尽管“选择提供者 -- 选择监听者”模式使用方便并且能满足大多数的需求,但由于以下原因,我们仍需要一种不同的方式来关联视图:

1 信息量超过了UI selection对象的承载力。

2 View需要发布处理后的信息而不仅仅是选择对象信息。

3 View需要监听一个不包含JFace viewer对象的View。

您可以使用org.eclipse.core.runtime.IAdaptable接口来解决第一个问题,这个接口可以使一个选择事件对象承载更多的信息。需求2和3则需要程序员做更多的工作,也许“属性变化监听器模式”更适用于那种需求。

使用IAdaptable 接口

实现IAdaptable接口的类可以动态地根据需求返回不同适配器,这些适配器可以用来获取更多的信息。若一个viewer中的selection对象实现了IAdaptable接口,那么它可以使用不同类适配器来提供更多信息。org.eclipse.core.runtime.IAdaptable接口的签名如下:

public void object getAdapter(Class adapter);

很明显,调用者应该知道自己所需要的适配器类型。例如一个以单层树的形式来提供城市列表的TableViewer,其中表示城市的类为CityClass。CityClass对象应该包含一些有关这个城市的基本信息,并只有在需要的时候才返回详细的信息。在下面的代码中,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 View,这个View显示了在editor中打开的文件的结构。Outline View这个例子展示了通过使用IAdaptable接口和一些特定的事件类型,如何根据其他view的内容来初始化一个view。一个editor必须为打开的文件创建一个Outline page,这个内容Outline page与IContentOutlinePage接口相关。Editor实现IAdaptable接口之后,便可以提供相关的适配器来作为IContentOutlinePage来使用。

另一个IAdaptable的例子是Properties View。Properties View追踪活跃的part并在当前选择对象上调用getAdapter()方法。所需的适配器类型为IPropertySource。Properties View从而可以使用IPropertySource适配器来获取属性信息并显示。

在这些视图关联的例子中,应用程序在发生Selection change或Part Activation通知时通过IAdaptable接口来获取信息。因此,如果selection是IAdaptable的,用户可以通过适配器来获取更多的信息。

属性变化监听器模式

您可以使用“属性变化监听器模式”来解决前面所说的第2、3个问题:一个View如何从一个非UI view中获取信息,以及一个View如何发布在选择事件发生后经过处理后的信息。

您可以创建一个插件来接受注册属性变化监听器的注册,并在需要时通知所注册的插件。应用程序可以创建选择事件并通知监听器,从而使View从非UI View中获取信息。与selection provider不同,property change provider并不需要实现某个特定的接口。你必须自己定义注册的监听器和创建的provider的语义。下面的代码显示了如何在property provider view或插件中添加或删除property change监听器。

//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);

Property provider将使用org.eclipse.jface.util.PropertyChangeEvent 来创建一个可以发布的Event。同时,使用者将维护一个监听器列表,并对property provider提供回调功能。例如,一个每隔一小时从世界气候服务获取城市气象信息的插件,希望将这些气象信息与其他View分享。CityWeatherPlugin 可以暴露一个名为CitiesWeatherXML的服务,需要这些信息的view则将作为Property Change监听器注册到CityWeatherPlugin 中。为了实现这个,监听器必须知道CityWeatherPlugin 中将监听器注册为监听气候信息监听器的方法。CityWeatherPlugin 将负责记录并通知所有注册的监听器,它使用PropertyChangeEvent 对象来给这些监听器提供信息。

class CityPopulationPlugin {ArrayList myListeners;// A public method that allows listener registrationpublic void addPropertyChangeListener(IPropertyChangeListener listener) {if(!myListeners.contains(listener))myListeners.add(listener);}// A public method that allows listener registrationpublic 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 listenersfor (Iterator iter = listeners.iterator(); iter.hasNext();) {IPropertyChangeListener element = (IProperty ChangeListener) iter.next();element.propertyChange(new PropertyChangeEvent(this, "CitiesWeatherXML" , null , CityWeatherXMLObj));            }}
}

Property change监听器必须实现 org.eclipse.jface.util.IPropertyChangeListener接口来使property change provider可以使用回调函数。这个接口有一个方法:public void propertyChange(PropertyChangeEvent event).

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}}
}

这种方法使应用程序可以在任何时刻通知监听器并通过自定义的Event传给他们信息。这些信息并不需要和UI selection有什么关系,可以是经过一些处理后的信息。例如它可以包含后台任务的描述或某个模型中包含的信息。例如,City Selector View可以不仅提供选择的城市信息,而且可以异步地将当前选择的城市气候信息推送到其他注册的View。

总结

本文讨论了几种使View相互关联的方法。如果UI selection不能满足您的需求,那么可以考虑使用IAdaptable接口。属性变化监听器模式则更为灵活,尤其适用于包含非UI场景。

原文地址:http://www.ibm.com/developerworks/opensource/library/os-ecllink/

转载于:https://www.cnblogs.com/jubincn/archive/2012/05/07/3381201.html

Eclipse RCP中Viewer交互的三种方式/Make your Eclipse applications richer with view linking相关推荐

  1. Django中Model继承的三种方式

    Django中Model继承的三种方式 Django中Model的继承有三种: 1.抽象继承 2.多表继承 3.proxy model(代理model) 1.抽象继承 第一种抽象继承,创建一个通用父类 ...

  2. android获取自定义属性,android 自定义控件中获取属性的三种方式(转)

    第一种方法,直接设置属性值,通过attrs.getAttributeResourceValue拿到这个属性值. (1)在xml文件中设置属性值 android:layout_width="f ...

  3. UE4学习-在虚幻编辑器中打开VS的三种方式

    文章目录 方式一 方式二 方式三 在虚幻编辑器中打开VS的三种方式 方式一 在文件浏览器这里,选择C++类,然后在文件夹内,找到一个和截图中类似的图标,双击,即打开vs,并在vs中打开这个类的代码. ...

  4. Java中实现接口的三种方式您造吗?

    本文介绍了Java中实现接口的三种方式:常规实现方式.匿名内部类和 Lambda表达式实现方式.希望已经了解的同学可以重新温习一下,不了解的同学则从中受益! Java中接口最常规的实现方式 同学们都会 ...

  5. java中实现多线程的三种方式

    java中实现多线程的三种方式 1.实现多线程的方法: 在java中实现多线程的两途径:继承Thread类,实现Runable接口(Callable) 2.继承Thread类实现多线程: ​ 继承类T ...

  6. java类初始数组_java中数组初始化的三种方式是什么

    java中数组初始化的三种方式是:1.静态初始化,如[int a[] = {2, 0, 1, 9, 2020}]:2.动态初始化,如[int[] c = new int[4]]:3.默认初始化,如[i ...

  7. 【查看linux中所有用户的三种方式】

    查看linux中所有用户的三种方式学习目标: 提示:通过使用 /etc/passwd 文件,getent 命令,compgen 命令这三种方法查看系统中用户的信息 用户信息存放位置: 提示:Linux ...

  8. java中Map遍历的三种方式

    Java中Map遍历的三种方式 前言 一:在for循环中使用entries实现Map的遍历: 二:在for循环中遍历key或者values,一般适用于只需要map中的key或者value时使用,在性能 ...

  9. JavaScript概述和HTML中嵌入JavaScript的三种方式

    "成功没有捷径,脚踏实地一步一个脚印,该来的总会来,不好高骛远,不急功近利,付出总会有回报,不管处于哪个阶段,都要一步一个脚印,踏实的走好每一步!" 目录 01.JavaScrip ...

  10. c .net ajax,Asp.net mvc 2中使用Ajax的三种方式

    在Asp.net MVC中,我们能非常方便的使用Ajax.这篇文章将介绍三种Ajax使用的方式,分别为原始的Ajax调用.Jquery.Ajax Helper.分别采用这三种方式结合asp.net m ...

最新文章

  1. 文件上传与下载【目前仅仅实现了上传功能】
  2. 让PHP更快的提供文件下载 【转】
  3. 国内程序员最容易发音错误的单词集合
  4. WebLogic11g-常用运维操作
  5. 2018.09.14python学习第四天part2
  6. 【MyBatis笔记】17-多对多做左连接查询(查询老师,并且把关联的学生也查出来)
  7. Spring 3整合Quartz 2实现定时任务:动态添加任务
  8. Yandex安装插件实现百度网盘不需要会员就能倍速播放
  9. 戴尔t620服务器怎么进bios设置u盘启动(戴尔进入u盘启动设置)
  10. 【JZOJ 4598】 准备食物
  11. 微信聊天记录备份:当前网络状况复杂和连接失败的解决办法
  12. 中琅条码软件连续打印设置方法
  13. java 批次号,java重复批次执行
  14. symbian与uiq开发教程
  15. pytorch笔记(四)nn.Conv1d、nn.Conv2d、nn.Conv3d
  16. css定义变量(定义:--aa;使用:var(--aa)、calc()计算样式函数
  17. 机械制造作业考研题目答案分享——加工方法、工序和夹紧
  18. OJB和Hibernate框架的评议一
  19. 零基础怎么学习网站建设? ?
  20. Java 用户评价可信度计算

热门文章

  1. 【进阶】PyTorch自定义CUDA算子教程与运行时间分析
  2. 【GNN】图神经网络综述
  3. 【论文】AAAI 2020论文解读:关注实体以更好地理解文本
  4. 时间序列-BP神经网络及与auo arima的比较
  5. pytorch--nn模块(1)
  6. ThreadPool中变量ctl的分析
  7. 我们为什么需要SDN?
  8. 19【推荐系统5】NeuralCF
  9. PRML笔记:模式识别与机器学习
  10. 海量数据挖掘MMDS week6: 支持向量机Support-Vector Machines,SVM