转至元数据结尾
转至元数据起始

作者:王方舟

目录

1.               上下文菜单项 Action 注册

2.               工作流上下文菜单提供器

3.               根据不同类型节点的右击事件构建上下文菜单

4.               附录 GraphicalEditor 方法介绍

Data Studio 上下文菜单管理

B y 王方舟

              Data Studio 的工作流编辑器中,针对不同类型的节点,配置了不同的上下文菜单,并且实现了上下文菜单的动态构建。目前工作流当中的节点类型主要分为数据节点、算法节点、模型节点和可视化节点。其中,数据节点主要负责数据的读入、处理和处理结果表的预览;算法节点主要负责执行相应算法,读入数据并输出模型节点;模型节点以数据作为输入,输出包含预测结果的数据;可视化节点负责将输入数据转化成各式图表,对数据做可视化展现。

              不同类型节点的上下文菜单如下所示:

图表 1 数据节点菜单

图表 2 算法节点菜单

图表 3 可视化节点菜单

              本文将介绍 GEF 框架中的 EditorPart 上下文菜单创建流程,以及在 Data Studio 上的实践过程。

1.     上下文菜单项 Action 注册

RCP 程序的 EditorPart 中最常用主要是两类: TextEditor GraphicalEditor Eclipse Editor 就是一种 TextEditor ,而 Data Studio 中的 Editor 则是后者。

GraphicalEditor 隶属 GEF 框架,与大多数图形编辑框架类似, GEF 框架也是一种 MVC 框架,此外 GEF 提供了不同的编辑部分和图案类,供用户扩展。在 GraphicalEditor 中添加上下文菜单,首先要注册菜单项的各种 Action GraphicalEditor 类提供了 createAction 方法,注册编辑器中右键后需要展现的事件列表。父类中只提供了简单的撤销、恢复、全选、删除、保存这 5 个基本的 IAction ,如果要添加自定义 IAction ,则需要在子类里面覆写该方法,先调用父类的 createAction 方法,将父类的 5 个基本事件注册,再注册子类的事件到 ActionRegistery 对象中。

注册好的事件通过 createGraphicalViewer 方法,传给 WorkflowGraphicalViewerCreator 的实例,在其中的 createViewer 方法中,传递给 WorkflowContextMenuProvider 的上下文菜单提供器,提供注册事件列表,在该类中动态的构建上下文菜单。

 

2.     工作流上下文菜单提供器

工作流上下文菜单提供器中包含的成员有上述所说的事件注册列表、 WorkflowGraphicalViewerCreator 所创建的 GraphicalViewer 对象,以及鼠标右击事件的发生位置 Point ,在其继承自父类 ContextMenuProvider buildContextMenu 的方法里面,通过 ID 在传递的注册事件列表拿到对应的上下文菜单 IAction ,最终形成一个完整的菜单列表。

上下文菜单提供分组的功能,通过一个 GroupID 来创建一个 Separator 对象,该对象将添加到该分组 ID IAction 与其他 IAction 分隔开来,在 UI 上面体现为一条分隔线。

特别地, buildContextMenu 方法的参数为一个 IMenuManager 对象,调用该对象的 add 方法可以将 Separator 对象添加到菜单中,调用 remove 方法可以删除某个 ID IAction ,调用 appendToGroup 方法可以将 IAction 对象添加到指定分组中。

 

3.     根据不同类型节点的右击事件构建上下文菜单

那么 ContextMenuProvider 是如何根据不同的节点类型来构建不同的菜单实例的呢?在上节所说的 GraphicalViewer 对象,可以通过 getSelectedEditParts 方法拿到当前编辑器中被用户选中的 EditParts 对象列表,当用户使用 WorkflowSelectionTool 选中了多个 EditPart 对象时,理想状态下当然不能弹出多个上下文菜单,因此在这里会取该列表的第 1 EditPart 作为应显示其上下文菜单的载体,当然这在用户只选择了一个 EditPart 对象时是自然的。

拿到当前所选择的 EditPart 之后,只是拿到了在图形编辑器上 UI 的对象,如果要做模型的类型区分,那必须要通过 EditPart getModel 方法,拿到其中封装的模型,在 Data Studio 中,该模型对象是一个 NodeContainer 对象。

NodeContainer 在设计器中充当一层节点的容器封装,其中它的继承关系如下所示:

图表 4 NodeContainer继承关系

其中 WorkflowManager 为整个工作流中的节点集合类, SingleNodeContainer 用来表示一个节点的容器类, NativeNodeContainer 表示其本身只有一个节点,而 SubNodeContainer 中可能有多个节点,但在外部表现成一个节点(类似于一个元节点)。

特殊地,在 NativeNodeContainer 中,会封装一个 Node 对象,这个对象该容器类中封装的节点对象, getNode 之后再 getFactory 则会取到该节点对象的工厂类。

工厂类的子类从功能上区分了三种不同类型的节点,数据节点、算法节点和可视化节点的工厂类分别为 DataNodeFactory AlgorithmNodeFactory VizNodeFactory ,根据节点工厂类的类型,可以构建分支创建不同的上下文菜单。

 

4.     附录 GraphicalEditor 方法介绍

         createActions() ——为该编辑器创建操作,子类应该覆盖该方法以使用 ActionRegistery 创建并注册操作。

         getCommandStack() ——返回命令栈。

         getEditDomain() ——返回编辑域。

         initializeGraphicalViewer() ——覆盖以在 GraphicalViewer 创建后设置它的内容。

         setEditDomain(DefaultEditDomain) ——为该 EditorPart 设置 EditDomain

  • 无标签