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 Method、Command、Policy等。为了便于读者更好的使用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时使用的Factory,Factory就会根据创建的模型,去创建与模型对应的EditPart(控制器)。
public class BerthGraphicalEditor ……{ …… protected void configureGraphicalViewer() { …… viewer.setEditPartFactory(new BerthEditPartFactory()); …… } |
2.2 Policy (Strategy)模式
当有一系统算法时,在算法的选择上,如果用if…else…则是非常不明智的,把这些算法抽象出来,然后根据程序的需要,动态地加载,这便是策略模式。GEF把不同的处理类型分为不同的角色如:LAYOUT_ROLE、COMPONENT_ROLE、DIRECT_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模式
Command在MVC的模式,以及图形进行处理中使用较多。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); } …… |
转载于:https://blog.51cto.com/growup/551853