其他分享
首页 > 其他分享> > RCP 视图交互 ISelectionProvider和ISelectionListener,只响应鼠标左键

RCP 视图交互 ISelectionProvider和ISelectionListener,只响应鼠标左键

作者:互联网

原文链接:https://my.oschina.net/zhenghuazhi/blog/199080

 

有时候一个视图( 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() 方法就会被调用。

 

 

 

以上是网上搜索出来的,确实是正确的,但是本人在使用过程中发现,鼠标右键点击也会触发视图的交互,所以我改进了:

 

protected void hookControl(Control control) {

tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){

public void selectionChanged(SelectionChangedEvent event) {

ISelection selection2 = event.getSelection();

setSelection(selection2);

}

});

}

 替换为:

viewer.getTree().addMouseListener(new MouseAdapter() {

			@Override
			public void mouseDown(MouseEvent e) {
				super.mouseDown(e);
				//鼠标右键不执行读取视图表格内容的操作
				if (e.button == 3) {
					return;
				}else
				{
					ISelection selection2 = viewer.getSelection();
					setSelection(selection2);
				}
			}
		});
 

 

转载于:https://my.oschina.net/zhenghuazhi/blog/199080

标签:void,RCP,视图,ISelection,ISelectionListener,ISelectionProvider,public,View
来源: https://blog.csdn.net/chengyu0485/article/details/100708170