« 1 2» Pages: ( 1/2 total )
本页主题: emf&gef之一example.my.gefpractice 打印 | 加为IE收藏 | 收藏主题 | 上一主题 | 下一主题

hopeshared

状态: 离线
级别: CEC总版
精华: 0
发帖: 412
威望: 79 点
财富: 58 元
在线时间:73(小时)
注册时间:2005-10-16
最后登录:2008-08-28

emf&gef之一example.my.gefpractice

八进制写的关于GEF以及EMF的文章,对我当时的工作帮助很大。

    我最初看的是他的关于GEF的文章,但是我的工作需要将GEF与EMF结合,本文使用的例子就是根据八进制的Blog中gefpractice改编而成。

一 定义模型

    自从EMF出现以后,出现了一种新的说法:模型驱动的软件开发(例如Marlin),经过这段时间的研究开发,发现使用GEF与EMF确实是这样,一旦模型定义好了,这个项目就基本定型了。

    Ok,废话留着以后慢慢说,进入正题先。

    首先,定义模型。在gefpractice这个例子中,模型很简单,只有三类元素:Diagram、Node和Connection。他们之间的关系,用EMF的模型文件(ecore)定义出来就是这样的:
见 图1

    在做模型定义的时候,需要注意他们之间的包含关系。打开Properties视图,有一个Containment属性需要格外注意,因为它将决定该接点是一个属性还是一个子节点。以上图为例,这个属性设置为true,那么xml文件的格式是
<Diagram>
<Node/>
</Diagram>

假如是false,那么就是
<Diagram nodes=”//node.0”/>
<Node />

见图2

    由于有这个问题,在定义Node的时候就一定要注意sourceConnections和targetConnections的这个属性,一个是true,另一个是false。(自己想想,为什么呢?^-^)

    当然模型的定义并不是只有这种方式,只要你将逻辑表述对了,这个模型就没有问题。

二 创建工程

    用这个模型创建一个EMF Project。操作过程是New -> Project -> EMF Project -> 工程名称是eclipse.my.gefpractice -> 选择Ecore Model -> 选择定义好的nodeemf.ecore并load -> 其他的按照默认选择。这样,你的工作区就创建了这个工程。
    这个新建的工程有个model文件夹,里面有nodeemf.ecore和nodeemf.genmodel两个文件。用当前默认的编辑器打开nodeemf.genmodel文件,更改根节点(Nodeemf)的子节点(nodeemf)的属性(从属性视图中改)

见图3

    接着,右键选择上图中的根节点,选择Generate Model Code。这样,模型的代码就全部生成了。

三 事件监听

    一般,完全使用GEF的情况下,模型的监听是通过模型实现PropertySource来实现的。详细的请参看八进制的相关文章。但是本文中使用EMF来定义模型,那么原则上就不修改生成的代码。那么,这里利用Adapter来给模型“安装”属性。

这里给出一段示例代码
Copy code

public class NodePropertySource extends AbstractPropertySource {
     
     private static final String ID_X = "X";
     private static final String ID_Y = "Y";
     private static final String ID_NAME = "Name";
     private static final String ID_VISIBLE = "Visible";
     
     public NodePropertySource(Object model) {
           super(model);
     }
     
     private Node getNode() {
           return (Node) getModel();
     }
     
     public void createPropertyDescriptors(List descriptors) {
           descriptors.add(new TextPropertyDescriptor(ID_X, ID_X));
           descriptors.add(new TextPropertyDescriptor(ID_Y, ID_Y));
           descriptors.add(new TextPropertyDescriptor(ID_NAME, ID_NAME));
           descriptors.add(new TextPropertyDescriptor(ID_VISIBLE, ID_VISIBLE));
     }
     
     public Object getPropertyValue(Object id) {
           if(id == ID_X) {
                 return Integer.toString(getNode().getX());
           }
           if(id == ID_Y) {
                 return Integer.toString(getNode().getY());
           }
           if(id == ID_NAME) {
                 return getNode().getName();
           }
           if(id == ID_VISIBLE) {
                 return Boolean.toString(getNode().isVisible());
           }
           return null;
     }
     
     public void setPropertyValue(Object id, Object value) {
           if (id == ID_X) {
                 getNode().setX(Integer.parseInt(value.toString()));
           } else if (id == ID_Y) {
                 getNode().setY(Integer.parseInt(value.toString()));
           } else if (id == ID_NAME) {
                 getNode().setName(value.toString());
           } else if(id == ID_VISIBLE) {
                 getNode().setVisible(Boolean.getBoolean(value.toString()));
           }
     }
     
}



在这个模型对应的EditPart中安装这个PropertySource:
Copy code

          public Object getAdapter(Class key) {
           if (IPropertySource.class == key)
                 return new NodePropertySource(getModel());
           return super.getAdapter(key);
     }



由于用EMF定义的model本身就实现了notifier,故在本例中采用了EMF的事件监听机制。(采用GEF的事件监听机制也是可行的)

Copy code
          public void notifyChanged(Notification notification) {
           int type = notification.getEventType();
           int featureId = notification.getFeatureID(ModelPackage.class);
           switch(type) {
           case Notification.SET:
                 switch(featureId) {
                 case ModelPackage.NODE__X:
                 case ModelPackage.NODE__Y:
                 case ModelPackage.NODE__NAME:
                 case ModelPackage.NODE__VISIBLE:
                       refreshVisuals();
                       break;
                 }
           case Notification.ADD:
           case Notification.REMOVE:
                 switch(featureId) {
                 case ModelPackage.NODE__INPUTS:
                       refreshSourceConnections();
                       break;
                 case ModelPackage.NODE__OUTPUTS:
                       refreshTargetConnections();
                       break;
                 }
           }
     }



四 编辑器

    编辑器的其他重要组成部分,如Command,policy根原来的基本上没区别,这里就不再叙述了。

五 其他

    本例中不能从左边的Explorer视图中打开这个编辑器,而是用了Open Action和New Action。原因是本插件项目打包后可以加载到Rcp项目中。

六 本例的运行结果

见图4

除了上图中的问题外,还有一些小bug,呵呵,我比较懒,基本不用它,所以就没有改(Eclipse的懒加载法则)。这是我的一个面试考题,做这个例子,共用了1.5天。


七 源码

点击下载(见最后一个附件)

八 环境

JDK1.4
Eclipse 3.1
GEF
EMF
图片:
图片:
图片:
图片:
附件: example.my.gefpractice.rar (130 K) 下载次数:517
本帖最近评分记录:
  • 威望:5(reload_cn)
  • ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Welcome to my BLOG: http://hopeshared.blogjava.net
    顶端 时间: 2005年11月25日 22:50 | [楼 主]
    reload_cn

    头衔:CS高手 CS高手
    状态: 离线
    级别: CEC总版
    精华: 4
    发帖: 436
    威望: 72 点
    财富: 458 元
    在线时间:74(小时)
    注册时间:2005-09-21
    最后登录:2008-12-02

    不错,GEF和EMF配合的典型例子。
    顶端 时间: 2005年11月29日 12:46 | 1 楼
    linpay2000

    状态: 离线
    级别: CEC高级程序员
    精华: 0
    发帖: 42
    威望: 16 点
    财富: 280 元
    在线时间:11(小时)
    注册时间:2005-11-28
    最后登录:2007-10-07

    有什么优势呢,到底结合能带来多少便利。
    顶端 时间: 2005年11月29日 15:58 | 2 楼
    reload_cn

    头衔:CS高手 CS高手
    状态: 离线
    级别: CEC总版
    精华: 4
    发帖: 436
    威望: 72 点
    财富: 458 元
    在线时间:74(小时)
    注册时间:2005-09-21
    最后登录:2008-12-02

    比如StrutsBox这个插件,如果不用EMF生成模型和做模型框架,你自己写解析XML的工作量足够再写一个StrutsBox了。
    自动给你生成模型,并且还有序列化机制以及消息通知,另外还为你生成一些Viewer的provider
    顶端 时间: 2005年11月29日 16:59 | 3 楼
    bjzhanghao

    状态: 离线
    级别: CEC高级程序员
    精华: 0
    发帖: 1
    威望: 12 点
    财富: 210 元
    在线时间:2(小时)
    注册时间:2005-10-20
    最后登录:2006-03-28

    EMF的主要作用是帮你做这些工作:给定一个模型(uml,schema等等),帮你生成java代码。
    有了生成的API,就可以把精力放在怎样在java程序里使用这个模型了。
    顶端 时间: 2005年12月02日 12:14 | 4 楼
    reload_cn

    头衔:CS高手 CS高手
    状态: 离线
    级别: CEC总版
    精华: 4
    发帖: 436
    威望: 72 点
    财富: 458 元
    在线时间:74(小时)
    注册时间:2005-09-21
    最后登录:2008-12-02

    老张!终于盼到你来了!
    顶端 时间: 2005年12月02日 13:18 | 5 楼
    hopeshared

    状态: 离线
    级别: CEC总版
    精华: 0
    发帖: 412
    威望: 79 点
    财富: 58 元
    在线时间:73(小时)
    注册时间:2005-10-16
    最后登录:2008-08-28

    我一直都奇怪,他的blog更新如此之快,哪来的时间呢?

    这是他在本社区的第一篇帖子,真荣幸阿

    我想评个分来着,但是我不知道怎么评
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Welcome to my BLOG: http://hopeshared.blogjava.net
    顶端 时间: 2005年12月02日 13:25 | 6 楼
    suifongqi

    头衔:梦逸 梦逸
    状态: 离线
    级别: CEC高级程序员
    精华: 0
    发帖: 121
    威望: 40 点
    财富: 298 元
    在线时间:44(小时)
    注册时间:2005-11-07
    最后登录:2008-11-19

    楼主加油更新哦,期待你下一篇....
    顶端 时间: 2005年12月10日 12:29 | 7 楼
    拓跋

    状态: 离线
    级别: CEC高级程序员
    精华: 0
    发帖: 4
    威望: 11 点
    财富: 204 元
    在线时间:1(小时)
    注册时间:2006-02-09
    最后登录:2006-09-12

    你好,前面的EMF方面很清楚,但是突然跳到 “Code". 那从EMF模型到GEF是怎么个步骤呢。
    在压缩文件里的“心得“文档中讲道:
    首先要做的是一个插件项目,那么先新建example.my.gefpractice这个插件项目,然后将这个ecore和genmodel文件都copy到这个项目的根目录中,修改genmodel的属性,这些属性将指导genmodel将代码生成到正确的位置上。接着,按照文章中提到的方法,察看代码,为模型增加property.
    能不能结合例子,详细讲讲这个过程,比如修改那些文件,这个文件的位置等等
    谢谢
    顶端 时间: 2006年03月30日 23:10 | 8 楼
    hopeshared

    状态: 离线
    级别: CEC总版
    精华: 0
    发帖: 412
    威望: 79 点
    财富: 58 元
    在线时间:73(小时)
    注册时间:2005-10-16
    最后登录:2008-08-28

    是这样,genmodel需要修改的地方很少,最重要的就是你需要修改它的“目的地”。genmodel文件是用来做什么的?它是用来将EMF定义的模型翻译成Java代码。这里说到的修改就是指修改"目的地",这个"目的地"包括生成的代码所在的项目名称,生成的代码所在的包名。你打开我例子中的genmodel文件(最好在Eclipse中的专用编辑器打开),然后对比你的genmodel文件,看看有什么不同,应该可以很容易的看出该怎么改,因为我最初也是这样学习EMF的。
    接着是利用genmodel文件生成代码。
    “察看代码,为模型增加property”是查看genmodel文件生成代码。我添加的property文件都在一个包里,genmoedel生成的代码应该没有做过修改,也是不需要做修改的。你可以研究一下代码。
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Welcome to my BLOG: http://hopeshared.blogjava.net
    顶端 时间: 2006年03月31日 09:51 | 9 楼
    jiangtk05

    状态: 离线
    级别: CEC高级程序员
    精华: 0
    发帖: 1
    威望: 11 点
    财富: 201 元
    在线时间:5(小时)
    注册时间:2006-04-17
    最后登录:2006-07-22

    可否将八进制的blog地址告诉我?
    顶端 时间: 2006年04月17日 21:17 | 10 楼
    leonade

    状态: 离线
    级别: CEC程序员
    精华: 0
    发帖: 295
    威望: 12 点
    财富: 0 元
    在线时间:29(小时)
    注册时间:2006-04-07
    最后登录:2008-11-11

    好文。。。由于工作关系。一直没有悉心研究gef。。。虽然已经如雷贯耳。。
    好。。就从楼主的这篇文章开始。。。:)thanks
    顶端 时间: 2006年04月18日 08:58 | 11 楼
    bobby

    状态: 离线
    级别: CEC高级程序员
    精华: 0
    发帖: 16
    威望: 11 点
    财富: 218 元
    在线时间:9(小时)
    注册时间:2006-04-27
    最后登录:2006-08-10

    强!!
    顶端 时间: 2006年05月11日 16:31 | 12 楼
    yiyi1982916

    状态: 离线
    级别: CEC高级程序员
    精华: 0
    发帖: 10
    威望: 1 点
    财富: 111 元
    在线时间:0(小时)
    注册时间:2006-05-15
    最后登录:2007-01-09

    请问谁能给我一个简单的例子啊,比如,我有一个表达式,1&&1,想用图表示出来1用矩形,&&用圆形,然后用线连上这样怎么做啊?我只会做出矩形,.........
    顶端 时间: 2006年06月01日 16:04 | 13 楼
    yiyi1982916

    状态: 离线
    级别: CEC高级程序员
    精华: 0
    发帖: 10
    威望: 1 点
    财富: 111 元
    在线时间:0(小时)
    注册时间:2006-05-15
    最后登录:2007-01-09

    为什么上面的例子我下载了运行的时候报错呢?也没有是什么错误,就是运行的时候说有错.
    顶端 时间: 2006年06月01日 16:41 | 14 楼
    quxiangqian

    状态: 离线
    级别: CEC高级程序员
    精华: 0
    发帖: 6
    威望: 1 点
    财富: 106 元
    在线时间:0(小时)
    注册时间:2006-06-30
    最后登录:2006-10-18

    我现在还什么都不能做
    顶端 时间: 2006年07月02日 15:05 | 15 楼
    popular

    状态: 离线
    级别: CEC高级程序员
    精华: 0
    发帖: 57
    威望: 1 点
    财富: 168 元
    在线时间:0(小时)
    注册时间:2006-08-15
    最后登录:2008-07-21

    从这里起步,tks
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    淡薄明志 宁静致远
    顶端 时间: 2006年08月31日 13:02 | 16 楼
    bear110

    状态: 离线
    级别: CEC高级程序员
    精华: 0
    发帖: 32
    威望: 1 点
    财富: 146 元
    在线时间:0(小时)
    注册时间:2006-07-05
    最后登录:2008-05-08

    这个bjzhanghao是真的八进制?
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    随——想——go……
    顶端 时间: 2006年09月18日 14:16 | 17 楼
    ghdong

    状态: 离线
    级别: CEC高级程序员
    精华: 0
    发帖: 13
    威望: 1 点
    财富: 115 元
    在线时间:0(小时)
    注册时间:2006-12-23
    最后登录:2008-07-08

    可以将所写的编辑器在 Package Explorer 添加到上下文菜单中,
    这样就可以在当前的工作区内打开编辑器,而不用使用 action 来操作。
    顶端 时间: 2007年01月07日 19:50 | 18 楼
    lkitten

    状态: 离线
    级别: CEC高级程序员
    精华: 0
    发帖: 33
    威望: 11 点
    财富: 233 元
    在线时间:0(小时)
    注册时间:2005-12-25
    最后登录:2008-03-07

    存下了
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    程序员
    顶端 时间: 2007年04月04日 13:14 | 19 楼
    « 1 2» Pages: ( 1/2 total )
    中国Eclipse社区 » 图形与模型
    

    辽ICP备05021625号