RCP中的几种选择监听(Selection Provider-Listener)机制

监听在一个特定的Viewer中的进行的选择是RCP开发中经常遇到的情况。例如,在TabelViewer中或TreeViewer中用户选择了一行数据或者一个节点时,需要针对当前的Selection做出某些处理(如更新Text组件中的数据)。

图1. Selection Provider和Listener在同一视图中 

图1. Selection Provider和Listener在同一视图中 

为了方便对此机制的介绍,我们设定一个如图1中所示的场景,当用户在视图左边的TabelViewer中选择一个节点后,在右边的Text Component中将显示出所选择的内容。 

在RCP的开发中,我们可以基于实际情况的不同,采取以下的办法:

     1. 直接调用Viewer的addSelectionChangedListener方法

     2. 使用Selection Provider-Selection Listener机制

 此两种方法,各自有优缺点及适用的范围,以下将分别对其说明。

直接调用Viewer的addSelectionChangedListener方法 

这种方法是最简单明了的,它只需要在Viewer的addSelectionChangedListener方法中实现一个Listener即可。但它只适用于Viewer和Listener在同一个视图中的情况下,如图1所示。也就是说,如果我们的Viewer和Text Component在同一个视图中,可以使用一个Listener监听在同一个视图中发生的Selection变化。

实现的过程如下:

a. 定义并初始化一个Viewer。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> TableViewer viewer  =   new  TableViewer(parent, SWT.MULTI  |  SWT.H_SCROLL  |  SWT.V_SCROLL);

b. 在Viewer的addSelectionChangedListener方法中定义一个Listner。

c. 在Listner中实现对UI Component的数据更新。 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> viewer.addSelectionChangedListener( new  ISelectionChangedListener() {
    @Override
    
public   void  selectionChanged(SelectionChangedEvent event) {
        ISelection selection 
=  event.getSelection();
        
if  (selection  != null  ) {
            String value 
=  (String) ((IStructuredSelection) selection).getFirstElement();;
            
// txtValue是一个UI Component,用于更新当前选择的数据
            txtValue.setText(value);                    
        }
    }
});

使用Selection Provider-Selection Listener机制

这种机制是在实践中最经常用到的,特别是用在Selection发生的视图和Listener所在的视图不相同的情况下(如图2所示)。虽然所在视图不相同,但他们都处于一个相同的WorkbenchPage中。在这种方法中,我们需要首先定义一个Selection的Provider,即谁提供这个Selection Event,本例中当然是Viewer。然后,我们需要生成一个Listener用来处理Selection Event。而Provider和Listener之间的关联,可以通过由当前WorkbenchPage管理的Listener注册器完成。即将我们的Listener注册到这个注册器中,一旦当前WorkbenchPage的SelectionProvider发出SelectionChangedEvent时,所有注册的Listener就可以做出相应的处理。

图2. Selection Provider和Listener在不同的视图中 

图2. Selection Provider和Listener在不同的视图中 

实现的过程如下:

a. 在视图1中定义并初始化一个Viewer。 

TableViewer viewer  =   new  TableViewer(parent, SWT.MULTI  |  SWT.H_SCROLL  |  SWT.V_SCROLL);

b. 在视图1中定义Viewer为SelectionProvider。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> getSite().setSelectionProvider(viewer);

c. 在同一WorkbenchPage中的视图2中定义一个ISelectionListener,为了方便处理视图内的UI Component,通常在视图中实现此接口。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> public   class  DetailsView  extends  ViewPart  implements  ISelectionListener

d. 实现ISelectionListener的方法selectionChanged,用于处理Selection变化。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> @Override
public   void  selectionChanged(IWorkbenchPart part, ISelection selection) {
    
if  (selection  != null  ) {
        String value 
=  (String) ((IStructuredSelection) selection).getFirstElement();;
        
// txtValue是一个UI Component,用于更新当前选择的数据
        txtValue.setText(value);                    
    }
}

e. 将实现了ISelectionListener的Listener(通常就是视图自己)注册到当前WorkbenchPage管理的Listener注册器。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> getSite().getPage().addSelectionListener((ISelectionListener)  this );

 

此方法需要注意的是,在同一个视图中只能定义一个SelectionProvider,但针对此Provider可以在不同的视图中注册多个Listener。相反,一个已注册的Listener可以同时监听,来自不同视图的SelectionProvider发出的SelectionChangedEvent。为了进一步限制监听的对象,可以在注册时指定监听的视图。 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> getSite().getPage().addSelectionListener(SampleView.ID,  (ISelectionListener) this );

这样,SelectionListener只监听来自SampleView的SelectionChangedEvent。

总结

在常规的RCP开发中,处理Selection监听的任务,通过上述的两种方法可以轻松的完成。若Selection的Provider和Listener都在一个视图,且只需要简单处理SelectionChangedEvent时,我们可以选择方法1即可。若Selection的Provider和Listener分散在两个或多个视图时,我们必须通过方法2完成。当然,对于在同一视图的情况,我们也可以通过方法2实现,原理也是一样的。另外,其他较为复杂的Selection Provider-Listener的情况,还可以使用RCP的IAdaptable实现。

你可能感兴趣的:(UI)