现在你已经知道如何进行图形化的显示,接下来就开始尝试图形编辑吧。图形编辑是 EditPart 提供的最复杂的功能,它不但要求对模型进行修改,同时需要与视图进行交互在界面上反馈修改的结果。 GEF 使用请求 (Request) 对交互的源进行抽象,工具和 UI 解释器创建请求并调用 EditPart 提供的 API 方法来完成交互。下面列出的是一些 EditPart 提供的 API 方法。
EditPart 中使用请求 (Request) 的方法为:
4. void performRequest(Request) |
1 | 编辑的第一步是确定关联的 EditPart , 通常情况下,它们会包括 Viewer 中选中的 EditPart 和当前鼠标位置处的 EditPart 。被选中的 EditPart 也会根据它们是否响应请求而进行调整,不响应请求的 EdiPart 将被忽略掉。 鼠标选中的 EditPart 称为目标 (Target) ,目标可以由 Viewer 的助手或者 getTargetEditPart(Request) 方法获取。注意并非所有的交互都有目标。 |
2 | 交互中,尤其是在鼠标动作响应的交互中, EditPart 需要根据自己的角色 (Role) 做出特定的反馈 (Feedback) 。正在被操作的 EditPart 称之为源 (Source) 。例如,当我们在图形中拖动一个节点时,这个节点就是源,而图形就是目标。节点需要根据拖动的结果做出源反馈 (Source Feedback) ,比如移动到另一个的位置、修改大小等。图形也要做出相应的目标反馈 (Target Feedback) 。另一种情况,当我们重置连接的端点时,节点可能就变成目标,这时候它要做出目标反馈,比如删除或者新建连接。注意一些交互操作可能只对源有影响,这时候只需要源作为反馈。 |
3 | 最终修改模型的是命令 (Command) ,对于指定的请求 EditPart 需要产生命令。命令同时也会用来辅助确定是否响应某个操作,如果没有对应的命令或者命令不能执行 (Not Executable) , UI 界面将提示无法响应这个操作。 EditPart 通过返回一个不可执行的命令来阻止某种操作,而不是将命令设置为 NULL ,后者不会阻止交互的发生。当然如果所有的 EditPart 都没有对应的命令,操作一样不会响应。 |
4 | 最后, GEF 提供了一些常见的 API 方法使 EditPart 响应一些操作,这些操作不会立刻影响到对象模型。比如打开一个对话框、启用直接编辑 (Direct-edit) 功能。 |
编辑策略 (EditPolicies)
EditPart 不会直接处理编辑操作,它们使用编辑策略来响应编辑操作。每一个编辑策略 (EditPolicy) 只负责一种编辑工作或者一组相关联的工作。 EditPolicy 被设计为可以在不同的 EditPart 上重用,另外,它们还可以动态的改变对编辑操作的处理动作,比如布局或者连接路径变化的时候,
当上面列举的任何一个编辑方法被调用的时候 ( 除了 performRequest()) , EditPart 将委托它的编辑策略去处理请求。 EditPart 可能会只让第一个编辑策略处理请求,也可能让所有的编辑策略都处理请求,这视方法的具体实现而定,详细参考方法的 API 说明。
在 EditPart 的创建过程中, createEditPolicies() 用来安装适当的编辑策略。编辑策略的安装需要指定角色 (Role) ,角色在 GEF 中无非就是一个身份标识而已。 GEF 内置了几种常用的角色,在 EditPart 需要移除或者调整编辑策略时,角色将变得非常重要。针对这些角色, GEF 也提供了几种常用的编辑策略,当然大部分编辑策略都是抽象类,需要用户自己实现某些方法。编辑策略会在交互 (Interactions) 一节详细讨论。
命令 (Commands)
命令在编辑的处理过程中被分发的各处,它们负责封装对应用模型的修改。
每个应用程序都由一个命令栈 (Command Stack) ,命令最好不要直接执行而是放在命令栈中再执行。命令栈将维护已经执行过的命令的重做 (Redo) 和撤销 (Undo) 等操作,直接执行的话你将无法使用这些特性。