来源:http://www.blogjava.net/eclipshine/archive/2005/09/19/13459.html
有时候一个视图(View)希望得到另外一个视图显示的内容,或者选择的内容。在Eclipse中,比较标准的做法是通过ISelectionProvider和ISelectionListener来完成的。不过因为视图往往是独立的,他们之间并不太方便进行直接的事件监听,而且往往一个视图需要对诸多试图进行选择事件的监听,因此在这种情况下对每一个视图的事件进行注册,比较繁琐,有时候也不可能(比如在需要被监听的试图尚未激活的情况下)。
比较典型的例子就是Eclipse本身所提供的PropertySheet和Outline这两个视图,他们都是对其它试图或者Editor中的选择进行监听,并更具选择的内容作相应的处理,显示其Outline或者属性页。
Eclipse为了解决这个问题,提供了所谓的Site,以及ISelectionService机制,来处理试图之间的简单的交互。简单的说,ViewSite提供了一个交互的中心点,其它View向ViewSite提供选择事件,或者向其注册监听器,而事件的触发与转发则由ViewSite()来完成。
这应该也是一个设计模式,不过我还没想到比较接近的设计模式的名字。如果勉强要使用一个的话,我认为“Mediator”(调停者模式)可能比较适合(欢迎发表见解)。
调停者模式Blabla...
为了在这个机制中扮演角色,视图通常需要实现两类接口,或者Adapter。首先是作为被监听方的视图,需要实现
ISelectionProvider接口。ISelectionProvider是Jface中引入的接口。
public interface ISelectionProvider {
public void addSelectionChangedListener(ISelectionChangedListener listener);
public ISelection getSelection();
public void removeSelectionChangedListener(
ISelectionChangedListener listener);
public void setSelection(ISelection selection);
}
方法都比较简单,不做一一阐述。具体实现时,可能需要进行所谓的hookControl,也就是将View中具体控件的事件,关联到这个View所提供的ISelectionProvider上,简单的一个例子,如果View中控件是一个TableViewer的话,那么可以做如下的操作:
protected void hookControl(Control control) {
tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
public void selectionChanged(SelectionChangedEvent event) {
ISelection selection2 = event.getSelection();
setSelection(selection2);
}
});
}
然后再setSelection()中对事件进行扩散(propagate)
public void setSelection(ISelection selection) {
this.selection = selection;
SelectionChangedEvent event2 = new SelectionChangedEvent(
OntIndividualEditor.this, selection);
for (Iterator i = selectionChangeListeners.iterator(); i.hasNext();) {
ISelectionChangedListener object = (ISelectionChangedListener) i
.next();
object.selectionChanged(event2);
}
}
一个ISelectionProvider如果希望被别的View进行监听的话,则应该向其Site()进行注册:
this.getSite().setSelectionProvider(this);
如果事件比较简单,比如上面的例子,只是对TableViewer的选择进行监听,因为TableViewer本身就是一个ISelectionProvider,因此可以直接这样做:
this.getSite().setSelectionProvider(tableViewer);
这样View本身就不必实现ISelectionProvider接口了,但是实现的效果同上面的方式实现的是一样的。
作为事件监听的另一端,则更为简单一些。只需要实现ISelectionListener接口,并注册在Site中:
site.getPage().addSelectionListener(this);
然后实现public void selectionChanged(IWorkbenchPart part, ISelection selection) {}方法即可。这样,当SelectionProvider中的选择发生改变时,这个视图中的selectionChanged()方法就会被调用。
注意SelectionProvider和SelectionListener并不直接对应。这个地方有一点容易混淆,就是Eclipse实际上提供有两套与Selection相关的事件与接口:
ISelectionChangedListener <--> ISelectionProvider
这个是JFace中的选择监听机制,对试图或者控件而言,它提供对原始的选择事件的通知与响应。ISelectionProvider需要注册在Site上,以供ISelectionSerivce使用,将选择事件扩散到其他的ISelectionListener中。
ISelectionListener <--> ISelectionService
这个是在Site中使用的,ISelectionService不需要自己实现,已经实现好了,ISelectionListener则需要注册到ISelectionService上,以对其它SelectionProvider的事件响应进行监听。
在Eclipse本身的实现中,PropertySheet和Outline都使用了这种机制。不过需要注意的是,缺省的PropertyShee需要接受一个IStructuredSelection,而不仅仅是一个ISelection。因此,如果ISeletionProvider需要提供一个能够让PropertySheet进行显示的对象的话,除了除了要实现ISelection接口外,还需要对其进行封装成一个IStructuredSelection。这个比较简单,直接调用StructuredSelection构造函数即可。
分享到:
相关推荐
RCP 产品介绍图片
RCP&OSGI;
RCP在线升级RCP在线升级RCP在线升级RCP在线升级RCP在线升级
Eclipse RCP的扩展点与扩展机制研究,金星善,库少平,RCP (Rich Client Platform) 是基于Eclipse开发平台而推出的一套用来开发富客户端程序的应用框架。Eclipse的插件机制,使得我们可以通过扩展Ecli
RCP导出EXE 老大难问题。 RCp 程序导出步骤,保证能够导出~
Eclipse RCP允许开发者使用eclipse结构风格设计弹性的可扩展的应用程序,可重用Eclipse中已存在的方法和编码模式。俗话说,万事开头难。Eclipse RCP入手可能会比较困难、费时。接下来我们将主要讲述如何让RCP工作. ...
clipse RCP允许开发者使用eclipse结构风格设计弹性的可扩展的应用程序,可重用Eclipse中已存在的方法和编码模式。俗话说,万事开头难。Eclipse RCP入手可能会比较困难、费时。接下来我们将主要讲述如何让RCP工作 ...
有关rcp的内容 是rcp入门的好帮手,rcp自学的好帮手
Eclipse RCP开发教程,RCP入门教程,教你如何使用SWT Eclipse RCP开发教程,RCP入门教程,教你如何使用SWT Eclipse RCP开发教程,RCP入门教程,教你如何使用SWT Eclipse RCP开发教程,RCP入门教程,教你如何使用SWT
RCP 常见的扩展点指南 RCP最精华的部分之一,详细分析了RCP如何建立扩展点的。
RCP项目的登录窗体RCP项目的登录窗体RCP项目的登录窗体RCP项目的登录窗体
Eclipse RCP富客户端平台,基于Eclipse开发的。
RCP系统使用的弹出式日期控件,可切换上月下月,前一年后一年,可选择年、月
1.2.Eclipse RCP 建设风格——插件,扩展和扩展点 1 2.创建你的第一个RCP程序 1 2.1.创建一个RCP程序 2 2.2.启动你的RCP程序 5 2.3.应用程序VS 产品 6 3.应用程序里的插件ID 7 4.Actions的用法(菜单和...
RCP源码例子 RCP源码例子 RCP源码例子
RCP中文入门教程,RCP中文入门教程,RCP中文入门教程,RCP中文入门教程
EclipseRcp 例子程序
rcp for java one
eclipse rcp check table
eclipse rcp 例子 源码