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

本文介绍了Eclipse中视图间交互的实现机制,重点讨论了如何利用ISelectionProvider和ISelectionListener接口来同步不同视图的选择状态。此外,还探讨了一种改进方案,以避免鼠标右键操作触发不必要的视图更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

有时候一个视图( View )希望得到另外一个视图显示的内容,或者选择的内容。在 Eclipse 中,比较标准的做法是通过 ISelectionProvider ISelectionListener 来完成的。不过因为视图往往是独立的,他们之间并不太方便进行直接的事件监听,而且往往一个视图需要对诸多试图进行选择事件的监听,因此在这种情况下对每一个视图的事件进行注册,比较繁琐,有时候也不可能(比如在需要被监听的试图尚未激活的情况下)。

比较典型的例子就是 Eclipse 本身所提供的 PropertySheetOutline 这两个视图,他们都是对其它试图或者 Editor 中的选择进行监听,并更具选择的内容作相应的处理,显示其 Outline 或者属性页。

Eclipse 为了解决这个问题,提供了所谓的 Site ,以及 ISelectionService 机制,来处理试图之间的简单的交互。简单的说, ViewSite 提供了一个交互的中心点,其它 ViewViewSite 提供选择事件,或者向其注册监听器,而事件的触发与转发则由 ViewSite() 来完成。

这应该也是一个设计模式,不过我还没想到比较接近的设计模式的名字。如果勉强要使用一个的话,我认为“ Mediator ”(调停者模式)可能比较适合(欢迎发表见解)

调停者模式 Blabla...

为了在这个机制中扮演角色,视图通常需要实现两类接口,或者 Adapter 。首先是作为被监听方的视图,需要实现 ISelectionProvider 接口。 ISelectionProviderJface 中引入的接口。

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值