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