原文链接:http://www.ibm.com/developerworks/cn/opensource/os-cn-zest/#ibm-pcon
此文为原本备份。
本文介绍了如何使用 Eclipse Visualization Toolkit(http://www.eclipse.org/gef/zest/)这个短小精悍的 Java 图形工具库来进行简单的工作流程图形化的应用开发。通过程序示例由浅入深,让读者在短时间内掌握 Zest 图形库的基本概念和实用开发技巧,学习本文,相信读者可以使用 Eclipse Visualization Toolkit 图形库为 Eclipse 或单独的程序开发出更加精彩和 UML 建模 ( 类图,对象关系图等 ),工作流程图形化表现相关的应用范例。
使用 Zest 开发应用程序,建议读者首先了解基本的 SWT(http://www.eclipse.org/swt/) 开发知识,在 DeveloperWorks 的网站上有许多和 SWT/JFace 相关的文章和教程,感兴趣的读者可以查找阅读。Zest的开发 SDK 可以从网站 (http://www.eclipse.org/gef/zest/) 下载。Zest SDK 需要依赖于 Draw2D,Zest 的网站上有整合所有内容的完整开发包供下载。Draw2D 主要作用是在 SWT 的画布 (Canvas) 上提供了一种轻量级呈现和布局管理功能。在开发环境中设置好所依赖的程序库 (org.eclipse.draw2d_Version.jar,org.eclipse.zest.core_Version.jar,org.eclipse.zest.layouts_Version.jar 和 swt.jar),就可以进行 Zest 程序的代码编写和编译开发了。
Zest(The Eclipse Visualization Toolkit) 是在 Eclipse 平台基础上开发的一套可视化图形构件集合,方便开发和 UML 相关的图形应用程序,但范围不限于 UML 相关的应用,也可以用来开发工作流程图形化建模,树状结构图等。本文的示例代码都是以开发简单工作流程图形建模为例子。
Zest 库是从 SWT 和 Draw2D 扩展开发而来,可以无缝的集成到 Eclipse 的应用当中。因为 Zest 是基于 SWT(JFace) 的,所以 Zest 遵循 Eclipse 平台视图 (View) 的相关标准和规范,可以很容易在开发 Eclipse 的各种视图应用当中被集成和扩展。
虽然 Eclipse 的图形编辑框架 (GEF, http://www.eclipse.org/gef/) 也能够开发出丰富的图形应用,但是基于 GEF 的应用程序无法脱离 Eclipse 平台而单独运行;而基于 Zest 的应用没有这个限制,可以作为独立的应用程序在存在,从而脱离庞大的 Eclipse 平台,让应用程序更加小巧和灵活。
Zest 库提供了如下几种最基本的组件。
- 图形节点 (GraphNode):最基本的包含某些特性的节点图形,例如颜色,大小,位置和标签等。
- 图形关联 (GraphConnections):存储关联两个节点之间关联关系的图形对象,也包含连线的一些属性信息,例如:连线的颜色,线条宽度等。
- 图形容器 (GraphContainer):图形容器和图形节点类似,包含图形节点的所有属性,但图形容器支持折叠和展开的行为特性。
- 图形 (Graph):一个容器,用来容纳图形节点,图形容器以及图形关联这些对象。
- 样式常量 (ZestStyles):Zest 库默认设置的一些系统常量,例如线形等 ( 实线,虚线 ...)
Zest 库也提供了布局管理器,通过布局管理器来决定图形当中的节点,关联等这些图形对象如何在屏幕上显示分布。
CompositeLayoutAlgorithm | 组合其他布局方法来设置图形显示 |
DirectedGraphLayoutAlgorithm | 以全部重叠的方式来设置图形显示 |
GridLayoutAlgorithm | 以网格的布局方式来设置图形显示 |
HorizontalLayoutAlgorithm | 以水平方式来设置图形显示 |
HorizontalShift | 以重叠的方式依次向右水平来设置图形显示 |
HorizontalTreeLayoutAlgorithm | 以水平树状方式来设置图形显示 |
RadialLayoutAlgorithm | 以放射状的布局来设置图形显示 |
SpringLayoutAlgorithm | 以相同关联长度,图形节点重叠最少来设置图形显示 |
TreeLayoutAlgorithm | 以垂直树状方式来设置图形显示 |
VerticalLayoutAlgorithm | 以垂直方式来设置图形的显示 |
用户也可以开发自定义的布局管理器。
学习了 Zest 库当中的一些基本概念,就容易理解创建各种图形对象的类和方法,将这些图形对象通过合适的逻辑关系建立联系,就可以开发出一个简单的图形显示程序。
通常使用如下的构造函数来创建一个图形节点对象,需要传入 3 个参数。
GraphNode(IContainer graphModel, int style, String text)
各个参数的含义分别是:
设置图像节点对象所在的图形 (Graph) 对象,就是设置在哪个对象上面显示。
设置图形节点的风格,就是节点要显示成为什么样子。
设置图形节点上的标签,就是节点上要显示什么文字内容。
图形节点对象当中包含一系列的 setXX() 方法,通过这些方法,可以设置节点的大写,位置,颜色,字体等等。
创建节点关联对象只有一个构造函数,需要传入 4 个参数。
GraphConnection(Graph graphModel, int style, GraphNode source, GraphNode destination)
各个参数的含义分别是:
设置节点关联对象所在的图形 (Graph) 对象,就是设置在哪个对象上面显示。
设置节点关联的风格,就是节点关联要显示成为什么样子。
设置关联的源节点对象,从哪个节点开始。
设置关联的目标节点对象,到哪个节点结束。
节点关联对象的属性设置方法如下所示:
知道了如何创建节点对象和节点关系对象,就可以轻松创建出第一个基于 Zest 的程序。一个最简单的工作流程图形化建模程序,包含一个开始 (Start) 节点,一个结束 (End) 节点和两者之间的一条连线。
import org.eclipse.zest.core.widgets.Graph; import org.eclipse.zest.core.widgets.GraphConnection; import org.eclipse.zest.core.widgets.GraphNode; import org.eclipse.zest.layouts.LayoutStyles; import org.eclipse.zest.layouts.algorithms.SpringLayoutAlgorithm; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class FirstZest { public static void main(String[] args) { // SWT Display display = new Display(); Shell shell = new Shell(display); shell.setText("First Zest Program Demo"); shell.setLayout(new FillLayout()); shell.setSize(300, 300); // 创建 Graph Graph graph = new Graph(shell, SWT.NONE); // 创建一个图形节点 GraphNode startNode = new GraphNode(graph, SWT.NONE, "Start"); // 创建另外一个图形节点 GraphNode endNode = new GraphNode(graph, SWT.NONE, "End"); // 创建节点关联 new GraphConnection(graph, SWT.NONE, startNode, endNode); // 设置布局管理器 graph.setLayoutAlgorithm(new SpringLayoutAlgorithm( LayoutStyles.NO_LAYOUT_NODE_RESIZING), true); // 显示 SWT shell.open(); while (!shell.isDisposed()) { while (!display.readAndDispatch()) { display.sleep(); } } } } |
通过简单的几行代码,就创建了 2 个图形节点,并在它们之间建立了关联。你会发现,任何一个图形节点可以随意的通过鼠标拖动,而且连线也会随着节点的移动而移动。把很多复杂的功能的实现进行了封装和屏蔽。代码简单,但是功能强大。
也很容易的通过设置图形节点和节点关联的风格,来改变显示的样子。
Graph graph = new Graph(shell, SWT.NONE); // 设置连线风格 graph.setConnectionStyle(ZestStyles.CONNECTIONS_DIRECTED); // 设置图像 Image startIcon = new Image(display,"StartIcon.png"); // 创建图形节点 GraphNode startNode = new GraphNode(graph, SWT.NONE, "Start", startIcon); |
显示的效果如下图所示:
为了美化这个最简单的工作流程图形化建模程序,给连线增加了箭头,给图形节点增加了图标。
Zest 库当中组件的行为也是通过事件的方式进行驱动的。用户可以通过键盘,鼠标来操作 Zest 的图形组件,通过触发相应的事件来完成用户期望的业务行为。Zest 库的事件模型和编程方式和 SWT 是完全相同的。
对于图形节点 (GraphNode) 和图形关联 (GraphConnection) 对象可以通过调用下面的方法
addListener (int eventType, Listener listener)
为对象注册相应的事件,当这个事件发生的时候,就会触发相应的操作。具体的用法和接口参数可以参考 SWT 的文档。
对于图形 (Graph) 对象 Zest 提供了更多和更便利的事件使用注册方法。
下面通过代码来演示一下,在图形当中,当某个对象被选中的事件发生的时候,如何来触发特定的逻辑。
当某个对象被选中的时候,通过调用 addSelectionListener() 方法来注册事件。
// 创建 Graph Graph graph = new Graph(shell, SWT.NONE); // 注册对象选择侦听事件 graph.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { List selection = ((Graph) e.widget).getSelection(); // 确认只选择了一个对象 if (selection.size() == 1) { Object o = selection.get(0); // 图形节点对象 if (o instanceof GraphNode) { // 改变边线宽度 ((GraphNode) o).setBorderWidth(3); // 图形关联对象 } else if (o instanceof GraphConnection) { // 改变连线宽度 ((GraphConnection) o).setLineWidth(3); } } } }); |
工作流程图形化建模程序的运行效果进行美化,当图形节点或者图形关联被选中的时候,边线会被自动加粗。
Zest 库已经提供了多种图形显示的布局管理方式,需要用户根据图形应用的具体的情况来选择合适的布局管理算法。如果在程序当中没有设置任何布局管理,那么所有的图形节点和图形关联对象都将重合在一起。
下面分别给出了 Zest 当中常用布局管理的显示效果。
清单 4. 常用布局管理代码示例
Graph graph = new Graph(shell, SWT.NONE); graph.setConnectionStyle(ZestStyles.CONNECTIONS_DIRECTED); for (int i = 0; i < 10; i++) { GraphNode node1 = new GraphNode(graph, ZestStyles.NODES_FISHEYE, "Begin"); GraphNode node2 = new GraphNode(graph, ZestStyles.NODES_FISHEYE, "Middle"); GraphNode node3 = new GraphNode(graph, ZestStyles.NODES_FISHEYE, "Finish"); new GraphConnection(graph, SWT.NONE, node1, node2); new GraphConnection(graph, SWT.NONE, node2, node3); } graph.setLayoutAlgorithm(new GridLayoutAlgorithm( LayoutStyles.NO_LAYOUT_NODE_RESIZING), true); /* graph.setLayoutAlgorithm(new SpringLayoutAlgorithm( LayoutStyles.NO_LAYOUT_NODE_RESIZING), true); graph.setLayoutAlgorithm(new RadialLayoutAlgorithm( LayoutStyles.NO_LAYOUT_NODE_RESIZING), true); graph.setLayoutAlgorithm(new TreeLayoutAlgorithm( LayoutStyles.NO_LAYOUT_NODE_RESIZING), true); graph.setLayoutAlgorithm(new DirectedGraphLayoutAlgorithm( LayoutStyles.NO_LAYOUT_NODE_RESIZING), true); */ |
布局显示的效果依次为 Gridlayout, SpringLayout, Radialayout, TreeLayout 和 DirectedFraphLayout。
除了系统内置的布局管理器,Zest 也支持自定义的布局管理器。要实现自定义的布局管理器需要继承一个抽象类 AbstractLayoutAlgorithm。这个抽象类当中,要实现 7 个抽象方法,它们的名称和作用分别是:
void setLayoutArea()
设置布局的区域
boolean isValidConfiguration()
判断对于当前的布局配置是否正确
void applyLayoutInternal(InternalNode[] entitiesToLayout, InternalRelationship[] relationshipsToConsider, double boundsX, double boundsY, double boundsWidth, double boundsHeight)
把给定的对象进行布局,需要布局的对象会按照设定的算法被重新排列。这是最核心的一个方法。各个参数的含义分别是:
InternalNode[] entitiesToLayout:需要重新布局的对象数组
InternalRelationship[] relationshipsToConsider:重新布局对象之间关系的数组
double boundsX:布局区域可以放置对象的横 (X) 坐标开始位置
double boundsY:布局区域可以放置对象的纵 (Y) 坐标开始位置
double boundsWidth:布局区域的宽度
double boundsHeight:布局区域的高度
void preLayoutAlgorithm()
新布局算法之前调用的方法
postLayoutAlgorithm()
新布局算法之后调用的方法
getTotalNumberOfLayoutSteps()
获取布局当中总的步骤
int getCurrentLayoutStep()
获取当前的布局步骤
下面演示一个自定义的布局算法,让所有图形节点按照水平方式以相同间隔依次排列。
Graph graph = new Graph(shell, SWT.NONE); graph.setConnectionStyle(ZestStyles.CONNECTIONS_DIRECTED); GraphNode node1 = new GraphNode(graph, SWT.NONE, "Node 1"); GraphNode node2 = new GraphNode(graph, SWT.NONE, "Node 2"); GraphNode node3 = new GraphNode(graph, SWT.NONE, "Node 3"); new GraphConnection(graph, SWT.NONE, node1, node2); new GraphConnection(graph, SWT.NONE, node2, node3); graph.setLayoutAlgorithm(new AbstractLayoutAlgorithm(SWT.NONE) { int totalNodes; protected void applyLayoutInternal(InternalNode[] entitiesToLayout, InternalRelationship[] relationshipsToConsider, double boundsX, double boundsY, double boundsWidth, double boundsHeight) { // 需要布局的对象数量 totalNodes = entitiesToLayout.length; // 设置固定间隔距离 double spcaing = 100; // 开始位置坐标 int startX = 10; // 触发布局进程 fireProgressStarted(totalNodes); // 循环所有对象,按照设定的布局算法来排列对象 for (int curNode = 0; curNode < entitiesToLayout.length; curNode++) { LayoutEntity layoutEntity = entitiesToLayout[curNode] .getLayoutEntity(); // 设置一个对象显示的位置 layoutEntity.setLocationInLayout(startX, layoutEntity .getYInLayout()+10); // 保持相同的间隔 startX += spcaing; // 让对象在新位置上显示 fireProgressEvent(curNode, totalNodes); } // 结束布局进程 fireProgressEnded(totalNodes); } protected int getCurrentLayoutStep() { return 0; } protected int getTotalNumberOfLayoutSteps() { return totalNodes; } protected boolean isValidConfiguration(boolean asynchronous, boolean continuous) { return true; } protected void postLayoutAlgorithm(InternalNode[] entitiesToLayout, InternalRelationship[] relationshipsToConsider) { } protected void preLayoutAlgorithm(InternalNode[] entitiesToLayout, InternalRelationship[] relationshipsToConsider, double x, double y, double width, double height) { } public void setLayoutArea(double x, double y, double width, double height) { } }, true); |
下面是一些 Zest 开发当中小技巧的代码示例。
在 Zest 当中,图形节点的默认形状是矩形的,其实可以根据需求,来更改节点的默认形状,可变成为圆形,方形或者菱形等等。下面的示例是将图形节点的形状显示为椭圆。
需要创建用户自定义的图形节点,一般来说需要继承 CGraphNode 这个类
清单 5. 自定义图形节点 EllipseGraphNode 代码示例
import org.eclipse.draw2d.IFigure; import org.eclipse.zest.core.widgets.CGraphNode; import org.eclipse.zest.core.widgets.IContainer; public class EllipseGraphNode extends CGraphNode { public EllipseGraphNode(IContainer graphModel, int style, IFigure figure) { super(graphModel, style, figure); } } |
同时也需要继承 Figure 这个类
清单 6. 自定义图形节点 EllipseFigure 的代码示例
import org.eclipse.draw2d.ColorConstants; import org.eclipse.draw2d.Figure; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.Label; import org.eclipse.draw2d.LineBorder; import org.eclipse.draw2d.ToolbarLayout; import org.eclipse.draw2d.geometry.Rectangle; public class EllipseFigure extends Figure { public EllipseFigure(String name) { // 定义显示名称 Label label = new Label(name); // 定义图形节点的显示布局 ToolbarLayout layout = new ToolbarLayout(); setLayoutManager(layout); setBorder(new LineBorder(ColorConstants.white, 1)); setOpaque(true); add(label); } // 重写这个方法,实现自己需要显示的图形,更多的信息可以参考 Zest 的源代码 @Override public void paint(Graphics graphics) { super.paint(graphics); // 获取默认的矩形信息 Rectangle rectangle = getBounds().getCopy(); graphics.setLineWidth(2); // 画椭圆 graphics.drawOval(rectangle); } } |
同时简要修改一下主程序,在程序当中添加一个新的方法,用来创建椭圆图形对象 .
清单 7. 创建 EllipseFigure 对象的代码示例
// 创建 EllipseFigure 对象的方法 private static IFigure createEllipseFigure(String name) { EllipseFigure circleFigure = new EllipseFigure(name); circleFigure.setSize(-1, -1); return circleFigure; } GraphNode endNode = new GraphNode(graph, SWT.NONE, "End", stopIcon); // 创建椭圆图形节点对象 EllipseGraphNode ellipseNode = new EllipseGraphNode(graph, SWT.NONE, createEllipseFigure("ellipse")); // 创建节点关联 new GraphConnection(graph, SWT.NONE, startNode, ellipseNode); new GraphConnection(graph, SWT.NONE, ellipseNode, endNode); |
运行程序得到如下的显示效果。在开始节点和结束节点之间增加了一个椭圆形的节点。
Zest 图形 (Graph) 当中默认所有的组件对象都是可以被用户拖动。某些情况下,希望把某个元素固定不动,不可以被用户随意改变位置,实现的方法可以参考如下的代码:
清单 8. 禁止图形节点 (GraphNode) 被移动的代码示例
// 创建 Graph Graph graph = new Graph(shell, SWT.NONE); // 设置事件分发 graph.getLightweightSystem().setEventDispatcher( new SWTEventDispatcher() { @Override public void dispatchMouseMoved(MouseEvent me) { List selection = ((Graph) me.widget).getSelection(); for (Iterator iterator = selection.iterator(); iterator.hasNext();) { Object object = (Object) iterator.next(); if (object instanceof GraphNode) { String nodeName = ((GraphNode) object).getText(); if ("Start".equalsIgnoreCase(nodeName)) { // 如果是 Start 图形节点,就无法被移动 } else { // 其他图形节点,不受影响 super.dispatchMouseMoved(me); } } } } }); |
这样显示名字为 Start 的图形节点就无法被用户移动,而其他工作节点不受任何影响。
关于 Zest 的开发入门介绍到此就结束了,希望本篇文章能够对您的了解 Zest 库的使用和编程开发有所帮助和启发。
学习
- 参考 Zest官方站点,查看 Zest 的最新信息。
- 查看文章“SWT 全接触”,了解 SWT 的开发入门。
- 访问 developerWorks Open source 专区获得丰富的 how-to 信息、工具和项目更新以及 最受欢迎的文章和教程,帮助您用开放源码技术进行开发,并将它们与 IBM 产品结合使用。
- 随时关注 developerWorks 技术活动和 网络广播。
讨论
- 欢迎加入 My developerWorks 中文社区。
相关推荐
Zest提供了丰富的图形表示和交互方式,为开发者提供了强大的图形界面设计能力。 在这个压缩包中,"GEF-zest-3.7.1"是GEF-Zest的一个特定版本,可能包含了针对3.7.1版本Eclipse平台的优化和增强。这个版本的GEF-Zest...
ZBS.Zest库可能包含了各种Python类、函数和模块,它们可能涉及到了特定领域的功能,例如网络爬虫、数据分析、机器学习、图形界面等。具体的功能和用法需要查看库的文档或者阅读源代码来了解。如果压缩包内包含README...
GEF-zest-3.6.1.zipGEF-zest-3.6.1.zipGEF-zest-3.6.1.zipGEF-zest-3.6.1.zipGEF-zest-3.6.1.zipGEF-zest-3.6.1.zip
Zest Creator 工具,用于创建有效的 zest 脚本并通过辅助方法与脚本交互。 使用 安装它: ```bash $ npm i zest-creator ``` 需要它并使用: ```js var ZestCreator = require('zest-creator'); var opts = { ...
"Web应用程序的VueJS和TypeScript"意味着项目的前端部分是基于Vue.js,这是一个轻量级的JavaScript框架,以其可学习性、组件化和灵活性而受到广泛欢迎。Vue.js允许开发者构建用户界面,并与后端API进行通信。而...
将新标签转变为消费营销知识的强大平台---面向营销人员的知识构建平台:Zest结合了社区管理和AI来提供您所需的高级技能内容Zest确保您仅收到高质量的营销内容并杀死他们浪费您时间的信息过载使Zest脱颖而出的原因是...
在给定的压缩包中,我们有两个与Eclipse插件和图形编辑框架(GEF)相关的PDF文档,这些文档是学习和理解Eclipse生态系统的重要资源。 首先,"Eclipse Plug-ins Third Edition Dec. 2008.pdf"这本书籍可能涵盖了...
在Java世界中,JQF(Java QuantiFiable Fuzzing)是一个开源框架,它提供了高级的模糊测试工具,尤其是Zest Coverage Guided Fuzzer。这个框架结合了模糊测试和代码覆盖率分析,从而能够更有效地探索代码路径,发现...
标题中的“西数WDC WD3200BPVT固件-80ZEST0-板号1672-WD-WXB1AC064983-01.01A01-0015002M-256-1091-KL”涉及到的是西部数据(Western Digital,简称WD)的一款硬盘,具体型号为WD3200BPVT。固件是硬盘的重要组成部分...
语言:English Zest New Tab可帮助营销人员发现新鲜的营销内容以支持其工作,这些内容均由营销人员社区贡献。 Zest New Tab可帮助发现由长期的营销专家...通过向Zest提供内容,成员可以在同行之间以及行业内扩大影响力。
Zest提供了一组定义明确的工具包,可以处理这些事情,使您可以专注于构建应用程序。 Zest框架的目的对于PHP,当今有许多可用PHP框架,因此提出了一个问题,即为什么我们应该使用ZestFramework。 Zest框架的主要目的...
每个任务的JSON都有一个提供任务说明的question键和一个提供该任务examples键。 训练和验证在每个示例中都有标签,而测试则没有。 例如: { "question": "After leaving office, where did this president go to ...
语言:English 对Zendesk票证进行颜色编码,以帮助可视化和组织您的工作流程。 内文·乔治(Nevin George)开发 ...也可以考虑通过paypal.me/NevGZCC为我提供支持(完全可选,此扩展将对所有用户免费提供)。
Zest使可通过任何浏览器选项卡访问的通用云服务上存储的任何文档,文件或记录 您手上的所有文件。 通过在已经使用的工具中交付所需的文件,使Zest Assistant更加高效。 一个虚拟屋顶下的所有文件只需连接您的信息源...
Zest 脚本的运行时。 使用 安装它: ```bash $ npm i zest-runner ``` 需要它并使用: ```js var ZestRunner = require('zest-runner'); var opts = { sourceType: 'file', file: 'abc.zst' }; var zr = new ...
ZeST是用于强调文件系统/磁盘的TUI程序。 仅对curses起作用,它可在任何POSIX系统上使用。 它为IPC使用fork()和一个命名的fifo。 如果一个进程启动太多,则可以终止单个进程,这不会中断测试。
学习GEF时,可以参考官方文档和各种在线教程,通过实际项目来理解和应用这些概念。例如,创建一个简单的流程图编辑器或UML图编辑器。 **7. 扩展和集成** GEF可以与其他Eclipse插件集成,如Zest(用于图可视化)和...
官方文档是学习GEF的重要资源,它详细介绍了GEF架构、主要组件、设计模式以及API用法。文档通常分为入门指南、开发者指南和技术参考三部分,涵盖了从基础知识到高级特性的全面内容。阅读官方文档有助于深入理解GEF的...
因此,t4sg-zest.ai-skel很可能是基于Python的AI开发框架,可能集成了像TensorFlow、PyTorch这样的深度学习库,或者是专门为这些库提供便捷接口和抽象层的工具。 【压缩包子文件的文件名称列表】: t4sg-zest.ai-...