GEF 命令模式介绍

Wesley13
• 阅读 660

命令模式的结构如图:

在我们流程设计器中,实现复制粘贴功能,就是采用了命令模式,以剪切操作为例,当在编辑器中选中活动,在菜单中选择“剪切”,就会产生一个剪切命令(CutCommand对象)。

剪切操作所用到的类如下:

名称

说明

org.eclipse.gef.commands.Command

命令的抽象类

org.eclipse.gef.commands.Command.CompoundCommand

“结合多个命令的命令”的类

com.example.workflow.commands.CutCommand

“剪切命令”的类

com.example.workflow.model.WorkflowProcess

流程类

com.example.workflow.action.CutAction

剪切动作类

Command抽象类,这个类中有个execute()方法。

CompoundCommand表示“结合多个命令的命令”的类,此类继承了Command类,这个类的commandList属性是java.util.ArrayList类型,用来存放多个继承Command的对象,这个类在执行execute()方法时,会把commandList中所用命令的execute()方法按ArrayList中顺序执行一边,在执行undo()方法时,会把commandList中所用命令的undo ()方法按ArrayList中反序执行一边。

CutCommand类表示“剪切活动命令”,该类继承了Command类,该类有parent和child两个属性,parent是WorkflowProcess对象,表示流程对象,child是AbstractActivity对象,表示要剪切的活动对象,在构造函数中,给这两个属性赋值,指明要从哪个流程模型中删除哪个活动,在execute()方法中调用parent的removeChild()方法,把活动从流程模型中删除。

CutAction类是调用命令的类,这个类继承了org.eclipse.gef.ui.actions.SelectionAction,在这个类的run()方法中新建了CutCommand和CompoundCommand对象,并且把CutCommand对象加入到CompoundCommand对象的commandList中,这样如果剪切多个活动,执行了多个CutCommand命令,但这些命令都放在commandList中,这样在用户开来,就是执行一个命令。

对照命令模式的结构图,CompoundCommand和CutCommand就相当于ConcreteCommand,WorkflowProcess相当于Reciever,而removeChild()方法就是Reciever的action()方法,而CutAction则同时扮演了Client和Invoker角色。

CutCommand类代码:

package com.example.workflow.commands;

import org.eclipse.gef.commands.Command;

import com.example.workflow.model.AbstractActivity;

import com.example.workflow.model.WorkflowProcess;

public class CutCommand extends Command{

private WorkflowProcess parent;

private AbstractActivity child;

public CutCommand(WorkflowProcess parent,AbstractActivity child){

super();

if (parent == null || child == null) {

throw new IllegalArgumentException();

}

this.parent = parent;

this.child = child;

setLabel("cut activity");

}

public boolean canExecute() {

return parent != null && child != null;

}

public void execute() {

redo();

}

public void redo() {

parent.removeChild(child);

}

public void undo() {

parent.addChild(child);

}

}

CutAction类代码:

package com.example.workflow.action;

import java.util.List;

import org.eclipse.gef.EditPart;

import org.eclipse.gef.commands.Command;

import org.eclipse.gef.commands.CompoundCommand;

import org.eclipse.gef.ui.actions.Clipboard;

import org.eclipse.gef.ui.actions.SelectionAction;

import org.eclipse.jface.resource.ImageDescriptor;

import org.eclipse.ui.IWorkbenchPart;

import org.eclipse.ui.actions.ActionFactory;

import com.example.workflow.Activator;

import com.example.workflow.commands.CutCommand;

import com.example.workflow.model.AbstractActivity;

import com.example.workflow.model.WorkflowProcess;

import com.example.workflow.parts.WorkflowProcessEditPart;

public class CutAction extends SelectionAction{

private List selectionList = null;

private Clipboard clipboard = null;

private WorkflowProcess workflowProcess;

public CutAction(IWorkbenchPart part) {

super(part);

setId(ActionFactory.CUT.getId());

setText("Cut");

setImageDescriptor(ImageDescriptor.createFromFile(Activator.class, "icons/cut.gif"));

}

public Clipboard getClipboard() {

return clipboard;

}

public void setClipboard(Clipboard clipboard) {

this.clipboard = clipboard;

}

public WorkflowProcess getWorkflowProcess() {

return workflowProcess;

}

public void setWorkflowProcess(WorkflowProcess workflowProcess) {

this.workflowProcess = workflowProcess;

}

protected boolean calculateEnabled() {

selectionList = super.getSelectedObjects();

if(selectionList.isEmpty() ||

(selectionList.size() == 1 && selectionList.get(0) instanceof WorkflowProcessEditPart)){

return false;

}

return true;

}

public void run() {

getClipboard().setContents(selectionList);

execute(createCutCommand());

}

private Command createCutCommand(){

CompoundCommand compoundCmd = new CompoundCommand();

for(int i=0;i<selectionList.size();i++){

EditPart part = (EditPart)selectionList.get(i);

CutCommand cmd = new CutCommand(getWorkflowProcess(),(AbstractActivity)part.getModel());

compoundCmd.add(cmd);

}

return compoundCmd;

}

}

WorkflowProcess类代码:

package com.example.workflow.model;

import java.util.ArrayList;

import java.util.List;

/**

* 流程模型,可以包含多个活动和转移模型

* @author Administrator

*

*/

public class WorkflowProcess extends ModelElement{

private static final long serialVersionUID = -5478693636480758659L;

/** Property ID to use when a child is added to this WorkflowProcess. */

public static final String CHILD_ADDED_PROP = "WorkflowProcess.ChildAdded";

/** Property ID to use when a child is removed from this WorkflowProcess. */

public static final String CHILD_REMOVED_PROP = "WorkflowProcess.ChildRemoved";

private List activities = new ArrayList();

/**

* Add a Activity to this WorkflowProcess.

* @param s a non-null Activity instance

* @return true, if the Activity was added, false otherwise

*/

public boolean addChild(AbstractActivity a) {

if (a != null && activities.add(a)) {

firePropertyChange(CHILD_ADDED_PROP, null, a);

return true;

}

return false;

}

/** Return a List of Activities in this WorkflowProcess. The returned List should not be modified. */

public List getChildren() {

return activities;

}

/**

* Remove a Activity from this WorkflowProcess.

* @param s a non-null Activity instance;

* @return true, if the Activity was removed, false otherwise

*/

public boolean removeChild(AbstractActivity a) {

if (a != null && activities.remove(a)) {

firePropertyChange(CHILD_REMOVED_PROP, null, a);

return true;

}

return false;

}

}

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
VirtualBox导入已安装好的操作系统的方法
VirtualBox导入已安装好的操作系统的方法1、修改UUID进入VirtualBox安装目录,运行VBoxManage修改UUID,命令运行如下:D:\\VirtualBoxVBoxManage.exe internalcommands setvdiuuid E:\\VirtualX
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
00_设计模式之语言选择
设计模式之语言选择设计模式简介背景设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。设计模式(Designpattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的
Wesley13 Wesley13
3年前
Java设计模式之命令模式
介绍命令模式是一种行为型设计模式。在命令模式中,所有的请求都会被包装成为一个对象。参考了一下其他关于命令模式的文章,其中有谈到说是可以用不同的请求对客户进行参数化。对这句话的理解是,因为将请求封装成为对象,所以客户的所有操作,其实就是多个命令类的对象而已,即参数化了。命令模式的最大的特点就是将请求的调用者与请求的最终执行者进行了解
Easter79 Easter79
3年前
SwiftUI 跨组件数据传递
作者:Cyandev,iOS和MacOS开发者,目前就职于字节跳动0x00前言众所周知,SwiftUI的开发模式与React、Flutter非常相似,即都是声明式UI,由数据驱动(产生)视图,视图也会与数据自动保持同步,框架层会帮你处理“绑定”的问题。在声明式UI中不存在命令式地让一个视图变成xxx
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这