RCP中視圖間的交互機(jī)制探討
有時候一個視圖(View)希望得到另外一個視圖顯示的內(nèi)容,或者選擇的內(nèi)容。在Eclipse中,比較標(biāo)準(zhǔn)的做法是通過ISelectionProvider和ISelectionListener來完成的。不過因?yàn)橐晥D往往是獨(dú)立的,他們之間并不太方便進(jìn)行直接的事件監(jiān)聽,而且往往一個視圖需要對諸多試圖進(jìn)行選擇事件的監(jiān)聽,因此在這種情況下對每一個視圖的事件進(jìn)行注冊,比較繁瑣,有時候也不可能(比如在需要被監(jiān)聽的試圖尚未激活的情況下)。
比較典型的例子就是Eclipse本身所提供的PropertySheet和Outline這兩個視圖,他們都是對其它試圖或者Editor中的選擇進(jìn)行監(jiān)聽,并更具選擇的內(nèi)容作相應(yīng)的處理,顯示其Outline或者屬性頁。
這應(yīng)該也是一個設(shè)計模式,不過我還沒想到比較接近的設(shè)計模式的名字。如果勉強(qiáng)要使用一個的話,我認(rèn)為“Mediator”(調(diào)停者模式)可能比較適合(歡迎發(fā)表見解)。
調(diào)停者模式Blabla...
public interface ISelectionProvider {
public void addSelectionChangedListener(ISelectionChangedListener
listener);
public ISelection getSelection();
public void removeSelectionChangedListener(
ISelectionChangedListener
listener);
public void setSelection(ISelection selection);
}
方法都比較簡單,不做一一闡述。具體實(shí)現(xiàn)時,可能需要進(jìn)行所謂的hookControl,也就是將View中具體控件的事件,關(guān)聯(lián)到這個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()中對事件進(jìn)行擴(kuò)散(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進(jìn)行監(jiān)聽的話,則應(yīng)該向其Site()進(jìn)行注冊:
this.getSite().setSelectionProvider(this);
如果事件比較簡單,比如上面的例子,只是對TableViewer的選擇進(jìn)行監(jiān)聽,因?yàn)?/span>TableViewer本身就是一個ISelectionProvider,因此可以直接這樣做:
this.getSite().setSelectionProvider(tableViewer);
這樣View本身就不必實(shí)現(xiàn)ISelectionProvider接口了,但是實(shí)現(xiàn)的效果同上面的方式實(shí)現(xiàn)的是一樣的。
site.getPage().addSelectionListener(this);
然后實(shí)現(xiàn)public
void selectionChanged(IWorkbenchPart part, ISelection selection)
ISelectionChangedListener <--> ISelectionProvider
這個是JFace中的選擇監(jiān)聽機(jī)制,對試圖或者控件而言,它提供對原始的選擇事件的通知與響應(yīng)。ISelectionProvider需要注冊在Site上,以供ISelectionSerivce使用,將選擇事件擴(kuò)散到其他的ISelectionListener中。
ISelectionListener <--> ISelectionService
這個是在Site中使用的,ISelectionService不需要自己實(shí)現(xiàn),已經(jīng)實(shí)現(xiàn)好了,ISelectionListener則需要注冊到ISelectionService上,以對其它SelectionProvider的事件響應(yīng)進(jìn)行監(jiān)聽。
posted on 2005-09-19 22:42 Living Not Striving 閱讀(5090) 評論(6) 編輯 收藏 所屬分類: RCP 、ECLIPSE