1       Summary

 

本文讨论了GEF开发的一般步骤,并结合企业应用实例,详细介绍了GEF的主要运用方法。 本文未对GEF的原理作过多的阐述,如果需使用GEF进行企业应用的研发,还需对GEF的相关理论做深入的学习,这样才能完全驾驭GEF,开发出更多优秀的应用。

GEF世界里,几乎所有的东西都能进行定制,如果你觉得GEF的某个实现不满足你的需求,那么你可以把GEF的源代码拿过来,按照自己的方式来描绘GEF,如本文中的Ruler实现。改写源代码其实很简单,只要找到关键代码部分,按照自己的需要改写这个方法就ok

程序在描述世间万物,程序哲学的概念孕育而生。按照这种推论,程序不再是枯燥的代码,它可以是一种文学语言,来描述世间万物,表达你的喜怒哀乐。

 

(附件:本系列GEF教程的PDF版本)


 

 

参考文献

 

[1]    GEF website: http://download.eclipse.org/tools/gef

[2]    GEF in the Eclipse wiki: http://wiki.eclipse.org/index.php/Graphical_Editing_Framework

 

 

 

2       附件:GEF & Patterns

Java 深入到一定程度,就不可避免的碰到设计模式(design pattern)这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解。设计模式在java的中型系统中应用广泛,掌握常见的设计模式,不仅能有效的提高代码质量,还能更好的理解别人的代码。

GEF的基础架构中,用到了大量的设计模式,如Factory MethodCommandPolicy等。为了便于读者更好的使用GEF,我把GEF中常用的设计模式总结出来做以介绍。

2.1       Factory Method 模式

Factory Method:提供创建对象的接口,隐藏对象创建的复杂性,将创建过程进行封装。

GEF中大量用到了工厂模式,例如BerthEditPartFactory

 

public class BerthEditPartFactory implements EditPartFactory {

 

    public EditPart createEditPart(EditPart context, Object model) {

       AbstractGraphicalEditPart part = null;

       if (model instanceof DiagramModel) {

           part = new DiagramPart();

       } else if (model instanceof ShipModel) {

           part = new ShipPart();

       }

       part.setModel(model);

       return part;

    }

}

这样只需告诉GEF创建model时使用的FactoryFactory就会根据创建的模型,去创建与模型对应的EditPart(控制器)。

public class BerthGraphicalEditor ……{

……

protected void configureGraphicalViewer() {

       ……

       viewer.setEditPartFactory(new BerthEditPartFactory());

       ……

    }

 

2.2       Policy (Strategy)模式

当有一系统算法时,在算法的选择上,如果用ifelse…则是非常不明智的,把这些算法抽象出来,然后根据程序的需要,动态地加载,这便是策略模式。GEF把不同的处理类型分为不同的角色如:LAYOUT_ROLECOMPONENT_ROLEDIRECT_EDIT_ROLE等,在创建控制器(EditPart)时,把不同的策略安装到控制器中,由控制器根据请求类型,分配给不同的请求策略进行处理。

public class ShipPart extends AbstractEditPart{

    @Override

    protected void createEditPolicies() {

    installEditPolicy(EditPolicy.LAYOUT_ROLE, new BerthEditLayoutPolicy());

    installEditPolicy(EditPolicy.COMPONENT_ROLE, new AddPolicy());

    installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new DirectEditPolicy());

    }

……

在策略的实现中,可以对请求直接进行处理,也可以采用Command模式对处理进行进一步封装,在GEF中,基本上都是采用Command模式对处理进行封装的。

public class BerthEditLayoutPolicy extends XYLayoutEditPolicy {

    @Override

    protected Command createChangeConstraintCommand(EditPart child, Object constraint) {

       AbstractLayoutCommand command = null;

       if (child instanceof ShipPart) {

           command = new ShipChangeLayoutCommand();

       }

       else if(child instanceof DiagramPart)

       {

           command = new DiagramChangeLayoutCommand();

       }

        command.setModel(child.getModel());

        command.setConstraint((Rectangle)constraint);

        return command;

    }

……

 

2.3       Command模式

CommandMVC的模式,以及图形进行处理中使用较多。Command运用较多的就是菜单命令,我们在一个下拉菜单选择一个命令时,然后会执行一些动作。

将这些命令封装成在一个类中,然后用户(调用者)再对这个类进行操作,这就是Command 模式,换句话说,本来用户(调用者)是直接调用这些命令的,如菜单上打开文档(调用者),就直接指向打开文档的代码,使用Command 模式,就是在这两者之间增加一个中间者,将这种直接关系拗断,同时两者之间都隔离,基本没有关系了。

显然这样做的好处是符合封装的特性,降低耦合度,Command 是将对行为进行封装的典型模。

GEF为我们实现了Command的封装,并实现了命令堆栈,使用户能方便的实现对图形的“撤销、返回”功能。对于GEF开发人员来说,只需负责实现Command即可。

public class ShipChangeLayoutCommand extends AbstractLayoutCommand {

      private ShipModel model;

      private Rectangle layout;

      private Rectangle oldLayout;

      @Override

      public void execute() {

         this.model.setLayout(layout);

      }

@Override

      public void undo() {

         this.model.setLayout(this.oldLayout);

      }

      @Override

      public void redo()

      {

         this.model.setLayout(this.newLayout);

      }

……