- 浏览: 74923 次
- 性别:
- 来自: 成都
最新评论
-
Javaloverlover:
最好能写点使用场景,理论结合实际嘛。1、当类初始化时要消耗非常 ...
Java设计模式之原型模式 -
Javakeith:
写的不错,文章中说在某个的地方用,给个实例就更好了!
Java设计模式之代理模式 -
bobshute:
好.通俗,明了.
Java设计模式之简单工厂模式 -
zengguo1988:
写的不错。
个人博客 欢迎访问: http://zjava ...
Java设计模式之原型模式
1.控制器的功能
在GEF的MVC结构里,控制器是模型与视图之间的桥梁,也是整个GEF的核心,它不仅要监听模型的变化,当用户编辑视图时,还要把编辑结果反应到模型上。
在GEF中,控制器是由一组EditPart对象共同组成的,每一个模型对象都对应一个EditPart对象。应用程序中需要有一个EditPartFactory对象负责根据给定模型对象创建对应的EditPart对象,这个工厂类将在创建模型时被调用。
控制器是GEF中最复杂的一部分,GEF把控制器完成的工作又分成了几个部分,包括请求和编辑策略及引申出来的命令模式,如下图:
对每一个EditPart,用户都可以“安装”一些EditPolicy。用户对这个EditPart的特定操作会被交给已安装的对应EditPolicy处理。这样做的直接好处是可以在不同EditPart之间共享一些重复操作。
2.控制器的实现
每一个模型都会对应一个控制器,控制器主要负责模型和视图的同步。控制器要监听模型的属性改变的事件,并通知视图更新。另外,控制器还要设置相应的编辑策略,用来处理由视图接收的请求。
实现一个EditPart一般来说需要重载performRequest、getCommand、 activate、deactivate和refreshVisuals函数,并实现createEditPolicies、createFigure接 口函数,为了让EditPart能够成为PropertyChangeListener,你还必须实现PropertyChangeListener接 口。performRequest和getCommand将在第3节介绍,activate和deactivate用于处理当EditPart处于激活或 者非激活状态时的操作,一般来说,可以在这两个函数中注册和移除自己监听者的角色。refreshVisuals函数用于更新自己的视图。
- package com.example.parts;
- import java.beans.PropertyChangeEvent;
- import java.beans.PropertyChangeListener;
- import java.util.List;
- import org.eclipse.draw2d.ChopboxAnchor;
- import org.eclipse.draw2d.ConnectionAnchor;
- import org.eclipse.draw2d.IFigure;
- import org.eclipse.draw2d.geometry.Dimension;
- import org.eclipse.draw2d.geometry.Point;
- import org.eclipse.draw2d.geometry.Rectangle;
- import org.eclipse.gef.ConnectionEditPart;
- import org.eclipse.gef.EditPolicy;
- import org.eclipse.gef.GraphicalEditPart;
- import org.eclipse.gef.NodeEditPart;
- import org.eclipse.gef.Request;
- import org.eclipse.gef.RequestConstants;
- import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
- import org.eclipse.gef.tools.DirectEditManager;
- import org.eclipse.jface.viewers.TextCellEditor;
- import com.example.figures.NodeFigure;
- import com.example.model.Node;
- import com.example.policies.NodeDirectEditPolicy;
- import com.example.policies.NodeEditPolicy;
- import com.example.policies.NodeGraphicalNodeEditPolicy;
- public class NodePart extends AbstractGraphicalEditPart implements PropertyChangeListener, NodeEditPart {
- protected DirectEditManager manager;
- //处理请求
- public void performRequest(Request req) {
- if (req.getType().equals(RequestConstants.REQ_DIRECT_EDIT)) {
- if (manager == null) {
- NodeFigure figure = (NodeFigure) getFigure();
- manager = new NodeDirectEditManager(this, TextCellEditor.class, new NodeCellEditorLocator(figure));
- }
- manager.show();
- }
- }
- //监听模型属性改变
- public void propertyChange(PropertyChangeEvent evt) {
- if (evt.getPropertyName().equals(Node.PROP_LOCATION))
- //更新视图
- refreshVisuals();
- else if (evt.getPropertyName().equals(Node.PROP_NAME))
- refreshVisuals();
- else if (evt.getPropertyName().equals(Node.PROP_INPUTS))
- //更新连接
- refreshTargetConnections();
- else if (evt.getPropertyName().equals(Node.PROP_OUTPUTS))
- refreshSourceConnections();
- }
- //创建模型对应的视图
- protected IFigure createFigure() {
- return new NodeFigure();
- }
- //设置编辑策略
- protected void createEditPolicies() {
- installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new NodeDirectEditPolicy());
- installEditPolicy(EditPolicy.COMPONENT_ROLE, new NodeEditPolicy());
- installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new NodeGraphicalNodeEditPolicy());
- }
- //注册自己成为模型的监听器
- public void activate() {
- if (isActive()) {
- return;
- }
- super.activate();
- ((Node) getModel()).addPropertyChangeListener(this);
- }
- //把自己从模型的监听器中删除
- public void deactivate() {
- if (!isActive()) {
- return;
- }
- super.deactivate();
- ((Node) getModel()).removePropertyChangeListener(this);
- }
- //更新视图的显示
- protected void refreshVisuals() {
- Node node = (Node) getModel();
- Point loc = node.getLocation();
- Dimension size = new Dimension(150, 40);
- Rectangle rectangle = new Rectangle(loc, size);
- ((NodeFigure) this.getFigure()).setName(((Node) this.getModel()).getName());
- ((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(), rectangle);
- }
- //------------------------------------------------------------------------
- // Abstract methods from NodeEditPart
- //得到源连接的连接点
- public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection) {
- return new ChopboxAnchor(getFigure());
- }
- public ConnectionAnchor getSourceConnectionAnchor(Request request) {
- return new ChopboxAnchor(getFigure());
- }
- //得到目标连接的连接点
- public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart connection) {
- return new ChopboxAnchor(getFigure());
- }
- public ConnectionAnchor getTargetConnectionAnchor(Request request) {
- return new ChopboxAnchor(getFigure());
- }
- //得到以模型作为源的连接列表
- protected List getModelSourceConnections() {
- return ((Node) this.getModel()).getOutgoingConnections();
- }
- //得到以模型作为目标的连接列表
- protected List getModelTargetConnections() {
- return ((Node) this.getModel()).getIncomingConnections();
- }
- }
最后,要为EditPart增加适当的EditPolicy,这是通过覆盖EditPart的createEditPolicies()方法来实现 的,每一个被"安装"到EditPart中的EditPolicy都对应一个用来表示角色(Role)的字符串。对于在模型中有子元素的 EditPart,一般都会安装一个EditPolicy.LAYOUT_ROLE角色的EditPolicy(见下面的代码),后者多为 LayoutEditPolicy的子类;对于连接类型的EditPart,一般要安装 EditPolicy.CONNECTION_ENDPOINTS_ROLE角色的EditPolicy,后者则多为 ConnectionEndpointEditPolicy或其子类,等等。
用户的操作会被当前工具(缺省为选择工具SelectionTool)转换为请求(Request),请求根据类型被分发到目标EditPart所安装的EditPolicy,后者根据请求对应的角色来判断是否应该创建命令并执行。
在GEF里,这个弹出的编辑器由DirectEditManager类负责管理,在我们的NodePart类里,通过覆盖 performRequest()方法响应用户的DirectEdit请求,在这个方法里一般要构造一个DirectEditManager类的实例(例 子中的NodeDirectEditManager),并传入必要的参数,包括接受请求的EditPart(就是自己,this)、编辑器类型(使用 TextCellEditor)以及用来定位编辑器的CellEditorLocator(NodeCellEditorLocator),然后用 show()方法使编辑器显示出来,而编辑器中显示的内容已经在构造方法里得到。简单看一下NodeCellEditorLocator类,它的关键方法 在relocate()里,当编辑器里的内容改变时,这个方法被调用从而让编辑器始终处于正确的坐标位置。DirectEditManager有一个重要 的initCellEditor()方法,它的主要作用是设置编辑器的初始值。在我们的例子里,初始值设置为被编辑NodePart对应模型 (Node)的name属性值;这里还另外完成了设置编辑器字体和选中全部文字(selectAll)的功能,因为这样更符合一般使用习惯。
在NodePart里还要增加一个角色为DIRECT_EDIT_ROLE的EditPolicy,它应该继承自 DirectEditPolicy,有两个方法需要实现:getDirectEditCommand()和showCurrentEditValue (),虽然还未遇到过,但前者的作用你不应该感到陌生--在编辑结束时生成一个Command对象将修改结果作用到模型;后者的目的是更新Figure中 的显示,虽然我们的编辑器覆盖了Figure中的文本,似乎并不需要管Figure的显示,但在编辑中时刻保持这两个文本的一致才不会出现"盖不住"的情 况,例如当编辑器里的文本较短时。
上例通过继承AbstractGraphicalEditPart类实现了一个EditPart,另外,当GEF框架创建一个模型时,都会为此模型创建一 个对应的控制器。创建控制器的操作是在控制器工厂中完成的,用户可以在编辑器初始化时指定控制器工厂,例如:“getGraphicalViewer ().setEditPartFactory(new PartFactory())”,其中PartFactory为控制器工厂,代码如下:- /*
- * Created on 2005-1-24
- *
- * TODO To change the template for this generated file go to
- * Window - Preferences - Java - Code Style - Code Templates
- */
- package com.example.parts;
- import org.eclipse.gef.EditPart;
- import org.eclipse.gef.EditPartFactory;
- import com.example.model.Connection;
- import com.example.model.Diagram;
- public class PartFactory implements EditPartFactory {
- public EditPart createEditPart(EditPart context, Object model) {
- EditPart part = null;
- //根据模型创建相应的EditPart
- if (model instanceof Diagram)
- part = new DiagramPart();
- else if (model instanceof Connection)
- part = new ConnectionPart();
- else
- part = new NodePart();
- //设置EditPart对应的模型
- part.setModel(model);
- //返回根据模型创建的EditPart
- return part;
- }
- }
通过创建控制器和控制器工厂,GEF编辑器将会知道在模型创建后,自动调用控制器工厂创建对应的空气,从而实现模型和控制器的一一对应关系。
发表评论
-
GEF原理及实现系列(八、选项板)
2007-12-03 16:38 3770选项板提供了用户选择模型元素,并提供相应的机制把模型和视图加入 ... -
GEF原理及实现系列(七、模型同步)
2007-12-03 16:37 2000为了保证数据和展现的同步,必须要有一种消息通知机制,当模型被修 ... -
GEF原理及实现系列(六、命令)
2007-12-03 16:36 2138为了提高代码的重用性,以及实现GEF编辑器的功能,GEF采用命 ... -
GEF原理及实现系列(五、请求和编辑策略)
2007-12-03 16:35 2779请求和编辑策略是GEF框架中减轻控制器的负担、减小代码耦合度而 ... -
GEF原理及实现系列(三、视图)
2007-12-03 16:30 3107GEF视图通常利用Draw2d图 ... -
GEF原理及实现系列(二、模型)
2007-12-03 16:28 3836GEF的模型只与控制器打交道,而不知道任何与视图有关的东西。 ... -
GEF原理及实现系列(一、GEF概述)
2007-12-03 16:23 3217GEF(Graphical Editor Framework) ... -
开张了
2007-11-09 15:09 1179结束了一些事情,开始了一些事情。 本来应该有很多感慨才是的, ... -
糖在超市
2007-09-10 21:45 1161有些事情,不知道是描述的太过含蓄,还是表达的太过直接,让人无法 ...
相关推荐
- **模型-视图-控制器(MVC)**:GEF基于MVC设计模式,将图形元素的逻辑(模型)、显示(视图)和交互(控制器)分离,实现了高度可定制化和可扩展性。 - **Part和EditPart**:Part代表工作台上的一个独立组件,...
GEF 通过引入“模型-视图-控制器”(Model-View-Controller,MVC)架构模式,将数据模型、视图和控制器分开处理,便于维护和扩展。在这个架构中,数据模型表示应用程序的数据结构,视图负责显示这些数据,而控制器则...
GEF提供了模型-视图-控制器(MVC)架构,使得开发者能够轻松地创建和操作图形元素。它的核心功能包括图形对象的创建、拖放操作、连接线的管理、以及各种图形编辑行为的实现。GEF-3.7和GEF-3.8是其不同版本,可能包含...
- `gef.tutorial.step.parts`: 存放控制器相关的类(如EditParts)。 - `gef.tutorial.step.ui`: 存放视图相关的类, 如Editor中的图形显示。 5. **Editor实现**: - `gef.tutorial.step.ui`包中的Editor继承自`org....
1. **模型-视图-控制器(MVC)**:GEF基于MVC设计模式,模型存储图形数据,视图负责显示,控制器处理用户交互。 2. **编辑领域(EditPart)**:编辑领域是GEF中的核心组件,它将模型与视图关联起来,处理用户交互和...
2. **MVC模式**:在GEF中,模型负责存储数据,视图负责显示模型的内容,控制器处理用户的输入并更新模型。这种分离使代码更易于维护和扩展。 3. **图元(Figure)和图元工厂(FigureFactory)**:GEF中的图元是图形...
在Gef框架中,核心概念包括Model(模型)、View(视图)和Controller(控制器)。Model是应用程序的数据结构,存储了需要在图形界面中表示的信息。View是数据的可视化表示,根据Model的变化实时更新。Controller则是...
GEF是基于Java语言开发的,它遵循MVC(模型-视图-控制器)设计模式,为图形编辑器的开发提供了强大的支持。通过GEF,开发者可以快速实现图形的绘制、编辑操作、拖放功能以及自定义的图形布局。GEF不仅适用于开发...
- **Control(控制器)**:这部分主要是由一系列`EditPart`组成,它们是GEF的核心组件。每个`EditPart`都对应于模型中的某个元素,并负责处理用户交互。 #### 四、Draw2D的核心组件——LightweightSystem **...
它提供了模型-视图-控制器(MVC)架构,使得数据模型、视图展示和用户交互操作可以清晰地分离,便于维护和扩展。 **gef-step2.rar**中的内容可能是这个系列教程的第二部分,通常在学习过程中,随着教程的深入,...
GEF的核心组件包括模型(Model)、场景图(Scene Graph)、视图(View)和控制器(Controller),通过这些组件,开发者可以轻松地构建出具有拖放、连接、撤销/重做等功能的图形编辑器。 ### Draw2D简介 Draw2D是...
GEF 为开发者提供了模型-视图-控制器(MVC)的设计模式,使得开发者可以专注于图形编辑功能的实现,而不需要关心底层渲染和交互细节。它包括了基础的图形绘制、事件处理、工具条和菜单集成等核心功能,同时也支持...
- **建议**: 按照MVC(Model-View-Controller)模式组织代码,将模型、视图和控制器分离开来。 - `Kylingef.module`: 存放模型相关的类和接口。 - `Kylingef.parts`: 存放控制器相关的类和接口。 - `Kylingef.ui`: ...
- **模型-视图-控制器(MVC)** 设计模式:分离了数据模型、用户界面和控制逻辑,使得设计更加灵活和可维护。 - **绘图工具**:包括画布、图元、连接线等基本元素,用于构建图形编辑界面。 - **手势和事件处理**:...