最近遇到了RCP的view之间的信息传递的问题,看了一下,觉得这篇介绍的还不错,转一下

引用:http://blog.csdn.net/xueyepiaoling/article/details/6737048

在上一文中,我们介绍了怎样创建一个Eclipse RCP,并创建用户交互的视图,但是并没有提到如何实现视图的交互。在本文中,我们会介绍以两种不同的方式实现Eclipse RCP View之间的交互,并结合代码详细领略一下Eclipse是如何巧妙处理View之间交互的。
首先介绍一下我们要达到的效果,如下图所示:
RCP开发,view事件通知机制
可以看到,用户点击左边视图上的人员列表,该人员的详细信息会显示在右侧的view视图中,这一步骤看起来简单,但是要做的工作却不少,下面我们就着手把前期获得的RCP程序做成这个样子,让View之间传递信息或者更复杂一些的对象。

从Eclipse目前提供的手段看来,我们可以使用下列方法实现视图的交互:
(1)选择提供器 - 选择监听器(selection provider-selection listener)模式,从而让视图对其他视图中的选择做出反应
(2)使用属性改变监听模式,即Property Changed Listener模式,用于视图中没有可供点击的UI模块的情况下。这类监听模式允许视图将属性改变事件

以下将详细介绍这两种模式的概念、适用场景,并结合我们的Hello RCP分别实例说明这两种视图交互模式的实现。
(一)选择提供器-选择监听器(selection provider-selection listener)模式:
这是一种传统的事件传递模式,一般来说,只要视图中的UI控件实现了ISelectionProvider接口,即具备提供选 择事件的能力,就可以使用这个模式将自身发生的选择事件提供给其他实现了ISelectionListener的UI控件。例如我们在Hello RCP中实现的Navigation视图,里面采用了ListViewer这一控件,而Jface中所有的Viewer对象都实现了 ISelectionProvider接口,那么当我们点击navigation视图list列表中的人员名单时,ListViewer列表就可以向其他 能够监听该选择事件的对象提供该选择事件,如果我们在事件中包含一些字符串信息,那么其他对象得到这个信息之后,就可以进行相应显示了。
“Eclipse提供了所谓的Site,以及ISelectionService机制,来处理试图之间的简单的交互。简单的说,ViewSite提供了一个交互的中心点,其它ViewViewSite提供选择事件,或者向其注册监听器,而事件的触发与转发则由ViewSite()来完成。”
以上只是一些概念介绍,对于我们来说,只需按照下列步骤进行,就可以将一个视图变成一个提供Selection 事件的Selection Provider:
(1)首先将视图注册成为Selection Provider,即实现ISelectionProvider接口

RCP开发,view事件通知机制publicclassNavigationViewextendsViewPartimplementsISelectionProvider
以下是ISelectionProvider接口的定义:
1RCP开发,view事件通知机制publicinterfaceISelectionProvider{
2RCP开发,view事件通知机制
3RCP开发,view事件通知机制publicvoidaddSelectionChangedListener(ISelectionChangedListenerlistener);
4RCP开发,view事件通知机制
5RCP开发,view事件通知机制publicISelectiongetSelection();
6RCP开发,view事件通知机制
7RCP开发,view事件通知机制publicvoidremoveSelectionChangedListener(
8RCP开发,view事件通知机制
9RCP开发,view事件通知机制ISelectionChangedListenerlistener);
10RCP开发,view事件通知机制
11RCP开发,view事件通知机制publicvoidsetSelection(ISelectionselection);
12RCP开发,view事件通知机制
13RCP开发,view事件通知机制}

14RCP开发,view事件通知机制
(2)有了以上步骤还不够,还需要将视图中具体的Viewer上想要发生的事件,注册到这个Provider上。
RCP开发,view事件通知机制viewer.addSelectionChangedListener(newISelectionChangedListener(){
RCP开发,view事件通知机制
publicvoidselectionChanged(SelectionChangedEventevent){
RCP开发,view事件通知机制ISelectionselection2
=event.getSelection();
RCP开发,view事件通知机制setSelection(selection2);
RCP开发,view事件通知机制}

RCP开发,view事件通知机制}
);
这段代码就是把ListViewer上的Selection ChangeEvent注册到了Selection Provider上,由后者负责向外传播
(3)一个Selection Provider想要其他部件监听的话,还要向Site中控台进行注册,要不然就相当于开会时找不到话筒讲话,大家听不见
1RCP开发,view事件通知机制this.getSite().setSelectionProvider(this);

注意this对象指的是Viwe视图,它具有指向Site的引用,通过getSite()方法获得引用
(4)最后,还要把讲给听众听,没有听众也是白讲,这里是在setSelection()方法里迭代每一个注册了ISelectionListener的控件,找到它们,把事件传递给这些听众即可:

RCP开发,view事件通知机制publicvoidsetSelection(ISelectionselection){
RCP开发,view事件通知机制
this.selection=selection;
RCP开发,view事件通知机制SelectionChangedEventevent2
=newSelectionChangedEvent(viewer,selection);
RCP开发,view事件通知机制
for(Iteratori=myListeners.iterator();i.hasNext();){
RCP开发,view事件通知机制ISelectionChangedListenerobject
=(ISelectionChangedListener)i.next();
RCP开发,view事件通知机制object.selectionChanged(event2);
RCP开发,view事件通知机制}

RCP开发,view事件通知机制
RCP开发,view事件通知机制}


至此,我们已经实现了一个Selection Provider了,对于事件监听的另一端,即Selection Listener,则更为简单一些。只需要实现ISelectionListener接口,并注册在Site中:

RCP开发,view事件通知机制site.getPage().addSelectionListener(this);

然后实现public void selectionChanged(IWorkbenchPart part, ISelection selection) {}方法即可。这样,当SelectionProvider中的选择发生改变时,这个视图中的selectionChanged()方法就会被调用。

即如下方式:

1RCP开发,view事件通知机制publicvoidselectionChanged(IWorkbenchPartpart,ISelectionselection){
2RCP开发,view事件通知机制IStructuredSelectionstructuredSelection=(IStructuredSelection)selection;
3RCP开发,view事件通知机制Objectobj=structuredSelection.getFirstElement();
4RCP开发,view事件通知机制PersontempPerson=(Person)obj;
5RCP开发,view事件通知机制if(tempPerson!=null)
6RCP开发,view事件通知机制text.setText(tempPerson.getName());
7RCP开发,view事件通知机制text_1.setText(tempPerson.getSex());
8RCP开发,view事件通知机制}


根据以上介绍的Selection Provider-Selection Listener模式,我们重新改造了一下navigation view视图和detail view视图:

1RCP开发,view事件通知机制packagehellorcp;
2RCP开发,view事件通知机制
3RCP开发,view事件通知机制importjava.util.ArrayList;
4RCP开发,view事件通知机制importjava.util.Iterator;
5RCP开发,view事件通知机制
6RCP开发,view事件通知机制importorg.eclipse.jface.action.IToolBarManager;
7RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ISelection;
8RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ISelectionChangedListener;
9RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ISelectionProvider;
10RCP开发,view事件通知机制importorg.eclipse.jface.viewers.IStructuredContentProvider;
11RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ListViewer;
12RCP开发,view事件通知机制importorg.eclipse.jface.viewers.SelectionChangedEvent;
13RCP开发,view事件通知机制importorg.eclipse.swt.SWT;
14RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Composite;
15RCP开发,view事件通知机制importorg.eclipse.ui.part.ViewPart;
16RCP开发,view事件通知机制importhellorcp.NavigationViewLabelProvider;
17RCP开发,view事件通知机制
18RCP开发,view事件通知机制publicclassNavigationViewPartextendsViewPartimplementsISelectionProvider{
19RCP开发,view事件通知机制
20RCP开发,view事件通知机制privateISelectionselection;
21RCP开发,view事件通知机制ArrayListmyListeners=newArrayList();
22RCP开发,view事件通知机制ListViewerlistViewer;
23RCP开发,view事件通知机制
24RCP开发,view事件通知机制publicNavigationViewPart(){
25RCP开发,view事件通知机制//TODOAuto-generatedconstructorstub
26RCP开发,view事件通知机制}

27RCP开发,view事件通知机制
28RCP开发,view事件通知机制@Override
29RCP开发,view事件通知机制publicvoidcreatePartControl(Compositeparent){
30RCP开发,view事件通知机制listViewer=newListViewer(parent,SWT.BORDER);
31RCP开发,view事件通知机制listViewer.setLabelProvider(newNavigationViewLabelProvider());
32RCP开发,view事件通知机制listViewer.setContentProvider(newNavigationListViewContentProvider());
33RCP开发,view事件通知机制listViewer.setInput(newPersonModel());
34RCP开发,view事件通知机制initializeToolBar();
35RCP开发,view事件通知机制listViewer.addSelectionChangedListener(newISelectionChangedListener(){
36RCP开发,view事件通知机制publicvoidselectionChanged(SelectionChangedEventevent){
37RCP开发,view事件通知机制ISelectionselection2=event.getSelection();
38RCP开发,view事件通知机制setSelection(selection2);
39RCP开发,view事件通知机制}

40RCP开发,view事件通知机制}
);
41RCP开发,view事件通知机制this.getSite().setSelectionProvider(this);
42RCP开发,view事件通知机制//TODOAuto-generatedmethodstub
43RCP开发,view事件通知机制
44RCP开发,view事件通知机制}

45RCP开发,view事件通知机制
46RCP开发,view事件通知机制publicISelectiongetSelection(){
47RCP开发,view事件通知机制//TODOAuto-generatedmethodstub
48RCP开发,view事件通知机制returnnull;
49RCP开发,view事件通知机制}

50RCP开发,view事件通知机制
51RCP开发,view事件通知机制publicvoidaddSelectionChangedListener(ISelectionChangedListenerlistener){
52RCP开发,view事件通知机制if(!myListeners.contains(listener))
53RCP开发,view事件通知机制myListeners.add(listener);
54RCP开发,view事件通知机制}

55RCP开发,view事件通知机制
56RCP开发,view事件通知机制publicvoidremoveSelectionChangedListener(ISelectionChangedListenerlistener){
57RCP开发,view事件通知机制myListeners.remove(listener);
58RCP开发,view事件通知机制}

59RCP开发,view事件通知机制
60RCP开发,view事件通知机制@Override
61RCP开发,view事件通知机制publicvoidsetFocus(){
62RCP开发,view事件通知机制//TODOAuto-generatedmethodstub
63RCP开发,view事件通知机制
64RCP开发,view事件通知机制}

65RCP开发,view事件通知机制privatevoidinitializeToolBar(){
66RCP开发,view事件通知机制IToolBarManagertoolBarManager=getViewSite().getActionBars().getToolBarManager();
67RCP开发,view事件通知机制}

68RCP开发,view事件通知机制publicvoidsetSelection(ISelectionselection){
69RCP开发,view事件通知机制this.selection=selection;
70RCP开发,view事件通知机制SelectionChangedEventevent2=newSelectionChangedEvent(listViewer,selection);
71RCP开发,view事件通知机制for(Iteratori=myListeners.iterator();i.hasNext();){
72RCP开发,view事件通知机制ISelectionChangedListenerobject=(ISelectionChangedListener)i.next();
73RCP开发,view事件通知机制object.selectionChanged(event2);
74RCP开发,view事件通知机制}

75RCP开发,view事件通知机制
76RCP开发,view事件通知机制}

77RCP开发,view事件通知机制
78RCP开发,view事件通知机制}

79RCP开发,view事件通知机制

1RCP开发,view事件通知机制packagehellorcp;
2RCP开发,view事件通知机制
3RCP开发,view事件通知机制importjava.util.ArrayList;
4RCP开发,view事件通知机制
5RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ISelection;
6RCP开发,view事件通知机制importorg.eclipse.jface.viewers.IStructuredSelection;
7RCP开发,view事件通知机制importorg.eclipse.jface.viewers.TableViewer;
8RCP开发,view事件通知机制importorg.eclipse.swt.SWT;
9RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Composite;
10RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Group;
11RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Label;
12RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Table;
13RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Text;
14RCP开发,view事件通知机制importorg.eclipse.ui.ISelectionListener;
15RCP开发,view事件通知机制importorg.eclipse.ui.IWorkbenchPart;
16RCP开发,view事件通知机制importorg.eclipse.ui.part.ViewPart;
17RCP开发,view事件通知机制
18RCP开发,view事件通知机制publicclassDetailViewextendsViewPartimplementsISelectionListener{
19RCP开发,view事件通知机制
20RCP开发,view事件通知机制privateTabletable;
21RCP开发,view事件通知机制privateTexttext_1;
22RCP开发,view事件通知机制privateTexttext;
23RCP开发,view事件通知机制@SuppressWarnings("unchecked")
24RCP开发,view事件通知机制ArrayListmyListeners;
25RCP开发,view事件通知机制publicDetailView(){
26RCP开发,view事件通知机制super();
27RCP开发,view事件通知机制//TODOAuto-generatedconstructorstub
28RCP开发,view事件通知机制}

29RCP开发,view事件通知机制
30RCP开发,view事件通知机制@Override
31RCP开发,view事件通知机制publicvoidcreatePartControl(Compositeparent){
32RCP开发,view事件通知机制finalCompositecomposite=newComposite(parent,SWT.NONE);
33RCP开发,view事件通知机制
34RCP开发,view事件通知机制finalGroupgroup=newGroup(composite,SWT.NONE);
35RCP开发,view事件通知机制group.setBounds(0,0,494,62);
36RCP开发,view事件通知机制
37RCP开发,view事件通知机制finalLabellabel=newLabel(group,SWT.NONE);
38RCP开发,view事件通知机制label.setText("姓名");
39RCP开发,view事件通知机制label.setBounds(10,32,24,12);
40RCP开发,view事件通知机制
41RCP开发,view事件通知机制text=newText(group,SWT.BORDER);
42RCP开发,view事件通知机制text.setBounds(40,29,80,15);
43RCP开发,view事件通知机制
44RCP开发,view事件通知机制finalLabellabel_1=newLabel(group,SWT.NONE);
45RCP开发,view事件通知机制label_1.setText("性别");
46RCP开发,view事件通知机制label_1.setBounds(172,32,30,12);
47RCP开发,view事件通知机制
48RCP开发,view事件通知机制text_1=newText(group,SWT.BORDER);
49RCP开发,view事件通知机制text_1.setBounds(208,29,80,15);
50RCP开发,view事件通知机制
51RCP开发,view事件通知机制finalTableViewertableViewer=newTableViewer(composite,SWT.BORDER);
52RCP开发,view事件通知机制table=tableViewer.getTable();
53RCP开发,view事件通知机制table.setLinesVisible(true);
54RCP开发,view事件通知机制table.setHeaderVisible(true);
55RCP开发,view事件通知机制table.setBounds(0,68,494,270);
56RCP开发,view事件通知机制initializeToolBar();
57RCP开发,view事件通知机制this.getSite().getPage().addSelectionListener(this);
58RCP开发,view事件通知机制}

59RCP开发,view事件通知机制
60RCP开发,view事件通知机制@Override
61RCP开发,view事件通知机制publicvoidsetFocus(){
62RCP开发,view事件通知机制//TODOAuto-generatedmethodstub
63RCP开发,view事件通知机制
64RCP开发,view事件通知机制}

65RCP开发,view事件通知机制privatevoidinitializeToolBar(){
66RCP开发,view事件通知机制}

67RCP开发,view事件通知机制
68RCP开发,view事件通知机制publicvoidselectionChanged(IWorkbenchPartpart,ISelectionselection){
69RCP开发,view事件通知机制IStructuredSelectionstructuredSelection=(IStructuredSelection)selection;
70RCP开发,view事件通知机制Objectobj=structuredSelection.getFirstElement();
71RCP开发,view事件通知机制PersontempPerson=(Person)obj;
72RCP开发,view事件通知机制if(tempPerson!=null)
73RCP开发,view事件通知机制text.setText(tempPerson.getName());
74RCP开发,view事件通知机制text_1.setText(tempPerson.getSex());
75RCP开发,view事件通知机制
76RCP开发,view事件通知机制}

77RCP开发,view事件通知机制
78RCP开发,view事件通知机制}

79RCP开发,view事件通知机制


将以上文件重新编译,再运行我们的Hello RCP,可以看到,点击Navigation Views时,已经可以将选择的人员信息传递给detal view了,我们的视图真正动了起来:
RCP开发,view事件通知机制

其实对于本例来说,由于JFace Viewer已经实现了ISelectionProvider 接口,因此还有一种更简便的方法实现上述效果,就是将navigation view中的list viewer直接注册为Selection Provider ,这样就可以省去实现ISelectionProvider接口的代码了:
以下是NavigationViewPart.java的另外一种实现方式:

1RCP开发,view事件通知机制packagehellorcp;
2RCP开发,view事件通知机制
3RCP开发,view事件通知机制importjava.util.ArrayList;
4RCP开发,view事件通知机制importjava.util.Iterator;
5RCP开发,view事件通知机制
6RCP开发,view事件通知机制importorg.eclipse.jface.action.IToolBarManager;
7RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ISelection;
8RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ISelectionChangedListener;
9RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ISelectionProvider;
10RCP开发,view事件通知机制importorg.eclipse.jface.viewers.IStructuredContentProvider;
11RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ListViewer;
12RCP开发,view事件通知机制importorg.eclipse.jface.viewers.SelectionChangedEvent;
13RCP开发,view事件通知机制importorg.eclipse.swt.SWT;
14RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Composite;
15RCP开发,view事件通知机制importorg.eclipse.ui.part.ViewPart;
16RCP开发,view事件通知机制importhellorcp.NavigationViewLabelProvider;
17RCP开发,view事件通知机制
18RCP开发,view事件通知机制publicclassNavigationViewPartextendsViewPart{
19RCP开发,view事件通知机制
20RCP开发,view事件通知机制privateISelectionselection;
21RCP开发,view事件通知机制ArrayListmyListeners=newArrayList();
22RCP开发,view事件通知机制ListViewerlistViewer;
23RCP开发,view事件通知机制
24RCP开发,view事件通知机制publicNavigationViewPart(){
25RCP开发,view事件通知机制//TODOAuto-generatedconstructorstub
26RCP开发,view事件通知机制}

27RCP开发,view事件通知机制
28RCP开发,view事件通知机制@Override
29RCP开发,view事件通知机制publicvoidcreatePartControl(Compositeparent){
30RCP开发,view事件通知机制listViewer=newListViewer(parent,SWT.BORDER);
31RCP开发,view事件通知机制listViewer.setLabelProvider(newNavigationViewLabelProvider());
32RCP开发,view事件通知机制listViewer.setContentProvider(newNavigationListViewContentProvider());
33RCP开发,view事件通知机制listViewer.setInput(newPersonModel());
34RCP开发,view事件通知机制this.getSite().setSelectionProvider(listViewer);
35RCP开发,view事件通知机制//TODOAuto-generatedmethodstub
36RCP开发,view事件通知机制
37RCP开发,view事件通知机制}

38RCP开发,view事件通知机制@Override
39RCP开发,view事件通知机制publicvoidsetFocus(){
40RCP开发,view事件通知机制//TODOAuto-generatedmethodstub
41RCP开发,view事件通知机制
42RCP开发,view事件通知机制}

43RCP开发,view事件通知机制
44RCP开发,view事件通知机制}

45RCP开发,view事件通知机制

对于detail view ,如果将将消费者视图作为监听器注册到特定的视图部分,就不用循环所有的Listener来通知了,这样可以节约更多的系统资源了。

RCP开发,view事件通知机制this.getSite().getPage().addSelectionListener("hellorcp.navigationview",(ISelectionListener)this);

以下是DetailView的另外一种实现:

1RCP开发,view事件通知机制packagehellorcp;
2RCP开发,view事件通知机制
3RCP开发,view事件通知机制importjava.util.ArrayList;
4RCP开发,view事件通知机制
5RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ISelection;
6RCP开发,view事件通知机制importorg.eclipse.jface.viewers.IStructuredSelection;
7RCP开发,view事件通知机制importorg.eclipse.jface.viewers.TableViewer;
8RCP开发,view事件通知机制importorg.eclipse.swt.SWT;
9RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Composite;
10RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Group;
11RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Label;
12RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Table;
13RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Text;
14RCP开发,view事件通知机制importorg.eclipse.ui.ISelectionListener;
15RCP开发,view事件通知机制importorg.eclipse.ui.IWorkbenchPart;
16RCP开发,view事件通知机制importorg.eclipse.ui.part.ViewPart;
17RCP开发,view事件通知机制
18RCP开发,view事件通知机制publicclassDetailViewextendsViewPartimplementsISelectionListener{
19RCP开发,view事件通知机制
20RCP开发,view事件通知机制privateTabletable;
21RCP开发,view事件通知机制privateTexttext_1;
22RCP开发,view事件通知机制privateTexttext;
23RCP开发,view事件通知机制@SuppressWarnings("unchecked")
24RCP开发,view事件通知机制ArrayListmyListeners;
25RCP开发,view事件通知机制publicDetailView(){
26RCP开发,view事件通知机制super();
27RCP开发,view事件通知机制//TODOAuto-generatedconstructorstub
28RCP开发,view事件通知机制}

29RCP开发,view事件通知机制
30RCP开发,view事件通知机制@Override
31RCP开发,view事件通知机制publicvoidcreatePartControl(Compositeparent){
32RCP开发,view事件通知机制finalCompositecomposite=newComposite(parent,SWT.NONE);
33RCP开发,view事件通知机制
34RCP开发,view事件通知机制finalGroupgroup=newGroup(composite,SWT.NONE);
35RCP开发,view事件通知机制group.setBounds(0,0,494,62);
36RCP开发,view事件通知机制
37RCP开发,view事件通知机制finalLabellabel=newLabel(group,SWT.NONE);
38RCP开发,view事件通知机制label.setText("姓名");
39RCP开发,view事件通知机制label.setBounds(10,32,24,12);
40RCP开发,view事件通知机制
41RCP开发,view事件通知机制text=newText(group,SWT.BORDER);
42RCP开发,view事件通知机制text.setBounds(40,29,80,15);
43RCP开发,view事件通知机制
44RCP开发,view事件通知机制finalLabellabel_1=newLabel(group,SWT.NONE);
45RCP开发,view事件通知机制label_1.setText("性别");
46RCP开发,view事件通知机制label_1.setBounds(172,32,30,12);
47RCP开发,view事件通知机制
48RCP开发,view事件通知机制text_1=newText(group,SWT.BORDER);
49RCP开发,view事件通知机制text_1.setBounds(208,29,80,15);
50RCP开发,view事件通知机制
51RCP开发,view事件通知机制finalTableViewertableViewer=newTableViewer(composite,SWT.BORDER);
52RCP开发,view事件通知机制table=tableViewer.getTable();
53RCP开发,view事件通知机制table.setLinesVisible(true);
54RCP开发,view事件通知机制table.setHeaderVisible(true);
55RCP开发,view事件通知机制table.setBounds(0,68,494,270);
56RCP开发,view事件通知机制initializeToolBar();
57RCP开发,view事件通知机制this.getSite().getPage().addSelectionListener("hellorcp.navigationview",(ISelectionListener)this);
58RCP开发,view事件通知机制
59RCP开发,view事件通知机制}

60RCP开发,view事件通知机制
61RCP开发,view事件通知机制@Override
62RCP开发,view事件通知机制publicvoidsetFocus(){
63RCP开发,view事件通知机制//TODOAuto-generatedmethodstub
64RCP开发,view事件通知机制
65RCP开发,view事件通知机制}

66RCP开发,view事件通知机制privatevoidinitializeToolBar(){
67RCP开发,view事件通知机制}

68RCP开发,view事件通知机制
69RCP开发,view事件通知机制publicvoidselectionChanged(IWorkbenchPartpart,ISelectionselection){
70RCP开发,view事件通知机制IStructuredSelectionstructuredSelection=(IStructuredSelection)selection;
71RCP开发,view事件通知机制Objectobj=structuredSelection.getFirstElement();
72RCP开发,view事件通知机制PersontempPerson=(Person)obj;
73RCP开发,view事件通知机制if(tempPerson!=null)
74RCP开发,view事件通知机制text.setText(tempPerson.getName());
75RCP开发,view事件通知机制text_1.setText(tempPerson.getSex());
76RCP开发,view事件通知机制
77RCP开发,view事件通知机制}

78RCP开发,view事件通知机制
79RCP开发,view事件通知机制}

80RCP开发,view事件通知机制

看起来后两种实现是不是比前面的要轻便很多呢?
但是对于我们来讲,视图间以Selection Provider 和Listener模式传递消息还存在很多局限:
1视图可能希望公布其他信息,而不只是公布可视化选择信息。公布的信息可能是根据选择进行某些后期处理的结果。
2 视图可能希望使用来自另一个插件的信息,而这个插件可能根本没有提供视图(使用包含的 JFace 查看器)。在这种情况下,使用基于 UI 选择的链接是不可能的
对于以上问题,通过自动方式进行就很困难了,需要我们手工解决,而为视图注册属性监听器而实现观测其它视图的属性变化是个不错的替代模式。

(二)属性改变监听器模式:
属性改变监听器模式主要通过使用JFace中一个重要的接口org.eclipse.jface.util.IPropertyChangeListener来实现,通过注册该监听器,以及使用IPropertyChangeEvent,可以达到事件传递的目的。
与Selection provider-listener模式不同的是,属性改变监听器可以定义到插件上,由插件本身提供注册列表,如下所示:

1RCP开发,view事件通知机制ArrayListmyListeners=newArrayList();
2RCP开发,view事件通知机制//Apublicmethodthatallowslistenerregistration
3RCP开发,view事件通知机制publicvoidaddPropertyChangeListener(IPropertyChangeListenerlistener){
4RCP开发,view事件通知机制if(!myListeners.contains(listener))
5RCP开发,view事件通知机制myListeners.add(listener);
6RCP开发,view事件通知机制}

7RCP开发,view事件通知机制//Apublicmethodthatallowslistenerregistration
8RCP开发,view事件通知机制publicvoidremovePropertyChangeListener(IPropertyChangeListenerlistener){
9RCP开发,view事件通知机制myListeners.remove(listener);
10RCP开发,view事件通知机制}


当插件想要把产生的事件通知到各个监听器的时候,就对这个注册列表中每个Listener元素进行迭代,逐一通知,这样每个Property Change Event就传播到了各个Listener,由后者进行处理了,这个调用模式如下所示:

1RCP开发,view事件通知机制publicvoidinitAndInvoke(ArrayListlisteners,Objectobj){
2RCP开发,view事件通知机制//PostInvocation,informlisteners
3RCP开发,view事件通知机制for(Iterator<IPropertyChangeListener>iter=myListeners.iterator();iter.hasNext();){
4RCP开发,view事件通知机制IPropertyChangeListenerelement=(IPropertyChangeListener)iter.next();
5RCP开发,view事件通知机制element.propertyChange(newPropertyChangeEvent(this,"HelloRcpEvent",null,obj));
6RCP开发,view事件通知机制
7RCP开发,view事件通知机制}

8RCP开发,view事件通知机制}


总而言之,要想实现这个模式,我们必须自己新定义一个注册并调用Property Change Event的类,我们把它叫做:PersonPlugin.java

那么接下来对于我们的navigation view中的list来说,由于没有采用provider模式,那么就必须自己定义它的SelectionChangeListener了,我们可以在这个ListViewer的添加该Listener中实现我们的目的:

1RCP开发,view事件通知机制packagehellorcp;
2RCP开发,view事件通知机制
3RCP开发,view事件通知机制importjava.util.ArrayList;
4RCP开发,view事件通知机制importjava.util.Iterator;
5RCP开发,view事件通知机制
6RCP开发,view事件通知机制importorg.eclipse.jface.action.IToolBarManager;
7RCP开发,view事件通知机制importorg.eclipse.jface.util.IPropertyChangeListener;
8RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ISelection;
9RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ISelectionChangedListener;
10RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ISelectionProvider;
11RCP开发,view事件通知机制importorg.eclipse.jface.viewers.IStructuredContentProvider;
12RCP开发,view事件通知机制importorg.eclipse.jface.viewers.IStructuredSelection;
13RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ListViewer;
14RCP开发,view事件通知机制importorg.eclipse.jface.viewers.SelectionChangedEvent;
15RCP开发,view事件通知机制importorg.eclipse.swt.SWT;
16RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Composite;
17RCP开发,view事件通知机制importorg.eclipse.ui.part.ViewPart;
18RCP开发,view事件通知机制
19RCP开发,view事件通知机制importhellorcp.Person;
20RCP开发,view事件通知机制importhellorcp.PersonPlugin;
21RCP开发,view事件通知机制importhellorcp.NavigationViewLabelProvider;
22RCP开发,view事件通知机制
23RCP开发,view事件通知机制publicclassNavigationViewPartextendsViewPart{
24RCP开发,view事件通知机制
25RCP开发,view事件通知机制privateISelectionselection;
26RCP开发,view事件通知机制ArrayListmyListeners=newArrayList();
27RCP开发,view事件通知机制ListViewerlistViewer;
28RCP开发,view事件通知机制
29RCP开发,view事件通知机制publicNavigationViewPart(){
30RCP开发,view事件通知机制//TODOAuto-generatedconstructorstub
31RCP开发,view事件通知机制}

32RCP开发,view事件通知机制
33RCP开发,view事件通知机制@Override
34RCP开发,view事件通知机制publicvoidcreatePartControl(Compositeparent){
35RCP开发,view事件通知机制listViewer=newListViewer(parent,SWT.BORDER);
36RCP开发,view事件通知机制listViewer.setLabelProvider(newNavigationViewLabelProvider());
37RCP开发,view事件通知机制listViewer.setContentProvider(newNavigationListViewContentProvider());
38RCP开发,view事件通知机制listViewer.setInput(newPersonModel());
39RCP开发,view事件通知机制//this.getSite().setSelectionProvider(listViewer);
40RCP开发,view事件通知机制listViewer.addSelectionChangedListener(newISelectionChangedListener(){
41RCP开发,view事件通知机制publicvoidselectionChanged(SelectionChangedEventevent){
42RCP开发,view事件通知机制ISelectionselection2=event.getSelection();
43RCP开发,view事件通知机制setSelection(selection2);
44RCP开发,view事件通知机制//PostInvocation,informlisteners
45RCP开发,view事件通知机制IStructuredSelectionstructuredSelection=(IStructuredSelection)selection;
46RCP开发,view事件通知机制Objectobj=structuredSelection.getFirstElement();
47RCP开发,view事件通知机制PersontempPerson=(Person)obj;
48RCP开发,view事件通知机制PersonPlugin.getInstance().initAndInvoke(myListeners,tempPerson);
49RCP开发,view事件通知机制}

50RCP开发,view事件通知机制}
);
51RCP开发,view事件通知机制//TODOAuto-generatedmethodstub
52RCP开发,view事件通知机制
53RCP开发,view事件通知机制}

54RCP开发,view事件通知机制
55RCP开发,view事件通知机制publicISelectiongetSelection(){
56RCP开发,view事件通知机制//TODOAuto-generatedmethodstub
57RCP开发,view事件通知机制returnnull;
58RCP开发,view事件通知机制}

59RCP开发,view事件通知机制
60RCP开发,view事件通知机制//Apublicmethodthatallowslistenerregistration
61RCP开发,view事件通知机制publicvoidaddPropertyChangeListener(IPropertyChangeListenerlistener){
62RCP开发,view事件通知机制if(!myListeners.contains(listener))
63RCP开发,view事件通知机制myListeners.add(listener);
64RCP开发,view事件通知机制}

65RCP开发,view事件通知机制
66RCP开发,view事件通知机制//Apublicmethodthatallowslistenerregistration
67RCP开发,view事件通知机制publicvoidremovePropertyChangeListener(IPropertyChangeListenerlistener){
68RCP开发,view事件通知机制myListeners.remove(listener);
69RCP开发,view事件通知机制}

70RCP开发,view事件通知机制
71RCP开发,view事件通知机制@Override
72RCP开发,view事件通知机制publicvoidsetFocus(){
73RCP开发,view事件通知机制//TODOAuto-generatedmethodstub
74RCP开发,view事件通知机制
75RCP开发,view事件通知机制}

76RCP开发,view事件通知机制publicvoidsetSelection(ISelectionselection){
77RCP开发,view事件通知机制this.selection=selection;
78RCP开发,view事件通知机制}

79RCP开发,view事件通知机制}

80RCP开发,view事件通知机制


注意我们为listviewer添加了Selection Change Listener 方法,并通知到了PersonPlugin。

接着,在detail view中,我们只用实现IPropertyChangeListener即可,以下是detail view的代码:

1RCP开发,view事件通知机制packagehellorcp;
2RCP开发,view事件通知机制
3RCP开发,view事件通知机制importjava.util.ArrayList;
4RCP开发,view事件通知机制
5RCP开发,view事件通知机制importorg.eclipse.jface.util.IPropertyChangeListener;
6RCP开发,view事件通知机制importorg.eclipse.jface.viewers.ISelection;
7RCP开发,view事件通知机制importorg.eclipse.jface.viewers.IStructuredSelection;
8RCP开发,view事件通知机制importorg.eclipse.jface.viewers.TableViewer;
9RCP开发,view事件通知机制importorg.eclipse.swt.SWT;
10RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Composite;
11RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Group;
12RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Label;
13RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Table;
14RCP开发,view事件通知机制importorg.eclipse.swt.widgets.Text;
15RCP开发,view事件通知机制importorg.eclipse.ui.ISelectionListener;
16RCP开发,view事件通知机制importorg.eclipse.ui.IWorkbenchPart;
17RCP开发,view事件通知机制importorg.eclipse.ui.part.ViewPart;
18RCP开发,view事件通知机制
19RCP开发,view事件通知机制importhellorcp.PersonPlugin;
20RCP开发,view事件通知机制
21RCP开发,view事件通知机制importhellorcp.Person;
22RCP开发,view事件通知机制
23RCP开发,view事件通知机制publicclassDetailViewextendsViewPartimplementsIPropertyChangeListener{
24RCP开发,view事件通知机制
25RCP开发,view事件通知机制privateTabletable;
26RCP开发,view事件通知机制privateTexttext_1;
27RCP开发,view事件通知机制privateTexttext;
28RCP开发,view事件通知机制@SuppressWarnings("unchecked")
29RCP开发,view事件通知机制ArrayListmyListeners;
30RCP开发,view事件通知机制publicDetailView(){
31RCP开发,view事件通知机制super();
32RCP开发,view事件通知机制//TODOAuto-generatedconstructorstub
33RCP开发,view事件通知机制}

34RCP开发,view事件通知机制
35RCP开发,view事件通知机制@Override
36RCP开发,view事件通知机制publicvoidcreatePartControl(Compositeparent){
37RCP开发,view事件通知机制finalCompositecomposite=newComposite(parent,SWT.NONE);
38RCP开发,view事件通知机制
39RCP开发,view事件通知机制finalGroupgroup=newGroup(composite,SWT.NONE);
40RCP开发,view事件通知机制group.setBounds(0,0,494,62);
41RCP开发,view事件通知机制
42RCP开发,view事件通知机制finalLabellabel=newLabel(group,SWT.NONE);
43RCP开发,view事件通知机制label.setText("姓名");
44RCP开发,view事件通知机制label.setBounds(10,32,24,12);
45RCP开发,view事件通知机制
46RCP开发,view事件通知机制text=newText(group,SWT.BORDER);
47RCP开发,view事件通知机制text.setBounds(40,29,80,15);
48RCP开发,view事件通知机制
49RCP开发,view事件通知机制finalLabellabel_1=newLabel(group,SWT.NONE);
50RCP开发,view事件通知机制label_1.setText("性别");
51RCP开发,view事件通知机制label_1.setBounds(172,32,30,12);
52RCP开发,view事件通知机制
53RCP开发,view事件通知机制text_1=newText(group,SWT.BORDER);
54RCP开发,view事件通知机制text_1.setBounds(208,29,80,15);
55RCP开发,view事件通知机制
56RCP开发,view事件通知机制finalTableViewertableViewer=newTableViewer(composite,SWT.BORDER);
57RCP开发,view事件通知机制table=tableViewer.getTable();
58RCP开发,view事件通知机制table.setLinesVisible(true);
59RCP开发,view事件通知机制table.setHeaderVisible(true);
60RCP开发,view事件通知机制table.setBounds(0,68,494,270);
61RCP开发,view事件通知机制initializeToolBar();
62RCP开发,view事件通知机制//注册事件
63RCP开发,view事件通知机制PersonPlugin.getInstance().addPropertyChangeListener(this);
64RCP开发,view事件通知机制
65RCP开发,view事件通知机制}

66RCP开发,view事件通知机制
67RCP开发,view事件通知机制@Override
68RCP开发,view事件通知机制publicvoidsetFocus(){
69RCP开发,view事件通知机制//TODOAuto-generatedmethodstub
70RCP开发,view事件通知机制
71RCP开发,view事件通知机制}

72RCP开发,view事件通知机制privatevoidinitializeToolBar(){
73RCP开发,view事件通知机制}

74RCP开发,view事件通知机制
75RCP开发,view事件通知机制//publicvoidselectionChanged(IWorkbenchPartpart,ISelectionselection){
76RCP开发,view事件通知机制//IStructuredSelectionstructuredSelection=(IStructuredSelection)selection;
77RCP开发,view事件通知机制//Objectobj=structuredSelection.getFirstElement();
78RCP开发,view事件通知机制//PersontempPerson=(Person)obj;
79RCP开发,view事件通知机制//if(tempPerson!=null)
80RCP开发,view事件通知机制//text.setText(tempPerson.getName());
81RCP开发,view事件通知机制//text_1.setText(tempPerson.getSex());
82RCP开发,view事件通知机制//
83RCP开发,view事件通知机制//}
84RCP开发,view事件通知机制publicvoidpropertyChange(org.eclipse.jface.util.PropertyChangeEventevent){
85RCP开发,view事件通知机制if(event.getProperty().equals("HelloRcpEvent")){
86RCP开发,view事件通知机制Objectval=event.getNewValue();
87RCP开发,view事件通知机制PersontempPerson=(Person)val;
88RCP开发,view事件通知机制if(tempPerson!=null){
89RCP开发,view事件通知机制text.setText(tempPerson.getName());
90RCP开发,view事件通知机制text_1.setText(tempPerson.getSex());
91RCP开发,view事件通知机制}

92RCP开发,view事件通知机制}

93RCP开发,view事件通知机制
94RCP开发,view事件通知机制}

95RCP开发,view事件通知机制
96RCP开发,view事件通知机制}

97RCP开发,view事件通知机制

采用属性改变监听模式能够更加灵活地在插件之间、插件的各个view之间传递信息,突破了传递信息必须与UI相关的局限,而且还可以异步传递信息,这些信 息可以是插件后台JOB定期运行获得的信息,以及定期从数据库中获得的信息等等。不难看到,属性改变监听器扩展了插件之间,视图之间,前台与后台之间的消 息传递场景,是我们开发Eclipse RCP应用更好的选择。


相关文章:

  • 2021-05-30
  • 2021-04-03
  • 2022-03-09
  • 2022-02-05
  • 2021-08-20
  • 2021-11-27
  • 2022-03-05
  • 2021-12-19
猜你喜欢
  • 2021-04-18
  • 2022-01-11
  • 2021-04-14
  • 2021-09-08
  • 2022-12-23
相关资源
相似解决方案