GEF学习教程5-Unplugged版(结合EMF和GEF)

 EMF是eclipse下面的一个相当优秀的自动生成代码的框架.IBM很多大型软件都是基于EMF做出来的,这足已说明它的成熟和优秀.
特别地,如果是要做eclipse插件,EMF带来的帮助更大,除了根据模型生成model代码外,它还能够生成和eclipes UI相关的viewer和相应的viewprovider(控制层).
EMF其实不难,网上有很多关于EMF入门的文章,我这里也就不多废话了.
今天的主题是把前面的例子用EMF+GEF实现.

回顾一下前面的model,他们的UML图如下:


EMF需要我们先定义好model,然后它会根据model自动生成代码.可以有好几种方法,UML图(Rose),Java Codes, XML文件.我自己偏向于用Java代码来定义,因为自己没钱买rose,而XML我很容易出错(就没成功过).

根据上面的UML图,每个类的Java代码如下
Content.java
/**
 * @model
 
*/

public   interface  Content  {
    
/**
     * @model containment="true" type="Page"
     
*/

    
public List getChildren();

    
public void addChild(Page child);

    
public void removeChild(Page child);
}

Page.java
/**
 * @model
 
*/

public   interface  Page  {
    
/**
     * @model containment="true" type="Control"
     
*/

    
public List getChildren();
    
    
/**
     * @model
     
*/

    
public Rectangle getConstraint();

    
public void addChild(Control child);

    
public void removeChild(Control child);

}

Control.java
/**
 * @model
 
*/

public   interface  Control {

}

Container.java
/**
 * @model
 
*/

public   interface  Container  extends  Control  {
    
/**
     * @model containment="true" type="Column"
     
*/

    
public List getChildren();

    
public void addChild(Column child);

    
public void removeChild(Column child);
}

Column.java
/**
 * @model
 
*/

public   interface  Column  {
    
/**
     * @model containment="true" type="Node"
     
*/

    
public List getChildren();

    
/**
     * @model default="column"
     
*/

    
public String getName();

    
public void addChild(Node node, int index);

    
public void addChild(Node node);

    
public void removeChild(Node node);

}

Node.java
/**
 * @model
 
*/

public   interface  Node  {
    
/**
     * @model default="node"
     
*/

    
public String getName();

}

Label.java
/**
 * @model
 
*/

public   interface  Label  extends  Control  {
    
/**
     * @model default="label"
     
*/

    
public String getName();

}

MyButton.java
/**
 * @model
 
*/

public   interface  MyButton  extends  Control  {
    
/**
     * @model default="button"
     
*/

    
public String getName();

}

选择model文件夹,右键新建EMF Model,选择从Java代码得到model,文件名写geftest.genmodel,完成.然后就会自动生成geftest.ecore和geftest.genmodel两个文件,ecore文件保存的是emf core需要的信息, 而genmodel是一些比如生成的包名等和core无关的其它信息.

右键点ecore文件,然后选择:Initialize ecore_diagram diagram file,生成diagram_file文件,打开后得到下图:


可以看出来我们的model定义的是正确的.
然后修改一些地方就可以了.

EMF生成的代码有一个完整的事件机制,每个对象都可以有许多adapter,对象属性被改后会通知这些adapter.
所以我把以前的AbstractModel删掉了.然后把每个editpart做为它的model的adapter就可以了.这需要我们的所有editpart都实现Adapter接口.

因为我们的editpart都继承AbstractEditPartWithListener,所以我把里面原来的加入到listener list的代码都删掉了,加了如下代码:
EditPartWithListener.java
protected   void  hookIntoModel(EObject model)  {
        
if(model != null{
            model.eAdapters().add(
this);
        }

    }

    
    
protected   void  unhookFromModel(EObject model)  {
        
if(model != null{
            model.eAdapters().remove(
this);
        }

    }

    @Override
    
public   void  activate()  {
        hookIntoModel((EObject) getModel());
        
super.activate();
        
    }


    @Override
    
public   void  deactivate()  {
        unhookFromModel((EObject) getModel());
        
super.deactivate();
    }
然后每个EditPart实现notifyChanged方法:
举个例子,比如PageEditPart:
PageEditPart.java
public   void  notifyChanged(Notification notification)  {
        
int type = notification.getEventType();
        
int featureId = notification.getFeatureID(ModelPackage.class);
        
switch (type) {
        
case Notification.ADD:
        
case Notification.REMOVE:
            
switch (featureId) {
            
case ModelPackage.PAGE__CHILDREN:
                refreshChildren();
                
break;
            }

        
case Notification.SET:
            
switch (featureId) {
            
case ModelPackage.PAGE__CONSTRAINT:
                refreshVisuals();
                
break;
            }

        }

    }

最后修改Editor的ToolEntry.因为我们不能用SimpleFactory来简单的用反射生成每个model对象.
而应该用ModelFactory.eINSTANCE.createXXX方法.
Editor.java
CreationToolEntry creationPage  =   new  CreationToolEntry( " draw page " ,
                
" create page " new  CreationFactory()  {

                    
public Object getNewObject() {
                        
return ModelFactory.eINSTANCE.createPage();
                    }


                    
public Object getObjectType() {
                        
return null;
                    }

                }
, descriptor, descriptor);
        drawer.add(creationPage);

基本上这样就OK了,其实不麻烦.

代码下载

参考资源:
EMF
Using GEF with EMF
GEF学习教程-Unplugged版
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值