创建一个RCP应用"de.vogella.zest.jface",使用"RCP Application with a view"做为模板。增加zest的依赖项。修改Pespective.java如下:
package de.vogella.zest.jface; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPerspectiveFactory; public class Perspective implements IPerspectiveFactory { public void createInitialLayout(IPageLayout layout) { String editorArea = layout.getEditorArea(); layout.setEditorAreaVisible(false); layout.setFixed(true); layout.addView(View.ID, IPageLayout.LEFT, 1.0f, editorArea); }
}
创建以下模型:
package de.vogella.zest.jface.model; import java.util.ArrayList; import java.util.List; public class MyNode { private final String id; private final String name; private List<MyNode> connections; public MyNode(String id, String name) { this.id = id; this.name = name; this.connections = new ArrayList<MyNode>(); } public String getId() { return id; } public String getName() { return name; } public List<MyNode> getConnectedTo() { return connections; } }
package de.vogella.zest.jface.model;
public class MyConnection { final String id; final String label; final MyNode source; final MyNode destination; public MyConnection(String id, String label, MyNode source, MyNode destination) { this.id = id; this.label = label; this.source = source; this.destination = destination; } public String getLabel() { return label; } public MyNode getSource() { return source; } public MyNode getDestination() { return destination; } }
package de.vogella.zest.jface.model;
import java.util.ArrayList; import java.util.List; public class NodeModelContentProvider { private List<MyConnection> connections; private List<MyNode> nodes; public NodeModelContentProvider() { // Image here a fancy DB access // Now create a few nodes nodes = new ArrayList<MyNode>(); MyNode node = new MyNode("1", "Hamburg"); nodes.add(node); node = new MyNode("2", "Frankfurt"); nodes.add(node); node = new MyNode("3", "Berlin"); nodes.add(node); node = new MyNode("4", "Munich"); nodes.add(node); node = new MyNode("5", "Eppelheim"); nodes.add(node); node = new MyNode("6", "Ahrensboek"); nodes.add(node); connections = new ArrayList<MyConnection>(); MyConnection connect = new MyConnection("1", "1", nodes.get(0), nodes.get(1)); connections.add(connect); connect = new MyConnection("2", "2", nodes.get(0), nodes.get(4)); connections.add(connect); connect = new MyConnection("3", "3", nodes.get(2), nodes.get(1)); connections.add(connect); connect = new MyConnection("4", "3", nodes.get(1), nodes.get(3)); connections.add(connect); // Because we are lasy we save the info about the connections in the // nodes for (MyConnection connection : connections) { connection.getSource().getConnectedTo() .add(connection.getDestination()); } } public List<MyNode> getNodes() { return nodes; }}
创建以下content和label providers
package de.vogella.zest.jface.zestviewer; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.zest.core.viewers.IGraphEntityContentProvider; import de.vogella.zest.jface.model.MyNode; public class ZestNodeContentProvider extends ArrayContentProvider implements IGraphEntityContentProvider { @Override public Object[] getConnectedTo(Object entity) { if (entity instanceof MyNode) { MyNode node = (MyNode) entity; return node.getConnectedTo().toArray(); } throw new RuntimeException("Type not supported"); } }
package de.vogella.zest.jface.zestviewer;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.zest.core.viewers.EntityConnectionData;
import de.vogella.zest.jface.model.MyConnection;
import de.vogella.zest.jface.model.MyNode;
public class ZestLabelProvider extends LabelProvider {
@Override
public String getText(Object element) {
if (element instanceof MyNode) {
MyNode myNode = (MyNode) element;
return myNode.getName();
}
// Not called with the IGraphEntityContentProvider
if (element instanceof MyConnection) {
MyConnection myConnection = (MyConnection) element;
return myConnection.getLabel();
}
if (element instanceof EntityConnectionData) {
EntityConnectionData test = (EntityConnectionData) element;
return "";
}
throw new RuntimeException("Wrong type: "
+ element.getClass().toString());
}
}
修改view如下:
package de.vogella.zest.jface; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IActionBars; import org.eclipse.ui.part.ViewPart; import org.eclipse.zest.core.viewers.AbstractZoomableViewer; import org.eclipse.zest.core.viewers.GraphViewer; import org.eclipse.zest.core.viewers.IZoomableWorkbenchPart; import org.eclipse.zest.core.viewers.ZoomContributionViewItem; import org.eclipse.zest.layouts.LayoutAlgorithm; import org.eclipse.zest.layouts.LayoutStyles; import org.eclipse.zest.layouts.algorithms.TreeLayoutAlgorithm; import de.vogella.zest.jface.model.NodeModelContentProvider; import de.vogella.zest.jface.zestviewer.ZestLabelProvider; import de.vogella.zest.jface.zestviewer.ZestNodeContentProvider; public class View extends ViewPart implements IZoomableWorkbenchPart { public static final String ID = "de.vogella.zest.jface.view"; private GraphViewer viewer; public void createPartControl(Composite parent) { viewer = new GraphViewer(parent, SWT.BORDER); viewer.setContentProvider(new ZestNodeContentProvider()); viewer.setLabelProvider(new ZestLabelProvider()); NodeModelContentProvider model = new NodeModelContentProvider(); viewer.setInput(model.getNodes()); LayoutAlgorithm layout = setLayout(); viewer.setLayoutAlgorithm(layout, true); viewer.applyLayout(); fillToolBar(); } private LayoutAlgorithm setLayout() { LayoutAlgorithm layout; // layout = new // SpringLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING); layout = new TreeLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING); // layout = new // GridLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING); // layout = new // HorizontalTreeLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING); // layout = new // RadialLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING); return layout; } /** * Passing the focus request to the viewer's control. */ public void setFocus() { } private void fillToolBar() { ZoomContributionViewItem toolbarZoomContributionViewItem = new ZoomContributionViewItem( this); IActionBars bars = getViewSite().getActionBars(); bars.getMenuManager().add(toolbarZoomContributionViewItem); } @Override public AbstractZoomableViewer getZoomableViewer() { return viewer; } }
最后结果如下:
可以通过setFilter()来定义一个filter,例如:
package de.vogella.zest.jface.zestviewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import de.vogella.zest.jface.model.MyNode; public class NodeFilter extends ViewerFilter { @Override public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof MyNode) { MyNode node = (MyNode) element; return node.getName().toLowerCase().contains("a"); } return true; } }
把这个filter用在所有元素上:
package de.vogella.zest.jface; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IActionBars; import org.eclipse.ui.part.ViewPart; import org.eclipse.zest.core.viewers.AbstractZoomableViewer; import org.eclipse.zest.core.viewers.GraphViewer; import org.eclipse.zest.core.viewers.IZoomableWorkbenchPart; import org.eclipse.zest.core.viewers.ZoomContributionViewItem; import org.eclipse.zest.layouts.LayoutAlgorithm; import org.eclipse.zest.layouts.LayoutStyles; import org.eclipse.zest.layouts.algorithms.TreeLayoutAlgorithm; import de.vogella.zest.jface.model.NodeModelContentProvider; import de.vogella.zest.jface.zestviewer.NodeFilter; import de.vogella.zest.jface.zestviewer.ZestLabelProvider; import de.vogella.zest.jface.zestviewer.ZestNodeContentProvider; public class View extends ViewPart implements IZoomableWorkbenchPart { public static final String ID = "de.vogella.zest.jface.view"; private GraphViewer viewer; public void createPartControl(Composite parent) { viewer = new GraphViewer(parent, SWT.BORDER); viewer.setContentProvider(new ZestNodeContentProvider()); viewer.setLabelProvider(new ZestLabelProvider()); NodeModelContentProvider model = new NodeModelContentProvider(); viewer.setInput(model.getNodes()); LayoutAlgorithm layout = setLayout(); viewer.setLayoutAlgorithm(layout, true); viewer.applyLayout(); NodeFilter filter = new NodeFilter(); ViewerFilter[] filters = new ViewerFilter[1]; filters[0]= filter; viewer.setFilters(filters); fillToolBar(); } private LayoutAlgorithm setLayout(){ LayoutAlgorithm layout; // layout = new SpringLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING); layout = new TreeLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING); // layout = new GridLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING); // layout = new HorizontalTreeLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING); // layout = new RadialLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING); return layout; } /** * Passing the focus request to the viewer's control. */ public void setFocus() { } private void fillToolBar() { ZoomContributionViewItem toolbarZoomContributionViewItem = new ZoomContributionViewItem(this); IActionBars bars = getViewSite().getActionBars(); bars.getMenuManager().add(toolbarZoomContributionViewItem); } @Override public AbstractZoomableViewer getZoomableViewer() { return viewer; } }
注:也可以在layout上注册filter,这样在计算布局的时候,特定的元素会被忽略。方法isObjectFiltered()。使用item.getGraphData()去得到底层的object对象。
缺省情况下节点都可以移动,要禁用,可以如下实现:
package de.vogella.zest.movenodes.graph; import org.eclipse.draw2d.SWTEventDispatcher; import org.eclipse.swt.widgets.Composite; import org.eclipse.zest.core.widgets.Graph; public class NonMovableGraph extends Graph { public NonMovableGraph(Composite parent, int style) { super(parent, style); this.getLightweightSystem().setEventDispatcher( new SWTEventDispatcher() { public void dispatchMouseMoved( org.eclipse.swt.events.MouseEvent me) { // Doing nothing } }); } }