上文提到的GEF工作过程中还有一些不太详细的地方,这里做些补充。
再GEF中UI的操作交互都是通过构建Request,并调用EditPart中的API来完成相应的操作,这些API可以分为四类:
1。 EditPart getTargetEditPart(Request)
boolean understandsRequest(Request)
再我们进行交互操作时,首先要确定激活的是那个EditPart,经常是一个当前被选中的viewer和通过单击选择的EditPart的复合体。这个被选择的部件通过询问每个被选择的EditPart是否处理这个request(通过understandsRequest方法)。那个在鼠标单击确定的EditPart是通过viewer的帮助和getTargetEditPart方法来找到的。并不是所有的交互都有target。
2。
void showSourceFeedback(Request)
void eraseSourceFeedback(Request)
void showTargetFeedback(Request)
void eraseTargetFeedback(Request)
在我们的交互操作特别是托拽图形时,就需要EditPart来回显(Feedback),托拽源被认为是起作用的那个editpart,目的部件被认为是鼠标的目的地。showXXXFeedback可能是在鼠标移到目的地,但未作用于目的part时调用,eraseXXXFeedback则可能是在鼠标作用于目的part后调用的。
3。Command getCommand(Request)
这个方法用于获得可执行的命令列表,命令可以对模型进行操作,Editpart通过request询问Editpolicy来获得相应的command列表。同时command也可以判断这个交互操作是否时可能的。如果没有command或者command不能执行,则ui会指出这个操作是不能执行的(鼠标变成禁止操作的样子)。如果一个editpart返回null作为command则它不会阻止这个交互操作,除非没有一个command被提供。为了指示某个操作是不能执行的则EditPart需要返回一个不能执行的command。
4。void performRequest(Request)
还有一种API,它让EditPart去do something,可能是一些并不会立即就改变model的改变,比如打开对话框或者激活直接编辑模式。
EditPart并不直接进行编辑,它将操作委托给EditPolicy,每个EditPolicy专著于一种编辑任务或者一组相关的操作。当上面的API被调用后(除了performRequest方法),EditPart便委托给它的EditPolicy来处理这个request。对于不同的方法,EditPart可能是在第一个能处理request的policy处就停止调用了或者每个policy都有机会执行这个request。GEF提供了几个默认的policy,不过还是需要实现其中的一些特定方法。
这里再废话一点,在注册相应的EditPolicy时,需要指定Role,这是一个字符串,用来标示这个EditPolicy,相同的Role对应的EditPolicy会被替换,例如子类可以通过Role这个Key来覆盖其父类所安装的EditPolicy。EditPolicy(Role)分成两种类型,一种是图形的,一种是非图形的,上文中有提到,这里详细的描述一下:
Non-Graphical Roles:
1) COMPONENT_ROLE: 一个Component存在于一个parent中,并且可以从parent中删除。更为一般的,它可以使任何只涉及到这个EditPart,而与View无关的东西。(More generally, it is anything that involves only this EditPart.)
2) CONNECTION_ROLE 这是ConnectionEditParts应该有的一个基本角色。Connections同Components有一点不同,删除Connections时通常还需要其从其source和target节点中删除,而不是从其parent中删除。
3) CONTAINER_ROLE 大部分拥有children的EditParts都应该具有这个角色。一个Container会涉及到adds/orphans以及creates/deletes等操作。
4) NODE_ROLE 如果一个EditParts用户Connection,则其应该具有这个角色,它可以用来创建,删除,重新连接一个Connection。
Graphical Roles:
1) PRIMARY_DRAG_ROLE: 用来允许用户拖动这个EditPart。用户可以通过点击这个EditPart然后拖动,或者点击这个EditPart所创建的一个Handle来进行拖动。
2) LAYOUT_ROLE: Layout角色用来放在一个Container的EditPart上,这个EditPart拥有一个graphical layout。如果这个layout有constraints,则它需要通过计算来得到这个constraints。
3) GRAPHICAL_NODE_ROLE: A node supports connections to terminals. When creating and manipulating connections, EditPolicies with this role might analyze a Request's data to perform "hit testing" on the graphical view and determine the semantics of the connection. 用于支持连接到重点的node,当创建、操作连接时,包含这个Role的Editpolicy会分析request的数据,来在图形view上做“hit testing”,并且判断这个connection的语义。
4) CONNECTION_ENDPOINTS_ROLE: 这个Role允许用户拖动一个ConnectionEditPart的端点。
5) CONNECTION_BENDPOINTS_ROLE: 这个Role允许用户能够在一个Connection中间拖动和创建bendpoints。
6) SELECTION_FEEDBACK_ROLE: 这个角色只是用来显示feedback。当鼠标进入或者在一个EditPart上暂停时,Selection Tool会发送两个类型的request给EditPart。安装了这个角色的EditPart能够在此时接受这些请求来改变view的样子,或者弹出tip,label等。
7) TREE_CONTAINER_ROLE: SWT Tree的Layout Role。 本地SWT Tree的Layout Role的等价物。这个EditPolicy应该在树上显示反馈并计算索引,就像在file explorer里拖拽一样。
over。