<source id="4vppl"><ins id="4vppl"></ins></source>
<u id="4vppl"><sub id="4vppl"><label id="4vppl"></label></sub></u>
<object id="4vppl"></object>
  • <u id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></u>

    <object id="4vppl"></object>
    <b id="4vppl"><sub id="4vppl"><tr id="4vppl"></tr></sub></b>

      <i id="4vppl"><thead id="4vppl"></thead></i>

      <thead id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></thead>

      當前位置:首頁 > 網站舊欄目 > 學習園地 > 設計軟件教程 > Command Framework如何實現EMF Model的編輯

      Command Framework如何實現EMF Model的編輯
      2010-01-14 22:47:19  作者:  來源:
      源于《EMF.Edit Framework Programmgering's Guide》

      EMF.Edit里面有幾個類比較繞,很容易被搞得暈頭轉向,所以需要澄清以下:
      ★AdapterFactoryContentProvider, ItemProviderAdapterFactory和ItemProviderAdapter之間的關系,ItemProviderAdapterFactory用來創建各種Adapter以及將各種notifier跟這些adapter關聯起來,AdapterFactoryContentProvider包裝了一個ItemProviderAdapterFactory(AdapterFactory),它用來將JFace需要的content provider代理到item content provider上,對content provider各種方法的調用將調用到相應的item content provider上,對org.eclipse.jface.viewers.IStructuredContentProvider的調用將代理到IStructuredItemContentProvider上,對ITreeContentProvider的調用將代理到ITreeItemContentProvider上,而對IPropertySourceProvider的調用將代理到IItemPropertySource,而ItemProviderAdapter是所有ItemProvider的基類,AdapterFactoryLabelProvider和ItemProviderAdapter之間也存在類似的關系

      ★為了顯示model內容,我們需要使用content provider和label provider,而編輯model內容則需要使用到editing domain,AdapterFactoryEditingDomain是一個和AdapterFactoryContentProvider、AdapterFactoryLabelProvider類似的東東

      ★editing domain主要有兩個功能:一個是作為command的factory(所以它的實現類是AdapterFactoryEditingDomain);另一個對EMF Model(ResourceSet,因此提供了getResource()方法)進行管理

      ★EditingDomain,AdapterFactoryEditingDomain,EditingDomainItemProvider和Command之間的關系,AdapterFactoryEditingDomain實現了EditingDomain接口,AdapterFactoryEditingDomain和AdapterFactoryContentProvider一樣,也是用來將EditingDomain的方法代理到EditingDomainItemProvider上去。

      從一般的操作說起,比如從一個company對象上刪除一個department對象,通常我們的做法是:
       
      java 代碼
      1. Department d = ...  
      2.   Company c = ...  
      3.   c.getDepartments().remove(d);  

      但是如果是使用command,則會這樣做:
       
      java 代碼
       
      1. Department d = ...  
      2.   Company c = ...  
      3.   EditingDomain ed = ...  
      4.   RemoveCommand cmd =  
      5.     new RemoveCommand(ed, c, CompanyPackage.eINSTANCE.getCompany_Departments(), d);  
      6.   ed.getCommandStack().execute(cmd);  

      不過這個做法有一個問題,就是不是很通用,因為所有的刪除操作基本上都差不多,所以還需要繼續抽象,這時就必須引入EditingDomain.
      EditingDomain的接口定義如下:
      java 代碼
       
      1. public interface EditingDomain  
      2.   {  
      3.     ...  
      4.     Command createCommand(Class commandClass, CommandParameter commandParameter);  
      5.     ...  
      6.   }  

      為了創建一個Command對象,我們需要構造一個CommandParameter對象。在createCommand方法里面會調用指定的Command的靜態create方法來創建指定的Command對象,通過使用create方法,我們可以對上面的操作做進一步的改寫:
      java 代碼
      1. Department d = ...  
      2. EditingDomain ed = ...  
      3. Command cmd = RemoveCommand.create(ed, d);  
      4. ed.getCommandStack().execute(cmd);  

      通過上面的改寫,差不多實現了一個通用的刪除操作流程
      接下來我們可以看看一個command的創建過程,首先是調用指定command的靜態create方法,該方法將調用EditingDomain的createCommand方法,AdapterFactoryEditingDomain作為EditingDomain的實現類,又將command的創建過程代理到EditingDomainItemProvider上,在Itemprovider(實現了EditingDomainItemProvider接口)中,最終使用new創建指定的Command實例
      我們可以采用多種方式對command定制,第一種就是復寫generated的EditingDomainItemProvider實現類的createCommand方法:
      java 代碼
       
      1. public class CompanyItemProvider ...  
      2. {  
      3.   ...  
      4.   
      5.   public Command createCommand(final Object object, ...)  
      6.   {  
      7.     if (commandClass == RemoveCommand.class)  
      8.     {  
      9.       return new RemoveDepartmentCommand(...);  
      10.     }  
      11.     return super.createCommand(...);  
      12.   }  
      13. }  

      這里的RemoveDepartmentCommand 就是我們自己實現的刪除操作。
      第二種方式就是復寫createRemoveCommand()來實現定制:
      java 代碼
       
      1. protected Command createRemoveCommand(...)  
      2.   {  
      3.     return new RemoveDepartmentCommand(...);  
      4.   }  


      通知的處理
      在創建AdapterFactoryContentProvider的時候會將其作為一個listener注冊到AdapterFactory里面,這個AdapterFactory實現了IChangeNotifier接口,而AdapterFactory在創建每一個ItemProvider的時候又會把自己傳遞過去,從而使得AdapterFactory成為model的消息分發中心,在AdapterFactoryContentProvider又會記錄所有需要接受通知的viewer(也就是為其提供了content provider的viewer)。
      當model被改變之后,將觸發和該model相關的adapter的notifyChanged()方法(這里面的adapter就包括itemprovider),當然這里還有一個過濾的過程,只把那些跟viewer相關的notification才會發送給viewer。為了將notification繼續傳遞,會使用ViewerNotification這樣一個對象來對notifation以及其他的信息進行封裝,因此它繼承了Notification,除了Notification相關的信息之外,還封裝了要更新的viewer的相關元素,IViewerNotification 的定義如下:
       
      java 代碼
       
      1. public interface IViewerNotification extends Notification  
      2.   {  
      3.     Object getElement();  
      4.     boolean isContentRefresh();  
      5.     boolean isLabelUpdate();  
      6.   }  

      對于消息的傳遞還會進行分類,這個是在notifyChanged這個方法里面做的,如下面的代碼:
      java 代碼
       
      1. public void notifyChanged(Notification notification)  
      2.   {  
      3.     ...  
      4.     switch (notification.getFeatureID(Company.class))  
      5.     {  
      6.       case CompanyPackage.COMPANY__NAME:  
      7.     //ViewerNotification(Notification decoratedNotification, Object element,
      8. boolean contentRefresh, boolean labelUpdate)  
      9.         fireNotifyChanged(new ViewerNotification(notification, ..., falsetrue));  
      10.         return;  
      11.       case CompanyPackage.COMPANY__DEPARTMENT:  
      12.         fireNotifyChanged(new ViewerNotification(notification, ..., truefalse));  
      13.         return;  
      14.     }  
      15.     super.notifyChanged(notification);  
      16.   }  

      可以看出,如果是attribute,那么會對label進行更新,如果是reference,那么需要更新content了,否則什么都不做。fireNotifyChanged方法是在ItemProviderAdapter(就是所有ItemProvider的基類)里面定義的,它會把notifaction傳給adapter factory,前面我們說過adapter factory是notification的分發器,因此它會將notification發送給所有注冊的listener,我們前面也說過AdapterFactory實現IChangeNotifier接口,并作為listener注冊到adapter factory中去了,因此在最后會調用adapter factory的fireNotifyChanged方法,當然了adapter factory也會將notification代理別的對象(可能是tree或者table的content/label provider,當然在emf中就是itemprovider了)上去,最后viewer被更新了。
       

      安徽新華電腦學校專業職業規劃師為你提供更多幫助【在線咨詢
      国产午夜福三级在线播放_亚洲精品成a人片在线观看_亚洲自慰一区二区三区_久久棈精品久久久久久噜噜
      <source id="4vppl"><ins id="4vppl"></ins></source>
      <u id="4vppl"><sub id="4vppl"><label id="4vppl"></label></sub></u>
      <object id="4vppl"></object>
    1. <u id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></u>

      <object id="4vppl"></object>
      <b id="4vppl"><sub id="4vppl"><tr id="4vppl"></tr></sub></b>

        <i id="4vppl"><thead id="4vppl"></thead></i>

        <thead id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></thead>
        亚洲精品乱码久久久久久 | 亚洲日韩精品专区 | 亚洲中文字幕AV精选 | 在线免费国产精品 | 日本又黄又潮娇喘视频免费 | 一a在线视频插进去了 |