`

Command Framework如何实现EMF Model的编辑

阅读更多
源于《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被更新了。
分享到:
评论

相关推荐

    emf eclipse

    而工具方面,Eclipse提供了一系列工具,如EMF Model Editor、GMF(Graphical Modeling Framework)、GEF(Graphical Edit Framework),这些都可用于构建基于模型的图形用户界面。 文件名列表提到了“EMF & GEF ...

    GMF EMF

    GMF(Generic Modeling Framework)是Eclipse Modeling Framework (EMF)的一个扩展,它提供了一种通用的方法来构建基于模型的应用程序。GMF旨在简化图形用户界面(GUI)的开发,特别是那些涉及图表编辑和可视化任务...

    The Eclipse Graphical Editing Framework (GEF)

    GEF与其他Eclipse组件如EMF(Eclipse Modeling Framework)和GMF(Graphical Modeling Framework)结合使用,可以构建更复杂的模型驱动的图形编辑器。EMF提供模型框架,而GMF则是一个基于图形和模型的代码生成工具...

    The Eclipse Graphical Editing FrameWork

    通常,开发者还会使用EMF(Eclipse Modeling Framework)来定义和操作数据模型,因为EMF提供了对XML Schema和Java类的强大支持,使得数据模型的开发和序列化变得简单。 在GEF插件开发中,还应当遵循一些性能优化的...

    GEF实现拷贝粘贴

    标题“GEF实现拷贝粘贴”涉及到的是在软件开发中使用Graphical Editing Framework(GEF)进行图形界面编辑时,如何实现复制和粘贴功能的技术。GEF是Eclipse平台下用于构建图形化编辑器的框架,它提供了一套完整的...

    eclipse3.4的可视化开发GEF

    1. **定义Model**:创建数据模型,可以是Eclipse的EMF(Eclipse Modeling Framework)或其他ORM框架的对象。 2. **定义Figure**:根据Model设计相应的图形元素。 3. **实现EditParts**:将Figure与Model关联,处理...

    GEF 入门教程

    1. **Model**: GEF的模型层是业务逻辑和图形表示的基础,通常使用EMF(Eclipse Modeling Framework)来定义和实现。 2. **View**: 视图是图形用户界面,它使用EditParts和Figures来显示模型数据。 3. **EditPart**...

    GEF_User_Guide_中文翻译

    8. **命令框架(Command Framework)**:GEF的命令框架确保了编辑操作的可撤销/重做,使得用户可以轻松地撤销错误操作。 9. **布局管理器(Layout Managers)**:布局管理器负责自动调整图形元素的位置和大小,以...

    GEF入门系列

    - **定义模型**:首先需要定义数据模型,通常使用Eclipse的EMF(Eclipse Modeling Framework)来实现。 - **创建EditParts**:为每个模型对象创建相应的EditPart,定义其视图表现和交互行为。 - **实现手势**:...

    eclipse插件开发框架GEF API文档

    GEF具有良好的可扩展性,可以通过实现自定义的EditPolicy、Command和Model来适应不同需求的图形编辑器。此外,它还支持自定义的布局策略和连接线样式,以实现更复杂的图形布局和连接逻辑。 7. **学习资源**: ...

    GEF入门学习例子

    在GEF中,模型通常由`EObject`和`EObjectImpl`实现,可以使用EMF(Eclipse Modeling Framework)来生成。 2. **视图(View)**: 视图是模型的可视化表示,将模型数据呈现给用户。GEF中的视图由`GraphicalViewer`类...

    GEF-runtime-3.5.2

    GEF提供了丰富的API和工具,如Command Framework用于撤销/重做操作,Zest用于图形布局和渲染,以及Diagram Editor Kit用于构建图形编辑器。此外,GEF还与Eclipse的其他组件如EMF(Eclipse Modeling Framework)和GMF...

    GEF入门实例代码2《Eclipse插件开发》中实例

    - **实现编辑策略(Edit Policies)**:根据需求,为EditPart定义编辑策略,比如添加拖拽、连接线绘制等策略。 - **实现命令(Command)**:定义能够修改模型的命令,比如`AddElementCommand`、`RemoveElementCommand`...

    GEF原理的详细介绍+程序实例和程序源码

    **GEF(Graphical Editing Framework)** 是一个用于构建图形化编辑器的开源框架,它在Eclipse平台中被广泛使用。GEF提供了一套全面的API和模型,帮助开发者快速构建可定制的、交互式的图形用户界面。该框架的核心...

    GEF初学者开发样例

    - **模型(Model)**: 模型负责存储图形编辑器的数据,是业务逻辑的载体,通常由Eclipse的EMF( Eclipse Modeling Framework)提供支持。 - **视图(View)**: 视图负责将模型数据渲染到屏幕上,用户通过视图与...

    eclipse插件 GEF-SDK-3.4.0.zip

    - **Command Framework**:提供了一种强大的命令机制,用于实现撤销/重做操作。 - **Zest图表库**:GEF的一部分,用于创建复杂的图表和图形网络,如流程图、关系图等。 5. **插件安装与集成** 将"GEF-SDK-3.4.0....

    Gef 学习总结

    - **命令(Command)**:Gef使用命令模式来实现可撤销/重做的功能,每个编辑操作对应一个命令对象。 2. **Gef的基本架构** - **适配器(Adapter)**:适配器用于将模型与视图之间的数据绑定,确保模型改变时视图...

    GEF资源文件

    1. **定义模型**:首先,你需要定义模型类,这通常是基于Eclipse的EMF(Eclipse Modeling Framework)进行,EMF提供了强大的元模型管理能力。 2. **创建EditParts**:接着,根据模型定义相应的EditPart,实现模型...

    GEF 入门版中文教程 源码

    在GEF中,模型通常由EMF(Eclipse Modeling Framework)来定义和管理,可以将业务逻辑和视图分离。 2. **视图(View)**:视图是模型的可视化表示,它将模型数据呈现为用户界面。GEF提供了基础框架来实现这一转换,...

    java开发工具插件 GEF

    **正文** Java开发工具插件GEF(Graphical Editing Framework)是用于构建图形化用户...在实际开发过程中,通常会结合其他Eclipse插件,如EMF( Eclipse Modeling Framework)用于生成模型类,以进一步提升开发效率。

Global site tag (gtag.js) - Google Analytics