Eclipse Zest是一个可视化的图形工具。它基于SWT/Draw2D。Zest还支持JFace中Viewer的概念,因此允许模型和视图的分离。这篇文章假设你已经熟悉了Eclipse RCP或Eclipse Plugin开发。
(我注:其实也可以在一个普通的SWT程序中使用Zest)
Eclipse Zest有以下组件:
Zest提供了一些布局管理器,用来决定怎么布局graph上的结点。下面列出的就是所提供的一些布局:
TreeLayoutAlgorithm | Graph is displayed in the form of a vertical tree |
HorizontalTreeLayoutAlgorithm | Similar to TreeLayoutAlgorithm, but layout is horizontal |
RadialLayoutAlgorithm | Root is the center, the others nodes are placed around this node |
GridLayoutAlgorithm SpringLayoutAlgorithm |
layout the graph, so that all connections should have approx the same length and that the edges overlap minimal |
HorizontalShift | move overlapping nodes to the right |
CompositeLayoutAlgorithm | combines other layout algorithms, for example, HorizontalShift can be the second layout algorithm to move nodes which were still overlapping if another algorithm is used. |
可以通过调用setFilter(filter)方法,在布局上增加过滤器(org.eclipse.zest.layouts.filter),用于决定哪些结点和边线是可见的。filter收到一个LayoutItem对象,实际的graph结点可以通过方法getGraphData()得到。
(我注:好像现在安装完GEF后,自动就有了,所以这里略了)
3.1 开始
创建一个Eclipse RCP应用“de.vogella.zest.first”。选择模板"Eclipse RCP with a view“。 增加"org.eclipse.zest.core" 和 "org.eclipse.zest.layouts" 依赖项。
修改"View.java"的代码如下,用于创建一个简单的graph和连接它的元素:
package de.vogella.zest.first; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.part.ViewPart; 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.core.widgets.ZestStyles; import org.eclipse.zest.layouts.LayoutStyles; import org.eclipse.zest.layouts.algorithms.SpringLayoutAlgorithm; import org.eclipse.zest.layouts.algorithms.TreeLayoutAlgorithm; public class View extends ViewPart { public static final String ID = "de.vogella.zest.first.view"; private Graph graph; private int layout = 1; public void createPartControl(Composite parent) { // Graph will hold all other objects graph = new Graph(parent, SWT.NONE); // Now a few nodes GraphNode node1 = new GraphNode(graph, SWT.NONE, "Jim"); GraphNode node2 = new GraphNode(graph, SWT.NONE, "Jack"); GraphNode node3 = new GraphNode(graph, SWT.NONE, "Joe"); GraphNode node4 = new GraphNode(graph, SWT.NONE, "Bill"); // Lets have a directed connection new GraphConnection(graph, ZestStyles.CONNECTIONS_DIRECTED, node1, node2); // Lets have a dotted graph connection new GraphConnection(graph, ZestStyles.CONNECTIONS_DOT, node2, node3); // Standard connection new GraphConnection(graph, SWT.NONE, node3, node1); // Change line color and line width GraphConnection graphConnection = new GraphConnection(graph, SWT.NONE, node1, node4); graphConnection.changeLineColor(parent.getDisplay().getSystemColor( SWT.COLOR_GREEN)); // Also set a text graphConnection.setText("This is a text"); graphConnection.setHighlightColor(parent.getDisplay().getSystemColor( SWT.COLOR_RED)); graphConnection.setLineWidth(3); graphConnection.addListener(SWT.SELECTED, new Listener() { @Override public void handleEvent(Event event) { System.out.println("Selected"); } }); graph.setLayoutAlgorithm(new SpringLayoutAlgorithm( LayoutStyles.NO_LAYOUT_NODE_RESIZING), true); } public void setLayoutManager() { switch (layout) { case 1: graph.setLayoutAlgorithm(new TreeLayoutAlgorithm( LayoutStyles.NO_LAYOUT_NODE_RESIZING), true); layout++; break; case 2: graph.setLayoutAlgorithm(new SpringLayoutAlgorithm( LayoutStyles.NO_LAYOUT_NODE_RESIZING), true); layout = 1; break; } } /** * Passing the focus request to the viewer's control. */ public void setFocus() { } }
运行以后,得到下图:
创建一个command,并把以下"de.vogella.zest.first.handler.ChangeLayout"作为它的handler,此handler用于更改布局。最后把这个command加到一个menu上:
package de.vogella.zest.first.handler; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.ui.IViewPart; import org.eclipse.ui.handlers.HandlerUtil; import de.vogella.zest.first.View; public class ChangeLayout extends AbstractHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException { IViewPart findView = HandlerUtil.getActiveWorkbenchWindow(event) .getActivePage().findView("de.vogella.zest.first.view"); View view = (View) findView; view.setLayoutManager(); return null; } }
运行应用,如果你选择了上面的菜单,视图的布局将会改变
JFace提供了viewers用于分离数据和展现。请看Eclipse JFace TableViewer 或 Eclipse JFace TreeViewer 。JFace要求一个content provider和一个label provider。Zest提供了一个"GraphViewer“作为一个viewer。content provider则是基于connections或者是nodes的。
标准的Zest content providers有:
IGraphContentProvider | Based on the connections. The connections contain the information which nodes they refer to. Cannot display nodes without connections. |
IGraphEntityContentProvider | Based on the Node which contain the information about which relationship they have. These relationship are available in the label provider as EntityConnectionData objects. |
IGraphEntityRelationshipContentProvider | Node based, the content provider defines getRelationShips(sourceNode, destinationNode) which determines the connections. The advantages compared with IGraphEntityContentProvider is that you decide which objects you return. |
Zest的label provider可以是一个标准的JFace的 ILabelProvider,也可以是Zest特定的IEntityStyleProvider。