EMF 不僅生成核心模型(介面與實作類),還會產生一個以 .edit 結尾的專案。此專案包含與核心模型及編輯器緊密相關的代碼,設計精良且高度可重用。它不僅被 EMF 生成的編輯器大量使用,開發者在擴充編輯器時也應充分利用。
以線上商店範例為例,com.my.shop.edit 專案包含:
ItemProviderAdapterFactory:負責建立各種 ItemProvider。ItemProviderAdapter 子類別,與核心模型介面一一對應(如 ShopItemProvider、CategoryItemProvider、ProductItemProvider)。注意: 類別名稱省略了 Adapter 字樣,但它們確實實作了 Adapter 介面。EMF 的 Adapter 等同於監聽器角色,監聽 Notifier;而 ItemProviderAdapterFactory 則類似 IAdaptable,負責動態型別轉換。
JFace Viewer(如 TreeViewer、TableViewer)依賴 ContentProvider 決定顯示資料結構,LabelProvider 決定顯示文字與圖示。EMF 的 ItemProvider 實作了 ITreeItemContentProvider 等介面,已內建 getParent()、hasChildren()、getChildren() 等方法。透過 AdapterFactoryContentProvider 適配,即可直接供 JFace Viewer 使用。
對於 TableViewer,需額外實作 ITableItemLabelProvider(參考 ProductItemProvider 範例)。這使得切換 Viewer 時幾乎無需修改代碼。
每個 ItemProvider 的 getPropertyDescriptors() 回傳 ItemPropertyDescriptor 清單,決定屬性視圖顯示的標籤、描述、圖示與可編輯性。EMF 預設將模型所有屬性加入,若要隱藏某屬性,只需移除對應的 addXxxPropertyDescriptor() 呼叫。
ItemProviderAdapter 基類提供多種 createXxxCommand() 方法(如 createSetCommand()、createAddCommand()),將使用者編輯行為轉為 Command 物件,放入 CommandStack 實現撤銷/重做。此機制與 GEF 的 EditPolicy 類似。
ItemProvider 作為 Adapter 監聽模型變更。當模型修改,對應的 notifyChanged() 被呼叫,事件經 ItemProviderAdapterFactory 的 fireNotifyChanged() 廣播給所有註冊的監聽器,確保所有 Viewer 同步更新。
collectNewChildDescriptors() 決定編輯器中「New Child」選單可建立的子元素型別,可透過覆寫此方法客製化選單項目。
.Edit 元件是 EMF 編輯器架構的核心橋樑,掌握 ItemProvider 的運作機制,能大幅簡化編輯器擴充與維護工作。