1 /*
2  * $Id: JGraphLayoutExample.java,v 1.2 2009/10/30 14:17:07 david Exp $
3  * Copyright (c) 2001-2005, Gaudenz Alder
4  *
5  * All rights reserved.
6  *
7  * This file is licensed under the JGraph software license, a copy of which
8  * will have been provided to you in the file LICENSE at the root of your
9  * installation directory. If you are unable to locate this file please
10  * contact JGraph sales for another copy.
11  */
12 package com.jgraph.layout;
13 
14 import java.awt.Container;
15 import java.awt.event.ActionEvent;
16 import java.awt.event.ActionListener;
17 import java.awt.geom.Point2D;
18 import java.beans.DefaultPersistenceDelegate;
19 import java.beans.Encoder;
20 import java.beans.Expression;
21 import java.beans.PersistenceDelegate;
22 import java.beans.XMLDecoder;
23 import java.beans.XMLEncoder;
24 import java.io.BufferedInputStream;
25 import java.io.FileInputStream;
26 import java.io.FileNotFoundException;
27 import java.net.URL;
28 import java.util.Map;
29 
30 import javax.swing.AbstractAction;
31 import javax.swing.Action;
32 import javax.swing.ImageIcon;
33 import javax.swing.JFileChooser;
34 import javax.swing.JFrame;
35 import javax.swing.JOptionPane;
36 import javax.swing.JToggleButton;
37 import javax.swing.JToolBar;
38 import javax.swing.JViewport;
39 
40 import org.jgraph.JGraph;
41 import org.jgraph.event.GraphSelectionEvent;
42 import org.jgraph.graph.BasicMarqueeHandler;
43 import org.jgraph.graph.DefaultEdge;
44 import org.jgraph.graph.GraphModel;
45 
46 import com.jgraph.example.GraphEdX;
47 import com.jgraph.layout.graph.JGraphSimpleLayout;
48 import com.jgraph.layout.hierarchical.JGraphHierarchicalLayout;
49 import com.jgraph.layout.organic.JGraphFastOrganicLayout;
50 import com.jgraph.layout.organic.JGraphOrganicLayout;
51 import com.jgraph.layout.organic.JGraphSelfOrganizingOrganicLayout;
52 import com.jgraph.layout.routing.JGraphParallelRouter;
53 import com.jgraph.layout.tree.JGraphCompactTreeLayout;
54 import com.jgraph.layout.tree.JGraphRadialTreeLayout;
55 import com.jgraph.layout.tree.JGraphTreeLayout;
56 
57 /**
58  * An example applet that provides features for testing the JGraph Layout
59  * package. Sample data can be inserted, the layouts applied, cells moved while
60  * the layout auto-applied and morphs the cells into position. This example also
61  * supports grouping and expand/collapse.
62  */
63 public class JGraphLayoutExample extends GraphEdX {
64 
65 	/**
66 	 * Global reference to the example layout cache.
67 	 */
68 	protected JGraphExampleLayoutCache layoutCache;
69 
70 	// Layout actions
71 	protected Action[] layoutActions;
72 
73 	/**
74 	 * Button representing the auto layout feature
75 	 */
76 	protected JToggleButton autoLayoutButton;
77 
78 	/**
79 	 * Semaphore for autolayout.
80 	 */
81 	protected boolean isInsideLayout = false;
82 
83 	protected int edgeCount = 0;
84 
85 	/**
86 	 * Constructs a new example
87 	 */
JGraphLayoutExample()88 	public JGraphLayoutExample() {
89 		layoutCache = (JGraphExampleLayoutCache) graph.getGraphLayoutCache();
90 //		JGraphParallelRouter.setGraph(graph);
91 		// Prepares layout actions
92 		layoutCache.layout = new JGraphCompactTreeLayout();
93 		createLayoutActions();
94 		setJMenuBar(new JGraphLayoutExampleMenuBar(this, graphFactory));
95 		// Initializes actions states
96 		valueChanged(null);
97 	}
98 
99 	/**
100 	 * Show something interesting on start.
101 	 */
init()102 	public void init() {
103 		graphFactory.insertTreeSampleData(getGraph(),
104 				createCellAttributes(new Point2D.Double(0, 0)),
105 				createEdgeAttributes());
106 		try {
107 			Thread.sleep(200);
108 		} catch (InterruptedException e) {
109 			// ignore
110 		}
111 		layoutActions[0].actionPerformed(null);
112 	}
113 
114 	// Override parent method
createGraph()115 	protected JGraph createGraph() {
116 		// Creates a model that does not allow disconnections
117 		GraphModel model = new MyGraphModel();
118 		return new JGraphExampleGraph(model);
119 	}
120 
121 	/**
122 	 * Hook from GraphEd to set attributes of a new edge
123 	 */
createEdgeAttributes()124 	public Map createEdgeAttributes() {
125 		Map map = super.createEdgeAttributes();
126 		// Adds a parallel edge router
127 //		GraphConstants.setRouting(map, JGraphParallelRouter.getSharedInstance());
128 		return map;
129 	}
130 
131 	// Hook for subclassers
createDefaultEdge()132 	protected DefaultEdge createDefaultEdge() {
133 		return new DefaultEdge("Edge " + new Integer(edgeCount++));
134 	}
135 
136 	/**
137 	 * Creates the actions for the layouts
138 	 */
createLayoutActions()139 	public void createLayoutActions() {
140 		JGraphLayout circleLayout = new JGraphSimpleLayout(
141 				JGraphSimpleLayout.TYPE_CIRCLE);
142 		JGraphLayout isomLayout = new JGraphSelfOrganizingOrganicLayout();
143 		JGraphLayout frLayout = new JGraphFastOrganicLayout();
144 		JGraphLayout hierLayout = new JGraphHierarchicalLayout();
145 		layoutActions = new Action[] {
146 				createLayoutAction("Compact Tree", "m", layoutCache.layout),
147 				createLayoutAction("Tree", "t", new JGraphTreeLayout()),
148 //				createLayoutAction("Organisational Chart", "t", new OrganizationalChart()),
149 				createLayoutAction("Radial Tree", "r",
150 						new JGraphRadialTreeLayout()),
151 				createLayoutAction("ISOM", "i", isomLayout),
152 				createLayoutAction("Organic", "o", new JGraphOrganicLayout()),
153 				createLayoutAction("Fast Organic", "f", frLayout),
154 				createLayoutAction("Hierarchical", "h", hierLayout),
155 				createLayoutAction("Circle", "c", circleLayout),
156 				createLayoutAction("Tilt", "l", new JGraphSimpleLayout(
157 						JGraphSimpleLayout.TYPE_TILT, 100, 100)),
158 				createLayoutAction("Random", "n", new JGraphSimpleLayout(
159 						JGraphSimpleLayout.TYPE_RANDOM, 640, 480)) };
160 	}
161 
162 	/**
163 	 * action to apply a layout
164 	 *
165 	 * @param title
166 	 *            the name of the layout
167 	 * @param shortcut
168 	 *            the string representing the shortcut keyboard combination that
169 	 *            invokes this action
170 	 * @param layout
171 	 *            the layout itself
172 	 * @return the apply layout action
173 	 */
createLayoutAction(final String title, String shortcut, final JGraphLayout layout)174 	public Action createLayoutAction(final String title, String shortcut,
175 			final JGraphLayout layout) {
176 		Action action = new AbstractAction(title) {
177 			public void actionPerformed(ActionEvent e) {
178 				layoutCache.layout = layout;
179 				layoutCache.layout(null);
180 			}
181 		};
182 		action.putValue("shortcut", shortcut);
183 		return action;
184 
185 	}
186 
187 	/**
188 	 * Updates buttons based on application state
189 	 */
valueChanged(GraphSelectionEvent e)190 	public void valueChanged(GraphSelectionEvent e) {
191 		super.valueChanged(e);
192 		// Group Button only Enabled if a cell is selected
193 		boolean enabled = !graph.isSelectionEmpty();
194 		boolean notEmpty = (graph.getModel().getRootCount() > 0);
195 		// hide.setEnabled(enabled);
196 		expand.setEnabled(enabled);
197 		expandAll.setEnabled(enabled);
198 		collapse.setEnabled(enabled);
199 		configure.setEnabled(layoutCache != null && layoutCache.layout != null);
200 		if (layoutActions != null) {
201 			for (int i = 0; i < layoutActions.length; i++) {
202 				layoutActions[i].setEnabled(notEmpty);
203 			}
204 		}
205 	}
206 
configureEncoder(XMLEncoder encoder)207 	protected void configureEncoder(XMLEncoder encoder) {
208 		super.configureEncoder(encoder);
209 		encoder
210 				.setPersistenceDelegate(JGraphExampleLayoutCache.class,
211 						new DefaultPersistenceDelegate(new String[] { "model",
212 								"factory", "cellViews", "hiddenCellViews",
213 								"partial" }));
214 		encoder.setPersistenceDelegate(JGraphExampleGraph.class,
215 				new DefaultPersistenceDelegate(new String[] { "model",
216 						"graphLayoutCache" }));
217 		encoder.setPersistenceDelegate(JGraphParallelRouter.class,
218 				new PersistenceDelegate() {
219 					protected Expression instantiate(Object oldInstance,
220 							Encoder out) {
221 						return new Expression(oldInstance,
222 								JGraphParallelRouter.class,
223 								"getSharedInstance", null);
224 					}
225 				});
226 	}
227 
228 	/**
229 	 * Hook from GraphEd to add action button to the tool bar
230 	 */
createToolBar()231 	public JToolBar createToolBar() {
232 		JToolBar toolbar = super.createToolBar();
233 
234 		// Configure layout
235 		configure = new AbstractAction() {
236 			public void actionPerformed(ActionEvent e) {
237 				layoutCache.configureLayout();
238 			}
239 		};
240 		URL url = getClass().getClassLoader().getResource(
241 				"com/jgraph/layout/image/configure.gif");
242 		configure.putValue(Action.SMALL_ICON, new ImageIcon(url));
243 		configure.setEnabled(false);
244 		toolbar.add(configure);
245 
246 		// AutoLayout toggle
247 		autoLayoutButton = new JToggleButton();
248 		autoLayoutButton.setSelected(false);
249 		url = getClass().getClassLoader().getResource(
250 				"com/jgraph/layout/image/layout.gif");
251 		autoLayoutButton.setIcon(new ImageIcon(url));
252 		autoLayoutButton.addActionListener(new ActionListener() {
253 			public void actionPerformed(ActionEvent e) {
254 				layoutCache.autolayout = autoLayoutButton.isSelected();
255 			}
256 		});
257 		toolbar.add(autoLayoutButton);
258 
259 		// JButton button = new JButton("My");
260 		// toolbar.add(button);
261 		// button.addActionListener(new ActionListener() {
262 		//
263 		// public void actionPerformed(ActionEvent event) {
264 		// // Add your code here
265 		// }
266 		//
267 		// });
268 		return toolbar;
269 	}
270 
openFile()271 	public void openFile() {
272 		int returnValue = JFileChooser.CANCEL_OPTION;
273 		initFileChooser();
274 		returnValue = fileChooser.showOpenDialog(graph);
275 		if (returnValue == JFileChooser.APPROVE_OPTION) {
276 			Container parent = graph.getParent();
277 			BasicMarqueeHandler marqueeHandler = graph.getMarqueeHandler();
278 			try {
279 				uninstallListeners(graph);
280 				parent.remove(graph);
281 				XMLDecoder decoder = new XMLDecoder(new BufferedInputStream(
282 						new FileInputStream(fileChooser.getSelectedFile())));
283 				graph = (JGraph) decoder.readObject();
284 				// Take the marquee handler from the original graph and
285 				// use it in the new graph as well.
286 				graph.setMarqueeHandler(marqueeHandler);
287 				JGraphParallelRouter.setGraph(graph);
288 				// Adds the component back into the component hierarchy
289 				if (parent instanceof JViewport) {
290 					JViewport viewPort = (JViewport) parent;
291 					viewPort.setView(graph);
292 				} else {
293 					// Best effort...
294 					parent.add(graph);
295 				}
296 				// graph.setMarqueeHandler(previousHandler);
297 				// And reinstalls the listener
298 				installListeners(graph);
299 			} catch (FileNotFoundException e) {
300 				JOptionPane.showMessageDialog(graph, e.getMessage(), "Error",
301 						JOptionPane.ERROR_MESSAGE);
302 			}
303 
304 		}
305 	}
306 
307 	/**
308 	 *
309 	 * @return a String representing the version of this application
310 	 */
getVersion()311 	protected String getVersion() {
312 		return JGraph.VERSION;
313 	}
314 
315 	/**
316 	 * Main method
317 	 */
main(String[] args)318 	public static void main(String[] args) {
319 		try {
320 			// Switch off D3D because of Sun XOR painting bug
321 			// See http://www.jgraph.com/forum/viewtopic.php?t=4066
322 			System.setProperty("sun.java2d.d3d", "false");
323 			// Construct Frame
324 			JFrame frame = new JFrame(JGraph.VERSION);
325 			// Set Close Operation to Exit
326 			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
327 			// Add an Editor Panel
328 			JGraphLayoutExample layoutExample = new JGraphLayoutExample();
329 			frame.getContentPane().add(layoutExample);
330 			// Fetch URL to Icon Resource
331 			URL jgraphUrl = JGraphLayoutExample.class.getClassLoader()
332 					.getResource("org/jgraph/example/resources/jgraph.gif");
333 			// If Valid URL
334 			if (jgraphUrl != null) {
335 				// Load Icon
336 				ImageIcon jgraphIcon = new ImageIcon(jgraphUrl);
337 				// Use in Window
338 				frame.setIconImage(jgraphIcon.getImage());
339 			}
340 			// Set Default Size
341 			frame.setSize(640, 480);
342 			// Show Frame
343 			frame.setVisible(true);
344 			layoutExample.init();
345 		} catch (Exception e) {
346 			e.printStackTrace();
347 		}
348 	}
349 
350 }
351