专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Java教程 » eclipsegef:[Eclipse]GEF入门系列(十 2、自定义Request) »正文

eclipsegef:[Eclipse]GEF入门系列(十 2、自定义Request)

来源: 发布时间:星期四, 2009年1月8日 浏览:106次 评论:0
  本文举例源代码或素材下载

  先简单回顾下Request在GEF里作用Request是GEF里个比较重要角色Tool将原始鼠标事件转换为EditPart可以识别请求Request则承载了这些请求信息举例来说用户在调色板(Palette)里选择了创建节点工具(CreationTool)然后在画布区域按下鼠标左键这时产生在画布上鼠标单击事件将被CreationTool转换为个CreateRequest它里面包含了要创建对象坐标位置等信息 EditPart上如果安装了能够处理CreateRequestEditPolicy则相应EditPolicy会根据这个 CreateRequest创建个Command由后者实际执行创建新对象必要操作

  GEF已经为我们提供了很多种类Request其中最常用是CreateRequest及其子类 CreateConnectionRequest其他比较常见还有SelectionRequestChangeBoundsRequest和 ReconnectRequest等等要实现个典型图形化应用例如UML类图编辑器这些预定义Request基本够用了然而各种稀奇古怪需求我相信大家也见过不少很多需求不太符合约定俗成使用习惯因此实现起来更多依赖开发人员编码而不是开发框架带来便利在这种时候我们唯期望就是开发框架提供足够扩展机制以便让我们额外编写代码能和其他代码和平共处幸好GEF是具有足够扩展性有点跑题了再回到Request问题上为了介绍说明什么情况下需要自定义 Request我在前文“应用例子”里举例应用基础上假设个新需求:

  在Palette里增加 3个工具作用分别是把选中节点背景颜色改变为红色、绿色和蓝色

  假如你用过Photoshop或类似软件Software这个需求很像给节点上色“油漆桶”或“上色工具”当然在用户界面背后实际应用里这些颜色可能代表个节点重要程度优先级或是异常信息等等现在让我们通过创建个自定义Request来实现这个需求还是以前文中举例项目为基础

  、首先原来模型里节点(Node)类里没有反映颜色成员变量所以先要在Node类里添加个color属性以及相应 getter/ter思路方法注意这个ter思路方法里要和其他成员变量ter思路方法样传递模型改变消息仿照其他成员变量还应该有个静态串变量用来区分消息对应哪个属性

final public String PROP_COLOR = "COLOR";
  
protected RGB color = RGB(255, 255, 255);
  
public RGB getColor {
   color;
}
  
public void Color(RGB color) {
   (this.color.equals(color)) {
    ;
  }
  this.color = color;
  firePropertyChange(PROP_COLOR, null, color);
}
2、然后要让Nodecolor属性变化能够反映到图形上因此要修改NodePart里propertyChanged和 refreshVisuals思路方法在前者里增加对color属性响应在后者里将NodeFigure背景颜色设置为Nodecolor属性对应颜色(注意Color对象是系统资源对象实际使用里需要缓存Cache以避免系统资源耗尽为节约篇幅起见举例代码直接 Color了)

public void propertyChange(PropertyChangeEvent evt) {
  
   (evt.getPropertyName.equals(Node.PROP_COLOR))//Response to color change
    refreshVisuals;
}
  
protected void refreshVisuals {
  
  ((NodeFigure) this.getFigure).BackgroundColor( Color(null, node.getColor));//TODO cache color instances
}


   3、现在来创建我们自己Request是改变颜色所以不妨叫做ChangeColorRequest它应当继承自org.eclipse.gef.Request我们需要ChangeColorRequest上带有两样信息:1.需要改变颜色节点;2.目标颜色因此它应该有这两个成员变量

import org.eclipse.gef.Request;
import org.eclipse.swt.graphics.RGB;
import com.example.model.Node;
  
public ChangeColorRequest extends Request{
  final public String REQ_CHANGE_COLOR="REQ_CHANGE_COLOR";
  private Node node;
  private RGB color;
  
  public ChangeColorRequest(Node node, RGB color) {
    super;
    this.color = color;
    this.node = node;
    Type(REQ_CHANGE_COLOR);
  }
  
  public RGB getColor {
     color;
  }
  
  public Node getNode {
     node;
  }
  
  public void Node(Node node) {
    this.node = node;
  }
  
  public void Color(RGB color) {
    this.color = color;
  }
  
}


  ChangeColorRequest看起来和个JavaBean差不多确如此Request作用就是传递翻译后鼠标事件如果你看下org.eclipse.gef.Request代码你会发现Request还有个type属性这个属性般是串(在gefRequestConstants里预定义了如RequestConstants.REQ_SELECTION_HOVER) EditPolicy可以根据它决定是否处理这个Request在我们例子里顺便定义了这样个常量串REQ_CHANGE_COLOR在后面 ChangeColorEditPolicy里会用到它

   4、现在有个问题这个Request例子应该在哪里生成?答案是在Tool里用户在画布区域按下鼠标左键时当前 Palette里被选中Tool负责创建个Request我们现在面对这个需求需要我们创建种新Tool:ChangeColorTool我们让ChangeColorTool继承org.eclipse.gef.tools.SelectionTool“上色工具”使用方法和“选择工具”基本上差不多显然我们需要覆盖是handleButtonDown思路方法用来告诉gef如果用户当前选择了这个工具在画布区域按下鼠标会发生什么事情代码如下:

import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.tools.SelectionTool;
import org.eclipse.swt.graphics.RGB;
import com.example.model.Node;
import com.example.parts.NodePart;
  
public ChangeColorTool extends SelectionTool {
  private RGB color;
  
  public ChangeColorTool(RGB color) {
    super;
    this.color = color;
  }
  
  /**
   * If target editpart is an {@link NodePart}, create a {@link ChangeColorRequest} instance,
   * get command from target editpart with this request and execute.
   */
  @Override
  protected boolean handleButtonDown( button) {
    //Get selected editpart
    EditPart editPart = this.getTargetEditPart;
    
     (editPart instanceof NodePart) {
      NodePart nodePart = (NodePart) editPart;
      Node node = (Node) nodePart.getModel;
      
      //Create an instance of ChangeColorRequest
      ChangeColorRequest request = ChangeColorRequest(node, color);
      
      //Get command from the editpart
      Command command = editPart.getCommand(request);
      
      //Execute the command
      this.getDo.getCommandStack.execute(command);
      
       true;
    }
     false;
  }
  
}


   5、有了Tool还需要用ToolEntry把它包装起来添加到Palette里所以我们创建个名为 ChangeColorToolEntry并继承org.eclipse.gef.palette.ToolEntry覆盖createTool 思路方法让它返回我们ChangeColorTool例子这个ChangeColorToolEntry代码应该很容易理解:

import org.eclipse.gef.SharedCursors;
import org.eclipse.gef.Tool;
import org.eclipse.gef.palette.ToolEntry;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.RGB;
  
public ChangeColorToolEntry extends ToolEntry {
  private RGB color;
  
  public ChangeColorToolEntry(RGB color, String label, String Desc, ImageDescriptor iconSmall,
      ImageDescriptor iconLarge) {
    super(label, Desc, iconSmall, iconLarge);
    this.color = color;
  }
  
  @Override
  public Tool createTool {
    ChangeColorTool tool = ChangeColorTool(color);
    tool.UnloadWhenFinished(false);//Switch to selection tool after performed?
    tool.DefaultCursor(SharedCursors.CROSS);//Any cursor you like
     tool;
  }
  
}


   6、要把 3个这样ToolEntry添加到Palette里当然是通过修改原来PaletteFactory类为节约篇幅这里就不帖它代码了可以下载并参考举例代码PaletteFactory.java里createCategories和 createColorDrawer思路方法

  到目前为止ChangeColorRequest已经可以发出了接下来要解决问题是如何让EditPart处理这个请求

   7、我们知道gef里任何对模型修改都是通过command完成因此个ChangeColorCommand肯定是需要execute思路方法和undo思路方法如下所示:

public ChangeColorCommand extends Command{
  
  private RGB oldColor;
  
  @Override
  public void execute {
    oldColor = node.getColor;
    node.Color(color);
  }
  
  @Override
  public void undo {
    node.Color(oldColor);
  }
}
8、EditPolicy负责接收所有Request所以还要创建个ChangeColorEditPolicy在下面列出代码里你会看到我们定义了个新“Role”会儿我们在EditPart上安装这个EditPolicy时候要以这个串作为Key以避免覆盖EditPart上已有其他EditPolicy

import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.AbstractEditPolicy;
import org.eclipse.swt.graphics.RGB;
  
import com.example.model.Node;
  
public ChangeColorEditPolicy extends AbstractEditPolicy {
  final public String CHANGE_COLOR_ROLE = "CHANGE_COLOR_ROLE";
  
  @Override
  public Command getCommand(Request request) {
    //Judge whether this request is ersting by its type
     (request.getType ChangeColorRequest.REQ_CHANGE_COLOR) {
      ChangeColorRequest theRequest = (ChangeColorRequest) request;
      
      //Get information from request
      Node node = theRequest.getNode;
      RGB color = theRequest.getColor;
      
      //Create corresponding command and it
      ChangeColorCommand command = ChangeColorCommand(node, color);
       command;
    }
     null;
  }
}




   9、最后还是回到EditPart前面在第 2个步骤里我们曾经修改过NodePart里还有最后处需要添加那就是在EditPolicies思路方法里添加刚刚创建ChangeColorEditPolicy:

protected void createEditPolicies {
  
  
  //Add change color editpolicy
  EditPolicy(ChangeColorEditPolicy.CHANGE_COLOR_ROLE, ChangeColorEditPolicy);
}


  现在我们已经完成了所有必要修改来看下运行结果



  整理总结需要创建类有:ChangeColorRequest, ChangeColorTool, ChangeColorToolEntry, ChangeColorCommand, ChangeColorEditPolicy;需要修改类有:Node, NodePart, PaletteFactory在例子项目里为了方便大家浏览所有新创建类都放在com.example.request包里实际项目里还是建议分别放在对应包里



0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: