RCP 视图交互 ISelectionProvider和ISelectionListener,只响应鼠标左键
作者:互联网
有时候一个视图( 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