`

[zt]EMF介绍系列(六、自定义命令)

阅读更多

FROM:http://www.cnblogs.com/bjzhanghao/archive/2005/12/31/309182.html

EMF生成的应用程序里,用户的发出的每一条命令都是可以撤销(Undo)的,例如修改了产品的价格,按一下撤销按钮就能恢复原来的价格,当然还可以通过重做(Redo)再回到新的价格。为了实现这个功能,应用程序里维护了一个用于存放命令的类似栈的数据结构(CommandStack),每一条执行过的命令都被存放在那里,需要撤销时取出最近一条命令进行撤销。这个数据结构是由EditingDomain对象负责维护的, EditingDomain相当于编辑模型时的环境。

在EMF里命令框架实际上可以分为两大部分,一部分是与模型无关的通用命令,另一部分是.Edit命令,后者是建立在前者的基础之上的。EMF对模型的任何修改都是通过命令完成的,例如当用户在属性视图里修改一个对象的属性时,会生成一个新的SetCommand实例,然后执行它的execute ()方法,这个方法里对模型进行修改(实际上是通过doExecute()方法),成功执行完成后这个命令被放入命令栈以便撤销时使用。

通用命令可以完全脱离EMF使用,也就是说,这个命令框架可以应用到任何需要命令框架的应用程序中,包括非EMF应用程序。它位于 org.eclipse.emf.common.command包里,其中Command接口定义了什么是“命令“,一个命令具有execute()、 undo()和redo()等方法,还有canExecute()和canUndo()方法用于判断命令是否可被执行或撤销(考虑到资源消耗,有些命令可能设计为不可撤销更合理)。另一个重要的接口是前面提到过的CommandStack,它的作用是保存所有命令,可以通过 addCommandStackListener()方法注册监听器来观察CommandStack的状态变化。CompoundCommand接口可以把多个命令按顺序包装成一个组合命令,它具有原子性,类似数据库里事务(Transaction)的概念,只有所有命令都可执行时这个组合命令才可执行,撤销也是如此。

EMF在.Edit框架提供了针对EMF模型编辑所需要的一些命令(位于org.eclipse.emf.edit.command包),例如 SetCommand用于修改对象的属性,CreateChildCommand的作用是创建一个子元素,还有MoveCommand、 CopyCommand和CutToClipboardCommand等等。这些命令都实现Command接口,并且大部分继承自 AbstractOverrideableCommand这个抽象类,它给我们带来的影响是在Command接口里的方法名前面都加了一个do,比如 execute()变为doExecute()、canUndo()变为doCanUndo()等等,我们在扩展这些.Edit命令时要覆盖doXXX方法。.Edit命令是通过反射的方式来修改模型的。

EMF提供的这些命令为我们完成基本的模型编辑功能,多数情况下直接使用它们就可以了,但有时通过自定义的命令可以实现一些特别的需求。举个例子来说,在网上商店的例子里,假设要求产品的价格只精确到小数点后两位,那么我们要在用户输入新价格以后立刻对这个数值进行四舍五入处理,这个操作就可以利用自定义命令完成。因为利用了.Edit提供的类,所以一般我们应该扩展.Edit命令,具体来说就是SetCommand。

首先通过继承SetCommand创建我们的SetPriceCommand,在这个方法里覆盖doExecute()方法,SetCommand 里有很多可供利用的环境变量,我们要用到的是owner和value这两项,前者是要修改的对象,在这里是产品对象,后者是属性的新值,在这里也就是新价格。所以我们的SetPriceCommand可以像下面这样写(为了使代码最简,我们直接把EObject类型转换为Product类型,这样就不需要用反射的方式了):

java 代码
  1. public class SetPriceCommand extends SetCommand {   
  2.     public SetPriceCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Object value) {   
  3.         super(domain, owner, feature, value);   
  4.     }   
  5.     public void doExecute() {   
  6.         Product product = (Product) owner;   
  7.         double newPrice = ((Double) value).doubleValue();   
  8.         newPrice = Math.max(0, newPrice);//New price value must >= 0   
  9.         newPrice=Math.round(newPrice*100)/100d;//Max fraction digits is 2       
  10.         product.setPrice(newPrice);   
  11.     }   
  12. }   

要让这个自定义命令生效,必须在ProductItemProvider里覆盖createSetCommand()方法,因为这个方法缺省是返回SetCommand的,我们要在这里做一个判断:如果修改的是价格属性,就返回我们自定义的这个命令,如下所示:

java 代码
  1. protected Command createSetCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Object value,   
  2.         int index) {   
  3.     if (feature == ShopPackage.eINSTANCE.getProduct_Price())   
  4.         return new SetPriceCommand(domain, owner, feature, value);   
  5.     return super.createSetCommand(domain, owner, feature, value, index);   
  6. }   

这样当用户在属性页里改价格属性时,就会调用我们的SetPriceCommand了。顺便说一句,在GEF里也有类似的EditDomain和Command,只是GEF里的Command一般通过EditPolicy的createXXXCommand()方法来创建。因为GEF和EMF的两套Command机制没有实现统一的接口,所以结合GEF和EMF的时候常会遇到一些问题,需要额外的代码帮助解决,请参考这两处讨论(讨论1,讨论2)。

最后要说一句,CreateChildCommand有点特殊,它是.Edit命令但不继承 AbstractOverrideableCommand,而且如果想在创建子元素时自动完成一些工作,不应该通过扩展这个类完成,而应该在 XXXItemProvider的collectNewChildDescriptors()方法里处理,这个方法决定每个对象可以创建哪些子元素,你可以修改它的代码以对新建的元素做一些处理。

参考资料: Eclipse Modeling Framework A Developers Guide,第3.3节、第14.1节。

点击下载源代码

分享到:
评论

相关推荐

    微软emf文件格式详解

    EMF文件本质上是由一系列命令组成的指令集,这些命令用于描述构成图像的各种元素,如线条、形状、颜色填充等。每个命令都包含了执行特定图形操作所需的参数。EMF文件格式的内部结构非常复杂,包括多个层次的数据结构...

    EMF_GEF_入门系列

    4. **GEF基础**:介绍GEF的基本组件,如图层、图形、连接器和模型视图,以及如何配置和扩展GEF来创建自定义编辑器。 5. **图形编辑**:深入探讨如何使用GEF创建图形元素,实现图形的绘制、选中、移动等操作,以及...

    emf文件格式详解

    2. **多记录结构**:EMF文件由一系列记录组成,每个记录代表一个图形操作,如画线、填充区域或设置颜色。 3. **设备独立性**:EMF格式不依赖于特定的显示器或打印机,因此可以在不同设备间保持一致性。 4. **颜色和...

    emf 转 BMP格式 lib

    本文将详细介绍如何使用"EMF转BMP库"进行格式转换,以及涉及到的关键技术点。 首先,我们需要理解EMF文件结构。EMF包含了图形设备接口(GDI)调用的序列,这些调用描述了如何绘制图像。在转换过程中,我们需要解析...

    EMF读取XML

    下面将详细介绍EMF读取XML的相关知识点。 1. **EMF模型与XML的关系** - EMF模型是面向对象的,它定义了数据结构和业务规则,可以看作是XML数据的抽象表示。 - XML是一种标记语言,用于存储和传输结构化数据,它与...

    emf转bmp代码

    EMF包含一系列图形命令,而BMP则是一个二维像素阵列,包含颜色信息。 2. **读取EMF文件**:使用Windows API函数,如`PlayMetaFile()`,可以读取并执行EMF文件中的图形指令。这会生成一个设备上下文(Device Context...

    SVG转EMF的示例代码

    在实际应用中,你可能需要处理更多的细节,比如错误处理、SVG文件的编码问题、用户自定义的转换选项等。此外,此转换过程可能会消耗一定资源,因此在处理大量文件时需要注意性能优化。 这个示例代码对于理解SVG和...

    Eclipse Modeling Framework (EMF) Developer Guide

    **EMF Edit Framework Programmer's Guide** 重点介绍了如何使用 EMF 创建用户界面,以便编辑和查看 EMF 模型。 - **创建编辑器**: EMF 提供了一种机制来自动生成编辑器,这些编辑器可以用来查看和修改 EMF 模型中...

    EMF文件提取文本,预览,打印

    这通常通过打印机驱动程序完成,该驱动程序理解EMF格式并将其转换为适合特定打印机的命令。 4. **转换为图像**:有时候,将EMF文件转换为位图格式(如JPEG、PNG或BMP)可能是必要的,例如为了在网络上分享或在不...

    将EMF图片格式转换成PNG

    EMF (Enhanced Metafile) 是Windows操作系统中用于存储矢量图形和光栅图像的文件格式,它在处理复杂的图形和图像是非常有效。而PNG(Portable Network Graphics)则是一种无损压缩的位图格式,广泛应用于网页设计、...

    C# 将打印机临时缓存文件SPL转为图片文件EMF

    在C#中,由于.NET Framework并未提供直接将SPL转换为EMF的内置功能,我们需要依赖第三方库或自定义代码来实现这一转换。SnailDev.EmfParser-master这个压缩包可能包含了一个名为`SnailDev.EmfParser`的库,这个库...

    EMF 自学笔记5

    #### 六、EMF在实际项目中的应用 EMF在各种领域都有广泛的应用,特别是在复杂系统的建模和设计中。例如,在企业架构设计中,EMF可以用于定义业务流程模型、数据模型、组件模型等;在软件开发中,EMF可以用于定义...

    EMF模型文件对比/比较(emf.compare)

    - 如何通过API扩展EMF.compare的功能,例如自定义比较策略。 - 在实际项目中,如何结合GWT、Guava和其他库来实现特定的需求。 然而,由于没有具体的博客内容,以上只是基于给定信息的推测。要获取更详细的信息,你...

    EMF开发过程整合资料

    - **EMF入门教程**:介绍如何安装EMF,创建第一个元模型,生成相应的Java类,以及如何使用生成的代码进行操作。 - **EMF编辑器创建**:讲解如何使用EMF创建自定义的图形化或文本编辑器,以提高用户体验。 - **模型...

    emf-runtime-2.7.2

    这个列表可能包含了一系列用于安装或更新EMF Runtime 2.7.2到Eclipse环境中的文件,如JAR包、配置文件等,这些文件将被Eclipse识别并集成到其插件系统中,以提供对EMF功能的支持。 EMF的主要特点和应用包括: 1. **...

    emf-xsd-SDK-2.6.1

    GEF是一个可扩展的框架,用于开发各种图形编辑器,它允许开发者创建自定义的绘图工具,以图形化方式表示和编辑EMF模型。 Visual Editor是基于EMF和GEF构建的,专门用于创建可视化的模型编辑器。它提供了一系列预...

    eclipse插件开发EMF api 文档

    9. **扩展和定制**:EMF允许开发者通过继承和实现接口来扩展其功能,如自定义类型系统、解析器和序列化策略等。 10. **与其他Eclipse组件集成**:EMF与Eclipse的其他组件如PDE(Plug-in Development Environment)...

    深入理解EMF&graphiti

    EMF(Eclipse Modeling Framework)和Graphiti是两个在Eclipse平台上用于建模和图形化表示的重要工具。本文将深入探讨这两个技术,并结合提供的压缩包文件"emf",为读者提供一个详尽的理解。 首先,EMF是Eclipse...

    emf教程入门和插件

    EMF(Eclipse Modeling Framework)是Eclipse基金会推出的一个开源框架,主要用于构建基于模型的软件系统。它提供了一种统一的方式来表示、存储和操作复杂的结构化数据,是面向对象建模的强大工具。本教程旨在帮助...

Global site tag (gtag.js) - Google Analytics