流程设计器开发五(转移的增加和删除部分)
2007-03-17 19:54
459 查看
哪个模型的控制器能接受在活动之间建立转移的请求呢,只有活动模型的控制器了,因为活动模型中维护着活动的输入和输出转移的列表,在活动控制器增加策略,使该控制器能接受建立转移的请求,代码如下:
[align=left]protectedvoid createEditPolicies() {[/align]
[align=left] //allow removal of the associated model element[/align]
[align=left] installEditPolicy(EditPolicy.COMPONENT_ROLE, new AbstractActivityComponentEditPolicy());[/align]
[align=left] //allow the creation of transitions and [/align]
[align=left] // and the reconnection of transitions between AbstractActivity instances[/align]
[align=left] installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new TransitionGraphicalNodeEditPolicy());[/align]
[align=left] [/align]
}
这里安装了TransitionGraphicalNodeEditPolicy策略,这个策略的代码如下:
package com.example.workflow.policy;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy;
import org.eclipse.gef.requests.CreateConnectionRequest;
import org.eclipse.gef.requests.ReconnectRequest;
import com.example.workflow.commands.TransitionCreateCommand;
import com.example.workflow.model.AbstractActivity;
public class TransitionGraphicalNodeEditPolicy extends GraphicalNodeEditPolicy{
protected Command getConnectionCompleteCommand(CreateConnectionRequest request) {
TransitionCreateCommand cmd =
(TransitionCreateCommand)request.getStartCommand();
cmd.setTarget((AbstractActivity)getHost().getModel());
return cmd;
}
protected Command getConnectionCreateCommand(CreateConnectionRequest request) {
AbstractActivity source = (AbstractActivity)getHost().getModel();
TransitionCreateCommand cmd = new TransitionCreateCommand(source);
request.setStartCommand(cmd);
return cmd;
}
protected Command getReconnectSourceCommand(ReconnectRequest request) {
// TODO Auto-generated method stub
return null;
}
protected Command getReconnectTargetCommand(ReconnectRequest request) {
// TODO Auto-generated method stub
return null;
}
}
这个类继承了GraphicalNodeEditPolicy,并且覆盖了getConnectionCreateCommand和getConnectionCompleteCommand,从这两个方法的字面意思就明白它们在什么时候执行,在getConnectionCreateCommand方法中,新建一个TransitionCreateCommand命令对象,并且把转移的起始活动放入该命令对象中,在getConnectionCompleteCommand方法中,得到在getConnectionCreateCommand方法中创建的命令,并且把转移的目标活动放入命令中。TransitionCreateCommand命令的代码如下:
package com.example.workflow.commands;
import java.util.Iterator;
import org.eclipse.gef.commands.Command;
import com.example.workflow.model.AbstractActivity;
import com.example.workflow.model.Transition;
public class TransitionCreateCommand extends Command{
/** The Transition instance. */
private Transition transition;
/** Start endpoint for the Transition. */
private final AbstractActivity source;
/** Target endpoint for the Transition. */
private AbstractActivity target;
public TransitionCreateCommand(AbstractActivity source){
if (source == null) {
throw new IllegalArgumentException();
}
setLabel("connection creation");
this.source = source;
}
public boolean canExecute() {
// disallow source -> source connections
if (source.equals(target)) {
return false;
}
// return false, if the source -> target connection exists already
for (Iterator iter = source.getSourceTransitions().iterator(); iter.hasNext();) {
Transition tran = (Transition) iter.next();
if (tran.getTarget().equals(target)) {
return false;
}
}
return true;
}
public void execute() {
// create a new transition between source and target
transition = new Transition(source, target);
}
public void redo() {
transition.reconnect();
}
public void setTarget(AbstractActivity target) {
if (target == null) {
throw new IllegalArgumentException();
}
this.target = target;
}
public void undo() {
transition.disconnect();
}
}
在这个命令中,用刚才放入的两个活动构建一个转移对象,其实通过代码我们知道最终执行的是在起始活动的输入转移列表中加入刚才新建的转移对象,在目标活动的输入转移列表中加入新建的转移对象。代码如下:
[align=left]void addTransition(Transition tran) {[/align]
[align=left] if (tran == null || tran.getSource() == tran.getTarget()) {[/align]
[align=left] thrownew IllegalArgumentException();[/align]
[align=left] }[/align]
[align=left] if (tran.getSource() == this) {[/align]
[align=left] sourceTransitions.add(tran);[/align]
[align=left] firePropertyChange(SOURCE_CONNECTIONS_PROP, null, tran);[/align]
[align=left] } elseif (tran.getTarget() == this) {[/align]
[align=left] targetTransitions.add(tran);[/align]
[align=left] firePropertyChange(TARGET_CONNECTIONS_PROP, null, tran);[/align]
[align=left] }[/align]
}
我们看到,向活动维护的转移列表中加入转移时,活动模型通知控制器它的SOURCE_CONNECTIONS_PROP和TARGET_CONNECTIONS_PROP属性发生变化了,因此在活动控制器中应该根据这两个属性来属性活动的视图,代码如下:
[align=left]publicvoid propertyChange(PropertyChangeEvent evt) {[/align]
[align=left] String prop = evt.getPropertyName(); [/align]
[align=left] if(AbstractActivity.SIZE_PROP.equals(prop) [/align]
[align=left] ||AbstractActivity.LOCATION_PROP.equals(prop)){[/align]
[align=left] refreshVisuals();[/align]
[align=left] }elseif(AbstractActivity.SOURCE_TRANSITIONS_PROP.equals(prop)){[/align]
[align=left] refreshSourceConnections();[/align]
[align=left] }elseif(AbstractActivity.TARGET_TRANSITIONS_PROP.equals(prop)){[/align]
[align=left] refreshTargetConnections();[/align]
[align=left] } [/align]
}
这里刷新的不是活动的视图,而是活动的输入和输入转移对应的视图。
只修改这些代码,还不能在编辑器中展示出新建的转移,还应该让活动控制器实现NodeEditPart接口,同时要实现这接口中的四个方法,代码如下:
private ConnectionAnchor anchor;
[align=left]protected ConnectionAnchor getConnectionAnchor(){[/align]
[align=left] if (anchor == null) {[/align]
[align=left] anchor = new ChopboxAnchor(getFigure());;[/align]
[align=left] }[/align]
[align=left] returnanchor;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart arg0) {[/align]
[align=left] return getConnectionAnchor();[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public ConnectionAnchor getSourceConnectionAnchor(Request arg0) {[/align]
[align=left] return getConnectionAnchor();[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart arg0) {[/align]
[align=left] return getConnectionAnchor();[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public ConnectionAnchor getTargetConnectionAnchor(Request arg0) {[/align]
[align=left] return getConnectionAnchor();[/align]
}
这四个方法就是实现转移和活动连接的锚点。
另外我们还要覆盖父类中的两个方法,得到活动模型维护的输入转移和输出转移,代码如下:
[align=left] protected List getModelSourceConnections() {[/align]
[align=left] return getCastedModel().getSourceTransitions();[/align]
[align=left] }[/align]
[align=left] protected List getModelTargetConnections() {[/align]
[align=left] return getCastedModel().getTargetTransitions();[/align]
}
这样我们就可以在活动之间建立转移了,效果下图:
这样我们就在两个活动之间建立了转移。那么如何删除转移呢,要删除活动之间的转移,应该在转移控制器中安装策略,代码如下:
[align=left]private Transition getCastedModel(){[/align]
[align=left] return (Transition)getModel();[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] protectedvoid createEditPolicies() {[/align]
[align=left] //Allows the removal of the transition model element[/align]
[align=left] installEditPolicy(EditPolicy.CONNECTION_ROLE, new ConnectionEditPolicy() {[/align]
[align=left] protected Command getDeleteCommand(GroupRequest request) {[/align]
[align=left] returnnew TransitionDeleteCommand(getCastedModel());[/align]
[align=left] }[/align]
[align=left] });[/align]
[align=left] [/align]
}
这里安装的是gef框架提供的策略,我们没有创建自己的策略,而是直接覆盖其中的getDeleteCommand,方法,在这个方法中新建了一个TransitionDeleteCommand命令,这个命令的代码如下:
package com.example.workflow.commands;
import org.eclipse.gef.commands.Command;
import com.example.workflow.model.Transition;
public class TransitionDeleteCommand extends Command {
/** Transition instance to disconnect. */
private final Transition transition;
public TransitionDeleteCommand(Transition tran) {
if (tran == null) {
throw new IllegalArgumentException();
}
setLabel("Transition deletion");
this.transition = tran;
}
public void execute() {
transition.disconnect();
}
public void undo() {
transition.reconnect();
}
}
这个类最终执行的其实活动模型中的removeTransition方法,从活动模型维护的转移列表中删除它,而此时活动模型通知控制器自己的SOURCE_CONNECTIONS_PROP和TARGET_CONNECTIONS_PROP属性发生变化了,要刷新视图,而这个我们在新建转移时,已经实现,因而这儿不用在实现了。这样运行程序,我们就可以删除活动之间的转移了。
接下来我们再给转移控制器安装一个策略,目的是当选择转移,转移有个反馈,给用户感觉是已经选择了转移,要不然,选择和不选择转移,效果一样,代码如下:
[align=left]protectedvoid createEditPolicies() {[/align]
[align=left] //Selection handle edit policy. [/align]
[align=left] // Makes the transition show a feedback, when selected by the user.[/align]
[align=left] installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE,[/align]
[align=left] new ConnectionEndpointEditPolicy());[/align]
[align=left] //Allows the removal of the transition model element[/align]
[align=left] installEditPolicy(EditPolicy.CONNECTION_ROLE, new ConnectionEditPolicy() {[/align]
[align=left] protected Command getDeleteCommand(GroupRequest request) {[/align]
[align=left] returnnew TransitionDeleteCommand(getCastedModel());[/align]
[align=left] }[/align]
[align=left] });[/align]
[align=left] }[/align]
下一节我们介绍如何在转移上新建,删除和移动拐点。
[align=left]protectedvoid createEditPolicies() {[/align]
[align=left] //allow removal of the associated model element[/align]
[align=left] installEditPolicy(EditPolicy.COMPONENT_ROLE, new AbstractActivityComponentEditPolicy());[/align]
[align=left] //allow the creation of transitions and [/align]
[align=left] // and the reconnection of transitions between AbstractActivity instances[/align]
[align=left] installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new TransitionGraphicalNodeEditPolicy());[/align]
[align=left] [/align]
}
这里安装了TransitionGraphicalNodeEditPolicy策略,这个策略的代码如下:
package com.example.workflow.policy;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy;
import org.eclipse.gef.requests.CreateConnectionRequest;
import org.eclipse.gef.requests.ReconnectRequest;
import com.example.workflow.commands.TransitionCreateCommand;
import com.example.workflow.model.AbstractActivity;
public class TransitionGraphicalNodeEditPolicy extends GraphicalNodeEditPolicy{
protected Command getConnectionCompleteCommand(CreateConnectionRequest request) {
TransitionCreateCommand cmd =
(TransitionCreateCommand)request.getStartCommand();
cmd.setTarget((AbstractActivity)getHost().getModel());
return cmd;
}
protected Command getConnectionCreateCommand(CreateConnectionRequest request) {
AbstractActivity source = (AbstractActivity)getHost().getModel();
TransitionCreateCommand cmd = new TransitionCreateCommand(source);
request.setStartCommand(cmd);
return cmd;
}
protected Command getReconnectSourceCommand(ReconnectRequest request) {
// TODO Auto-generated method stub
return null;
}
protected Command getReconnectTargetCommand(ReconnectRequest request) {
// TODO Auto-generated method stub
return null;
}
}
这个类继承了GraphicalNodeEditPolicy,并且覆盖了getConnectionCreateCommand和getConnectionCompleteCommand,从这两个方法的字面意思就明白它们在什么时候执行,在getConnectionCreateCommand方法中,新建一个TransitionCreateCommand命令对象,并且把转移的起始活动放入该命令对象中,在getConnectionCompleteCommand方法中,得到在getConnectionCreateCommand方法中创建的命令,并且把转移的目标活动放入命令中。TransitionCreateCommand命令的代码如下:
package com.example.workflow.commands;
import java.util.Iterator;
import org.eclipse.gef.commands.Command;
import com.example.workflow.model.AbstractActivity;
import com.example.workflow.model.Transition;
public class TransitionCreateCommand extends Command{
/** The Transition instance. */
private Transition transition;
/** Start endpoint for the Transition. */
private final AbstractActivity source;
/** Target endpoint for the Transition. */
private AbstractActivity target;
public TransitionCreateCommand(AbstractActivity source){
if (source == null) {
throw new IllegalArgumentException();
}
setLabel("connection creation");
this.source = source;
}
public boolean canExecute() {
// disallow source -> source connections
if (source.equals(target)) {
return false;
}
// return false, if the source -> target connection exists already
for (Iterator iter = source.getSourceTransitions().iterator(); iter.hasNext();) {
Transition tran = (Transition) iter.next();
if (tran.getTarget().equals(target)) {
return false;
}
}
return true;
}
public void execute() {
// create a new transition between source and target
transition = new Transition(source, target);
}
public void redo() {
transition.reconnect();
}
public void setTarget(AbstractActivity target) {
if (target == null) {
throw new IllegalArgumentException();
}
this.target = target;
}
public void undo() {
transition.disconnect();
}
}
在这个命令中,用刚才放入的两个活动构建一个转移对象,其实通过代码我们知道最终执行的是在起始活动的输入转移列表中加入刚才新建的转移对象,在目标活动的输入转移列表中加入新建的转移对象。代码如下:
[align=left]void addTransition(Transition tran) {[/align]
[align=left] if (tran == null || tran.getSource() == tran.getTarget()) {[/align]
[align=left] thrownew IllegalArgumentException();[/align]
[align=left] }[/align]
[align=left] if (tran.getSource() == this) {[/align]
[align=left] sourceTransitions.add(tran);[/align]
[align=left] firePropertyChange(SOURCE_CONNECTIONS_PROP, null, tran);[/align]
[align=left] } elseif (tran.getTarget() == this) {[/align]
[align=left] targetTransitions.add(tran);[/align]
[align=left] firePropertyChange(TARGET_CONNECTIONS_PROP, null, tran);[/align]
[align=left] }[/align]
}
我们看到,向活动维护的转移列表中加入转移时,活动模型通知控制器它的SOURCE_CONNECTIONS_PROP和TARGET_CONNECTIONS_PROP属性发生变化了,因此在活动控制器中应该根据这两个属性来属性活动的视图,代码如下:
[align=left]publicvoid propertyChange(PropertyChangeEvent evt) {[/align]
[align=left] String prop = evt.getPropertyName(); [/align]
[align=left] if(AbstractActivity.SIZE_PROP.equals(prop) [/align]
[align=left] ||AbstractActivity.LOCATION_PROP.equals(prop)){[/align]
[align=left] refreshVisuals();[/align]
[align=left] }elseif(AbstractActivity.SOURCE_TRANSITIONS_PROP.equals(prop)){[/align]
[align=left] refreshSourceConnections();[/align]
[align=left] }elseif(AbstractActivity.TARGET_TRANSITIONS_PROP.equals(prop)){[/align]
[align=left] refreshTargetConnections();[/align]
[align=left] } [/align]
}
这里刷新的不是活动的视图,而是活动的输入和输入转移对应的视图。
只修改这些代码,还不能在编辑器中展示出新建的转移,还应该让活动控制器实现NodeEditPart接口,同时要实现这接口中的四个方法,代码如下:
private ConnectionAnchor anchor;
[align=left]protected ConnectionAnchor getConnectionAnchor(){[/align]
[align=left] if (anchor == null) {[/align]
[align=left] anchor = new ChopboxAnchor(getFigure());;[/align]
[align=left] }[/align]
[align=left] returnanchor;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart arg0) {[/align]
[align=left] return getConnectionAnchor();[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public ConnectionAnchor getSourceConnectionAnchor(Request arg0) {[/align]
[align=left] return getConnectionAnchor();[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart arg0) {[/align]
[align=left] return getConnectionAnchor();[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public ConnectionAnchor getTargetConnectionAnchor(Request arg0) {[/align]
[align=left] return getConnectionAnchor();[/align]
}
这四个方法就是实现转移和活动连接的锚点。
另外我们还要覆盖父类中的两个方法,得到活动模型维护的输入转移和输出转移,代码如下:
[align=left] protected List getModelSourceConnections() {[/align]
[align=left] return getCastedModel().getSourceTransitions();[/align]
[align=left] }[/align]
[align=left] protected List getModelTargetConnections() {[/align]
[align=left] return getCastedModel().getTargetTransitions();[/align]
}
这样我们就可以在活动之间建立转移了,效果下图:
这样我们就在两个活动之间建立了转移。那么如何删除转移呢,要删除活动之间的转移,应该在转移控制器中安装策略,代码如下:
[align=left]private Transition getCastedModel(){[/align]
[align=left] return (Transition)getModel();[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] protectedvoid createEditPolicies() {[/align]
[align=left] //Allows the removal of the transition model element[/align]
[align=left] installEditPolicy(EditPolicy.CONNECTION_ROLE, new ConnectionEditPolicy() {[/align]
[align=left] protected Command getDeleteCommand(GroupRequest request) {[/align]
[align=left] returnnew TransitionDeleteCommand(getCastedModel());[/align]
[align=left] }[/align]
[align=left] });[/align]
[align=left] [/align]
}
这里安装的是gef框架提供的策略,我们没有创建自己的策略,而是直接覆盖其中的getDeleteCommand,方法,在这个方法中新建了一个TransitionDeleteCommand命令,这个命令的代码如下:
package com.example.workflow.commands;
import org.eclipse.gef.commands.Command;
import com.example.workflow.model.Transition;
public class TransitionDeleteCommand extends Command {
/** Transition instance to disconnect. */
private final Transition transition;
public TransitionDeleteCommand(Transition tran) {
if (tran == null) {
throw new IllegalArgumentException();
}
setLabel("Transition deletion");
this.transition = tran;
}
public void execute() {
transition.disconnect();
}
public void undo() {
transition.reconnect();
}
}
这个类最终执行的其实活动模型中的removeTransition方法,从活动模型维护的转移列表中删除它,而此时活动模型通知控制器自己的SOURCE_CONNECTIONS_PROP和TARGET_CONNECTIONS_PROP属性发生变化了,要刷新视图,而这个我们在新建转移时,已经实现,因而这儿不用在实现了。这样运行程序,我们就可以删除活动之间的转移了。
接下来我们再给转移控制器安装一个策略,目的是当选择转移,转移有个反馈,给用户感觉是已经选择了转移,要不然,选择和不选择转移,效果一样,代码如下:
[align=left]protectedvoid createEditPolicies() {[/align]
[align=left] //Selection handle edit policy. [/align]
[align=left] // Makes the transition show a feedback, when selected by the user.[/align]
[align=left] installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE,[/align]
[align=left] new ConnectionEndpointEditPolicy());[/align]
[align=left] //Allows the removal of the transition model element[/align]
[align=left] installEditPolicy(EditPolicy.CONNECTION_ROLE, new ConnectionEditPolicy() {[/align]
[align=left] protected Command getDeleteCommand(GroupRequest request) {[/align]
[align=left] returnnew TransitionDeleteCommand(getCastedModel());[/align]
[align=left] }[/align]
[align=left] });[/align]
[align=left] }[/align]
下一节我们介绍如何在转移上新建,删除和移动拐点。
相关文章推荐
- 流程设计器开发六(大纲视图部分)
- 流程设计器开发七(属性页部分)
- 流程设计器开发一(控制器和视图部分)
- 流程设计器开发八(新建向导部分)
- 流程设计器开发二(编辑器部分)
- 流程设计器开发三(策略和命令部分)
- 流程设计器开发四(改变活动的位置部分)
- 流程设计器开发一(模型部分)
- 流程设计器开发五(拐点部分)
- iOS开发:一个高仿美团的团购ipad客户端的设计和实现(功能:根据拼音进行检索并展示数据,离线缓存团购数据,浏览记录与收藏记录的批量删除等)
- 《游戏脚本的设计与开发》-(RPG部分)3.2 地图遮挡和人物行走
- 以增加收藏夹功能为实例,解析asp.net forums2结构流程及组件设计
- 办公管理支撑流程能力PaaS平台运维开发软件需求设计方案
- Java开发中的23个设计模式--第二部分:结构型模式
- iPhone开发 文件的增加删除查询
- 《游戏脚本的设计与开发》-(RPG部分)3.5 游戏背包和任务系统
- SharePoint无代码工作流设计开发实例——交通费报销流程(二)
- SharePoint无代码工作流设计开发实例——交通费报销流程(二)
- 开发中的Silverlight流程设计器
- 流程管理与流程快速开发平台设计思路