[zt]第四章 GEF框架(1)

FROM:http://www.blog.edu.cn/user1/19180/archives/2005/375044.shtml

4.1 概述

    GEF是一套建立在Draw2D基础之上的eclipse插件,它为Draw2D提供控制功能,它监听各种事件,如鼠标、键盘、Workbench的事件,并进行响应。GEF是一套框架,它提供一套完整的图形用户接口系统的基本处理方式,但是具体的功能需要我们实现,这一点和MFC的窗口系统不同。

    GEF使用MVC模式,它成功的将模型、视图、控制器三个部分剥离。模型是由用户编写的任何类,视图则采用Draw2D系统,控制器则是之前提到过的EditPart。

    M-V-C三个部分的交互式这样完成的:当用户直接对V进行了操作,比如改变V的形状或者修改了Label中的文字,系统就会产生一个Request,并将这个Request传递给相应的EditPart进行处理;EditPart根据Request的类型生成相应的Command(Command需要用户编写),并将Command在传递出去;系统得到Command后,就会在合适的时机执行这个Command。如果M发生了变化,并且需要更新视图,它可以使用一个PropertyChangeSupport实例,提示EditPart对V进行改变。PropertyChangeSupport实际上是M与EditPart的一个桥梁,只要在EditPart中实现PropertyChangeListener接口,就可以向M的PropertyChangeSupport实例注册自己为监听者。具体的例子将在第3节给出。

    实现一个模型是很简单,但是注意一般来说应该让模型包含一个PropertyChangeSupport类的实例。调用PropertyChangeSupport的addPropertyChangeListener方法可以向其中注册一个监听者,调用removePropertyChangeListener的移出一个监听者,调用firePropertyChange方法则向所有注册的监听者通知发生了变化。

    实现一个EditPart一般来说需要重载performRequest、getCommand、activate、deactivate和refreshVisuals函数,并实现createEditPolicies、createFigure接口函数,为了让EditPart能够成为PropertyChangeListener,你还必须实现PropertyChangeListener接口。performRequest和getCommand将在第3节介绍,activate和deactivate用于处理当EditPart处于激活或者非激活状态时的操作,一般来说,可以在这两个函数中注册和移除自己监听者的角色。refreshVisuals函数用于更新自己的视图。

    下面给出一个模型和它对应的EditPart的例子:
Element.java:

java 代码

 

  1. package com.example.model;   
  2.   
  3. import java.beans.PropertyChangeListener;   
  4. import java.beans.PropertyChangeSupport;   
  5. import java.io.Serializable;   
  6.   
  7. public abstract class Element implements Cloneable, Serializable {   
  8.   
  9.     PropertyChangeSupport listeners = new PropertyChangeSupport(this);   
  10.   
  11.     public void addPropertyChangeListener(PropertyChangeListener l) {   
  12.         listeners.addPropertyChangeListener(l);   
  13.     }   
  14.   
  15.     protected void firePropertyChange(String prop, Object old, Object newValue) {   
  16.         listeners.firePropertyChange(prop, old, newValue);   
  17.     }   
  18.   
  19.     protected void fireStructureChange(String prop, Object child) {   
  20.         listeners.firePropertyChange(prop, null, child);   
  21.     }   
  22.   
  23.     public void removePropertyChangeListener(PropertyChangeListener l) {   
  24.         listeners.removePropertyChangeListener(l);   
  25.     }   
  26.   
  27. }   


注意这个Element类中包含了一个PropertyChangeSupport对象。

Node.java:

java 代码
  1. package com.example.model;   
  2.   
  3. import java.util.ArrayList;   
  4. import java.util.List;   
  5.   
  6. import org.eclipse.draw2d.geometry.Dimension;   
  7. import org.eclipse.draw2d.geometry.Point;   
  8. import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor;   
  9. import org.eclipse.ui.views.properties.IPropertyDescriptor;   
  10. import org.eclipse.ui.views.properties.IPropertySource;   
  11. import org.eclipse.ui.views.properties.TextPropertyDescriptor;   
  12.   
  13. public class Node extends Element implements IPropertySource {   
  14.     final public static String PROP_LOCATION = "LOCATION";   
  15.   
  16.     final public static String PROP_NAME = "NAME";   
  17.   
  18.     final public static String PROP_VISIBLE = "VISIBLE";   
  19.   
  20.     final public static String PROP_INPUTS = "INPUTS";   
  21.   
  22.     final public static String PROP_OUTPUTS = "OUTPUTS";   
  23.   
  24.     protected Point location = new Point(00);   
  25.        
  26.     private Dimension size=new Dimension(150,40);   
  27.   
  28.     protected String name = "Node";   
  29.   
  30.     protected boolean visible = true;   
  31.   
  32.     protected IPropertyDescriptor[] descriptors = new IPropertyDescriptor[] {   
  33.             new TextPropertyDescriptor(PROP_NAME, "Name"),   
  34.             new ComboBoxPropertyDescriptor(PROP_VISIBLE, "Visible"new String[] { "true""false" }) };   
  35.   
  36.     protected List outputs = new ArrayList(5);   
  37.   
  38.     protected List inputs = new ArrayList(5);   
  39.   
  40.     public void addInput(Connection connection) {   
  41.         this.inputs.add(connection);   
  42.         fireStructureChange(PROP_INPUTS, connection);   
  43.     }   
  44.   
  45.     public void addOutput(Connection connection) {   
  46.         this.outputs.add(connection);   
  47.         fireStructureChange(PROP_OUTPUTS, connection);   
  48.     }   
  49.   
  50.     public List getIncomingConnections() {   
  51.         return this.inputs;   
  52.     }   
  53.   
  54.     public List getOutgoingConnections() {   
  55.         return this.outputs;   
  56.     }   
  57.   
  58.     public void removeInput(Connection connection) {   
  59.         this.inputs.remove(connection);   
  60.         fireStructureChange(PROP_INPUTS, connection);   
  61.     }   
  62.   
  63.     public void removeOutput(Connection connection) {   
  64.         this.outputs.remove(connection);   
  65.         fireStructureChange(PROP_OUTPUTS, connection);   
  66.     }   
  67.   
  68.     public boolean isVisible() {   
  69.         return visible;   
  70.     }   
  71.   
  72.     public void setVisible(boolean visible) {   
  73.         if (this.visible == visible) {   
  74.             return;   
  75.         }   
  76.         this.visible = visible;   
  77.         firePropertyChange(PROP_VISIBLE, null, Boolean.valueOf(visible));   
  78.     }   
  79.   
  80.     public String getName() {   
  81.         return name;   
  82.     }   
  83.   
  84.     public void setName(String name) {   
  85.         if (this.name.equals(name)) {   
  86.             return;   
  87.         }   
  88.         this.name = name;   
  89.         firePropertyChange(PROP_NAME, null, name);   
  90.     }   
  91.   
  92.     public void setLocation(Point p) {   
  93.         if (this.location.equals(p)) {   
  94.             return;   
  95.         }   
  96.         this.location = p;   
  97.         firePropertyChange(PROP_LOCATION, null, p);   
  98.     }   
  99.   
  100.     public Point getLocation() {   
  101.         return location;   
  102.     }   
  103.   
  104.     public void setSize(Dimension size) {   
  105.         this.size = size;   
  106.     }   
  107.   
  108.     public Dimension getSize() {   
  109.         return size;   
  110.     }   
  111.   
  112.     //------------------------------------------------------------------------   
  113.     // Abstract methods from IPropertySource   
  114.   
  115.     public Object getEditableValue() {   
  116.         return this;   
  117.     }   
  118.   
  119.     public IPropertyDescriptor[] getPropertyDescriptors() {   
  120.         return descriptors;   
  121.     }   
  122.   
  123.     public Object getPropertyValue(Object id) {   
  124.         if (PROP_NAME.equals(id))   
  125.             return getName();   
  126.         if (PROP_VISIBLE.equals(id))   
  127.             return isVisible() ? new Integer(0) : new Integer(1);   
  128.         return null;   
  129.     }   
  130.   
  131.     public boolean isPropertySet(Object id) {   
  132.         return true;   
  133.     }   
  134.   
  135.     public void resetPropertyValue(Object id) {   
  136.   
  137.     }   
  138.   
  139.     public void setPropertyValue(Object id, Object value) {   
  140.         if (PROP_NAME.equals(id))   
  141.             setName((String) value);   
  142.         if (PROP_VISIBLE.equals(id))   
  143.             setVisible(((Integer) value).intValue() == 0);   
  144.     }   
  145.   
  146. }   

这个Node继承自Element,并且实现了IPropertySource,这表明它可以作为属性页的数据源。下面再看对应的EditPart:
NodePart.java:

java 代码
  1. package com.example.parts;   
  2.   
  3. import java.beans.PropertyChangeEvent;   
  4. import java.beans.PropertyChangeListener;   
  5. import java.util.List;   
  6.   
  7. import org.eclipse.draw2d.ChopboxAnchor;   
  8. import org.eclipse.draw2d.ConnectionAnchor;   
  9. import org.eclipse.draw2d.IFigure;   
  10. import org.eclipse.draw2d.geometry.Dimension;   
  11. import org.eclipse.draw2d.geometry.Point;   
  12. import org.eclipse.draw2d.geometry.Rectangle;   
  13. import org.eclipse.gef.ConnectionEditPart;   
  14. import org.eclipse.gef.EditPolicy;   
  15. import org.eclipse.gef.GraphicalEditPart;   
  16. import org.eclipse.gef.NodeEditPart;   
  17. import org.eclipse.gef.Request;   
  18. import org.eclipse.gef.RequestConstants;   
  19. import org.eclipse.gef.commands.Command;   
  20. import org.eclipse.gef.editparts.AbstractGraphicalEditPart;   
  21. import org.eclipse.gef.requests.ChangeBoundsRequest;   
  22. import org.eclipse.gef.requests.DirectEditRequest;   
  23. import org.eclipse.gef.tools.DirectEditManager;   
  24. import org.eclipse.jface.viewers.TextCellEditor;   
  25.   
  26. import com.example.commands.RenameNodeCommand;   
  27. import com.example.commands.ResizeNodeCommand;   
  28. import com.example.figures.NodeFigure;   
  29. import com.example.model.Node;   
  30. import com.example.policies.NodeDirectEditPolicy;   
  31. import com.example.policies.NodeEditPolicy;   
  32. import com.example.policies.NodeGraphicalNodeEditPolicy;   
  33.   
  34. public class NodePart extends AbstractGraphicalEditPart implements PropertyChangeListener, NodeEditPart {   
  35.   
  36.     protected DirectEditManager manager;   
  37.   
  38.     public void performRequest(Request req) {   
  39.         if (req.getType().equals(RequestConstants.REQ_DIRECT_EDIT)) {   
  40.             if (manager == null) {   
  41.                 NodeFigure figure = (NodeFigure) getFigure();   
  42.                 manager = new NodeDirectEditManager(this, TextCellEditor.classnew NodeCellEditorLocator(figure));   
  43.             }   
  44.             manager.show();   
  45.         }   
  46.     }   
  47.     public Command getCommand(Request request) {   
  48.         if(REQ_RESIZE.equals(request.getType())) {   
  49.             ChangeBoundsRequest req=(ChangeBoundsRequest)request;   
  50.             Node node=(Node)getModel();   
  51.             ResizeNodeCommand cmd=new ResizeNodeCommand(node,this);   
  52.             Rectangle rect=new Rectangle(node.getLocation(),node.getSize());   
  53.             cmd.setRectangle(req.getTransformedRectangle(rect));   
  54.             return cmd;   
  55.         }   
  56.         return super.getCommand(request);   
  57.     }   
  58.   
  59.     public void propertyChange(PropertyChangeEvent evt) {   
  60.         if (evt.getPropertyName().equals(Node.PROP_LOCATION))   
  61.             refreshVisuals();   
  62.         else if (evt.getPropertyName().equals(Node.PROP_NAME))   
  63.             refreshVisuals();   
  64.         else if (evt.getPropertyName().equals(Node.PROP_INPUTS))   
  65.             refreshTargetConnections();   
  66.         else if (evt.getPropertyName().equals(Node.PROP_OUTPUTS))   
  67.             refreshSourceConnections();   
  68.     }   
  69.   
  70.     protected IFigure createFigure() {   
  71.         return new NodeFigure();   
  72.     }   
  73.   
  74.     protected void createEditPolicies() {   
  75.         installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new NodeDirectEditPolicy());   
  76.         installEditPolicy(EditPolicy.COMPONENT_ROLE, new NodeEditPolicy());   
  77.         installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new NodeGraphicalNodeEditPolicy());   
  78.     }   
  79.   
  80.     public void activate() {   
  81.         if (isActive()) {   
  82.             return;   
  83.         }   
  84.         super.activate();   
  85.         ((Node) getModel()).addPropertyChangeListener(this);   
  86.     }   
  87.   
  88.     public void deactivate() {   
  89.         if (!isActive()) {   
  90.             return;   
  91.         }   
  92.         super.deactivate();   
  93.         ((Node) getModel()).removePropertyChangeListener(this);   
  94.     }   
  95.   
  96.     protected void refreshVisuals() {   
  97.         Node node = (Node) getModel();   
  98.         Point loc = node.getLocation();   
  99.         Dimension size = node.getSize();   
  100.         Rectangle rectangle = new Rectangle(loc, size);   
  101.         ((NodeFigure) this.getFigure()).setName(((Node) this.getModel()).getName());   
  102.         //this.getFigure().setBounds(rectangle);   
  103.         ((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(), rectangle);   
  104.     }   
  105.   
  106.     //------------------------------------------------------------------------   
  107.     // Abstract methods from NodeEditPart   
  108.   
  109.     public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection) {   
  110.         return new ChopboxAnchor(getFigure());   
  111.     }   
  112.   
  113.     public ConnectionAnchor getSourceConnectionAnchor(Request request) {   
  114.         return new ChopboxAnchor(getFigure());   
  115.     }   
  116.   
  117.     public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart connection) {   
  118.         return new ChopboxAnchor(getFigure());   
  119.     }   
  120.   
  121.     public ConnectionAnchor getTargetConnectionAnchor(Request request) {   
  122.         return new ChopboxAnchor(getFigure());   
  123.     }   
  124.   
  125.     protected List getModelSourceConnections() {   
  126.         return ((Node) this.getModel()).getOutgoingConnections();   
  127.     }   
  128.   
  129.     protected List getModelTargetConnections() {   
  130.         return ((Node) this.getModel()).getIncomingConnections();   
  131.     }   
  132.   
  133. }   

这个EditPart还实现了NodeEditPart接口,这表明它可以被附着。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值