Free tutorials for Java, Eclipse and Web programming



Follow me on twitter

5. Zest and JFace Example

5.1. Create Project

Create a new RCP application "de.vogella.zest.jface". Use the " RCP application with a view" as a template. Add the zest dependencies to your MANIFEST.MF. Change the Perspective.java to the following (we don't want a standalone view).

				
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);
	}

}

			

5.2. Model

Create the following model. Please note that the model can be anything as long as you can logically convert it into a connected Graph.

				
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;
	}
	
}


			

Also build this class which provides an instance of the data model.

				
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;
	}
}

			

5.3. Providers

Create the following content and 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());
	}
}

			

5.4. View

Change the view to the following.

				
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;
	}
}

			

The result should look like the following.

5.5. Filter

You can define a filter on the viewer via setFilters();

For example define the following 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; 
	}

}

			

Apply the filter to the view to filter all elements.

				
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;
	}
}

			

Tip

You can also define a filter on the layout so that certain elements are ignore then calculating the layout. Method isObjectFiltered(LayoutItem item). Use item.getGraphData() to get the underlying object (GraphNode or GraphConnection).