GEF中文教程 自学笔记 3

目标:使HelloWorld label可以在XYLayout布局中自由移动和改变大小

 

控制器逻辑
模型发生改变(HelloWorld改变尺寸或位置)

--->产生请求(Request)
与GEF应用程序有关的事件,比如鼠标事件mouseUp,最终会被派发到EditDomain类去处理。EditDomain类使用active tool将低级事件(low-level events)转化为高级操作(higher-level operations),这些高级操作由org.eclipse.gef.Request来封装。PS:tool实现org.eclipse.gef.Tool接口,EditDomain类拥有一个active tool和一个default tool的引用,active tool默认为default tool,而default tool默认为selection tool。

--->请求发送给相应的EditPart
EditPart接口定义了getCommand方法,该方法负责创建一个Command来执行指定Request。但实际上创建Command的任务是委托(delegate)给EditPolicies的,EditPart不直接处理这个任务。

--->EditPart委托EditPolicies创建Command
查看AbstractEditPart的getCommand方法的实现可知,EditPart将创建Command的任务委托给了EditPolicies,即遍历所有已安装的EditPolicies,调用每个EditPolicy的getCommand方法(可能返回null,表示无对应操作),并把返回的Command组装起来(如果有多个Command就使用CompoundCommand)

--->执行Command实现请求
一般经由EditDomain通过取得CommandStack实例并调用其execute(Command)方法实现。CommandStack实现了redo/undo,核心算法就是同时维护了两个栈redoable和undoable。execute(Command)方法清空redoable栈,调用参数command的execute方法执行命令,最后把command压入undoable栈。undo()方法就是执行undoable栈弹出的command的undo()方法,并将该command压入redoable栈。redo()与undo()正好相反,它执行redoable栈弹出的command的redo()方法,并将该command压入undoable栈。

步骤
1. 创建edit policy
创建一个CustomXYLayoutEditPolicy,继承org.eclipse.gef.editpolicies.XYLayoutEditPolicy。

2. 安装edit policy到EditPart
在ContentsEditPart的createEditPolicies()方法中添加
    installEditPolicy(EditPolicy.LAYOUT_ROLE, new CustomXYLayoutEditPolicy());
EditPolicy.LAYOUT_ROLE是一个字符串常量,它指定了安装的edit policy的角色(Role)。一个EditPart可以安装很多edit policies,如果角色相同,那么就只有最后一个policy是有效的。理论上来说,角色可以是任何值,用EditPolicy的常量只是为了统一,清楚。

3. 创建Command
创建ChangeConstraintCommand用来处理改变约束条件(大小、位置)的请求。
public void execute() {
    helloModel.setConstraint(constraint);
}

4. 修改Edit Policy
接下来要做的是让我们创建的EditPolicy遇到改变约束条件的请求时,能正确的生成ChangeConstraintCommand去处理请求。
当我们移动HelloWorld label或改变它的大小时,会产生请求REQ_MOVE_CHILDREN或REQ_RESIZE_CHILDREN。对于这两种请求,XYLayoutEditPolicy的getCommand()方法最终都是调用createChangeConstraintCommand()创建Command。所以我们只要在CustomXYLayoutEditPolicy中重载createChangeConstraintCommand()方法,让它返回ChangeConstraintCommand即可。

5. 在模型中设置监听器
以上4步实现了控制器部分的逻辑,但是还没有完成所有的工作,因为模型虽然改变了,但是视图并不知道,所以要通知EditPart模型已经改变,再由EditPart改变视图。5、6两步就是为了实现监听机制。
我们要把模型定义为事件源,使用java.beans.PropertyChangeSupport类就可以完成这个任务。
为了把事件机制与模型剥离,我们需要创建一个基类AbstractModel来处理与监听有关的代码。

6. 在EditPart中注册监听器
EditPart需要在activate()方法中把自己注册为模型的监听器,在deactivate()方法中删除。同时EditPart要实现PropertyChangeListener接口,处理所有propertyChangeEvent。
同样创建一个基类EditPartWithListener来处理注册与删除监听器的代码。

7. Redo/Undo
让Command保存操作前的状态,undo时恢复原状态即可,而redo其实就是重新执行execute。

8. 增加Undo/Redo工具按钮
照做,最后要改ApplicationWorkbenchWindowAdvisor类的preWindowOpen()方法,configurer.setShowCoolBar(true),否则工具栏不显示。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值