EMF.Edit編程學(xué)習(xí)筆記之一: Item Provider機(jī)制
(注:大部分翻譯,整理自Eclipse Modeling Framework: A Developer's Guide一書的第3.1, 3.2節(jié)的內(nèi)容)
Porvider的概念
對于JFace部分的內(nèi)容已經(jīng)比較清楚,這里重點(diǎn)看一下Eclipse中PropertySheet是如何實(shí)現(xiàn)的。這涉及到了三個接口,IPropertySourceProvider,IPropertySource,IPropertyDescriptor。而模型對象如果要能夠與PropertySheet進(jìn)行交互,則必須實(shí)現(xiàn)IPropertySource接口。Eclipse能夠自動的通過IPropertySourceProvider(當(dāng)然也不是自動,用到了Eclipse中的Adapter技術(shù)),取得這個實(shí)現(xiàn)了IPropertySource的模型對象,并讓PropertySheet對其進(jìn)行調(diào)用。IPropertySource的getPropertyDescriptors()方法取得所有的屬性描述對象,屬性描述對象定義了一個顯示在PropertySheet中的屬性的名稱等一些相關(guān)的性質(zhì)。IPropertySource中的其它方法,提供了對屬性值的顯示與修改的方法。
圖摘自(Eclipse Modeling Framework: A Developer's Guide)
因此可以看到,要實(shí)現(xiàn)一個Tree Viewer,則必須有一個實(shí)現(xiàn)了ITreeContentProvider 接口的對象為其提供內(nèi)容,有一個ILabelProvider接口對象為其提供顯示的標(biāo)簽和圖標(biāo)。對于PropertySheet也是如此,必須有一些實(shí)現(xiàn)了IPropertyDescriptors()接口的對象來提供被編輯的屬性描述。EMF.Edit要做的就是這樣的一個工作:它為EMF模型對象,為這些不同的Viewer生成Provider,使得EMF模型對象能夠通過那些Viewer進(jìn)行顯示與編輯。EMF.Edit能夠通過兩種方式來完成這樣的工作,反射機(jī)制,以及代碼生成的機(jī)制。并且EMF.Edit允許方便的更改所生成的代碼,使得其能夠滿足特定的要求。
EMF.Edit中對EMF模型對象的改變,都是通過一種通用的機(jī)制:Command來實(shí)現(xiàn)的。EMF.Edit提供了對一些常見的Command的實(shí)現(xiàn),并可支持自定義的Command。從上面的討論可以大概的了解到,EMF.Edit提供的是在Eclipse的界面(JFace, PropertySheet, etc)同EMF模型對象之間的一個橋梁,使得能夠通過Eclipse UI來顯示和修改EMF所定義的模型對象。EMF.Edit分為兩個部分:
1. org.eclipse.emf.edit: 提供的是底層的與界面無關(guān)的部分。
2. org.eclipse.emf.edit.ui: 提供的是與Eclipse UI相關(guān)的實(shí)現(xiàn)類。
在EMF.Edit中最重要的概念是Item Provider。EMF.Edit使用一種代理機(jī)制,使得大部分與模型對象相關(guān)的功能都最終被代理到相關(guān)的Item Provider上了。因此Item Provider需要完成下面這4種主要的功能:
1. 實(shí)現(xiàn)content 和label provider 的功能。
2. 為EMF objects提供PropertySource的功能。
3. 作為Command Factory為模型對象創(chuàng)建相關(guān)的Command。
4. 將EMF模型改變通知到Viewers。
特定的Item Provider通常通過繼承ItemProviderAdapter類來完成全部或者部分的上述功能。Item Provider可以通過代碼生成機(jī)制被生成后然后進(jìn)行適當(dāng)?shù)男薷囊詽M足要求;另一方面,EMF.Edit也提供了ReflectiveItemProvider,通過EObject的反射機(jī)制實(shí)現(xiàn)了上述所有的功能。
下面看上述的功能是如何在EMF.Edit中被實(shí)現(xiàn)的。
實(shí)現(xiàn)content 和label provider 的功能
EMF.Edit提供了通用的AdapterFactoryContentProvider和AdapterFactoryLabelProvider實(shí)現(xiàn)。也就是說對于一個TableViewer而言,它使用AdapterFactoryContentProvider和AdapterFactoryLabelProvider作為其ContentProvider和LabelProvider。AdapterFactoryContentProvider等再將請求轉(zhuǎn)發(fā)到具體的Item Provider上。轉(zhuǎn)發(fā)的過程如下所示,在AdapterFactoryContentProvider中實(shí)現(xiàn)的ContentProvider所定義的getChildren()方法:
public Object[] getChildren(Object object) {
ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory
.adapt(object, ITreeItemContentProvider.class);
return adapter.getChildren(object).toArray();
}
AdapterFactoryContentnProvide通過其adapterFactory,將模型對象object適配到ITreeItemContentProvider上(注意ITreeContentProvider和ITreeItemContentProvider名稱上的區(qū)別),然后調(diào)用相應(yīng)的方法。這里用到的adapter的模式,在Eclipse和EMF中使用的非常廣泛。
圖摘自(Eclipse Modeling Framework: A Developer's Guide)
ITreeContentProvider和ITreeItemContentProvider雖然名稱上有區(qū)別,但其實(shí)際上功能是類似的,EMF中之所以引入ITreeItemContentProvider,是為了避免對JFace這樣的UI包的依賴,使得其能夠用到其它的非UI或者非JFace的環(huán)境中。這樣的接口有:
l ITreeItemContentProvider
l IStructuredItemContentProvider
l ITableItemLabelProvider
l IItemLabelProvider
分別對應(yīng)于JFace中去掉了Item后的接口。
為EMF objects提供PropertySource的功能
AdapterFactoryContentProvider實(shí)際上也實(shí)現(xiàn)了IPropertySourceProvider接口,使用如上所述的相同的方式,將模型對象適配到一個IItemPropertySource接口上,對應(yīng)于IPropertySource。另外的一個EMF類PropertySource通過封裝IItemPropertySource實(shí)現(xiàn)了PropertySheet所需要的的IPropertySource接口,并被AdapterFactoryContentProvider所返回。同樣的模式被使用到生成IPropertyDescriptor的EMF實(shí)現(xiàn)PropertyDescriptor上。下面的這個圖可以比較清楚的看到這樣的關(guān)系。
圖摘自(Eclipse Modeling Framework: A Developer's Guide)
作為Command Factory為模型對象創(chuàng)建相關(guān)的Command
EMF有其自生的Command框架。在這個框架中,EditingDomain是一個類是于JFace中的Provider的接口,提供對Command的創(chuàng)建。并且,EMF.Edit也有一個實(shí)現(xiàn)了這個接口的AdapterFactoryEditingDomain,并將請求轉(zhuǎn)發(fā)到被適配的IEditingDomainItemProvider對象上。
將EMF模型改變通知到Viewers
Item Provider作為標(biāo)準(zhǔn)的EMF Adapter,當(dāng)被適配的模型對象發(fā)生改變的時候Item Provider的notifyChanged()會被調(diào)用。實(shí)際上,ItemProvider的notifyChange()只是將請求(經(jīng)過過濾后)轉(zhuǎn)給相應(yīng)的ItemProviderAdapterFacotry,使得其作為模型事件注冊及響應(yīng)的中心。如下圖所示:
圖摘自(Eclipse Modeling Framework: A Developer's Guide)
需要注意的是,在這樣情景下,作為內(nèi)容顯示部分的Viewer并不是事件監(jiān)聽者,相應(yīng)的Provider對象才是,它監(jiān)聽事件,并調(diào)用Viewer的update()方法以刷新顯示的內(nèi)容。
posted on 2005-07-29 17:21 Living Not Striving 閱讀(2610) 評論(1) 編輯 收藏 所屬分類: EMF