1
14 package demo.view.flowchart;
15
16 import demo.view.DemoBase;
17 import org.w3c.dom.Element;
18 import y.base.Graph;
19 import y.io.GraphMLIOHandler;
20 import y.io.graphml.GraphMLHandler;
21 import y.io.graphml.KeyScope;
22 import y.io.graphml.graph2d.Graph2DGraphMLHandler;
23 import y.io.graphml.graph2d.PostprocessorInputHandler;
24 import y.io.graphml.graph2d.PostprocessorOutputHandler;
25 import y.io.graphml.input.GraphMLParseContext;
26 import y.io.graphml.input.GraphMLParseException;
27 import y.io.graphml.input.GraphMLParser;
28 import y.io.graphml.input.InputHandlerProvider;
29 import y.io.graphml.input.QueryInputHandlersEvent;
30 import y.module.YModule;
31 import y.util.DataProviderAdapter;
32 import y.view.Graph2D;
33 import y.view.Graph2DClipboard;
34 import y.view.Graph2DUndoManager;
35 import y.view.Graph2DView;
36 import y.view.Overview;
37
38 import javax.swing.AbstractAction;
39 import javax.swing.Action;
40 import javax.swing.BorderFactory;
41 import javax.swing.JComponent;
42 import javax.swing.JLabel;
43 import javax.swing.JMenu;
44 import javax.swing.JMenuBar;
45 import javax.swing.JMenuItem;
46 import javax.swing.JPanel;
47 import javax.swing.JSplitPane;
48 import javax.swing.JToolBar;
49 import javax.swing.KeyStroke;
50 import java.awt.BorderLayout;
51 import java.awt.Color;
52 import java.awt.Dimension;
53 import java.awt.EventQueue;
54 import java.awt.Font;
55 import java.awt.event.ActionEvent;
56 import java.awt.event.InputEvent;
57 import java.awt.event.KeyEvent;
58 import java.net.URL;
59 import java.util.Iterator;
60 import java.util.LinkedHashMap;
61 import java.util.Locale;
62 import java.util.Map;
63
64
65
71 public class FlowchartDemo extends DemoBase {
72
73 private static final Map EXAMPLES_FILE_NAMES;
74
75 static {
76 EXAMPLES_FILE_NAMES = new LinkedHashMap();
77 EXAMPLES_FILE_NAMES.put("problemsolving.graphml", "Problem Solving");
78 EXAMPLES_FILE_NAMES.put("studentRegistration.graphml", "Student Registration");
79 EXAMPLES_FILE_NAMES.put("E-commerce.graphml", "E-commerce");
80 EXAMPLES_FILE_NAMES.put("Procrastination.graphml", "The Procrastination Flowchart");
81 EXAMPLES_FILE_NAMES.put("DecisionMaking.graphml", "Decision Making");
82 EXAMPLES_FILE_NAMES.put("ComputingFactorial.graphml", "Computing the Factorial");
83 EXAMPLES_FILE_NAMES.put("FindingLargestNumber.graphml", "Finding the Largest Number");
84 EXAMPLES_FILE_NAMES.put("FindingLargestNumber2.graphml", "Finding the Largest Number 2");
85 }
86
87 FlowchartLayoutModule layoutModule;
88 FlowchartPalette palette;
89 Graph2DUndoManager undoManager;
90 Graph2DClipboard clipboard;
91
92
95 public FlowchartDemo() {
96 super();
97
98 final JComponent workBench = createWorkBench();
99 if (workBench != null) {
100 contentPane.add(workBench, BorderLayout.CENTER);
101 }
102
103 EventQueue.invokeLater(new Runnable() {
104 public void run() {
105 loadInitialGraph();
106 }
107 });
108 }
109
110 protected void loadInitialGraph() {
111 loadGraph("resource/graphs/problemsolving.graphml");
112 }
113
114
120 protected void registerViewModes() {
121 }
122
123
128 protected Graph2DView createGraphView() {
129 return new FlowchartView();
130 }
131
132
135 protected void initialize() {
136 palette = new FlowchartPalette(view);
137 palette.setSnapMode(true);
138
139 undoManager = new Graph2DUndoManager(view.getGraph2D());
140 undoManager.setViewContainer(view);
141
142 clipboard = new Graph2DClipboard(view);
143 clipboard.setCopyFactory(view.getGraph2D().getGraphCopyFactory());
144
145 layoutModule = new FlowchartLayoutModule();
146
147 view.getGraph2D().addDataProvider(PostprocessorOutputHandler.PROCESSORS_DPKEY,
150 new DataProviderAdapter() {
151 public Object get(Object dataHolder) {
152 return layoutModule;
153 }
154 });
155 }
156
157
162 protected JMenuBar createMenuBar() {
163 JMenu examplesMenu = new JMenu("Examples");
164 for (Iterator iterator = EXAMPLES_FILE_NAMES.entrySet().iterator(); iterator.hasNext(); ) {
165 final Map.Entry entry = (Map.Entry) iterator.next();
166 examplesMenu.add(new JMenuItem(new AbstractAction((String) entry.getValue()) {
167 public void actionPerformed(ActionEvent e) {
168 loadGraph("resource/graphs/" + entry.getKey());
169 }
170 }));
171 }
172
173 JMenuBar menuBar = super.createMenuBar();
174 menuBar.add(examplesMenu);
175 return menuBar;
176 }
177
178
183 protected JToolBar createToolBar() {
184 JToolBar toolBar = super.createToolBar();
185
186 toolBar.addSeparator();
187 toolBar.add(createUndoAction());
188 toolBar.add(createRedoAction());
189
190 toolBar.addSeparator();
191 toolBar.add(createCutAction());
192 toolBar.add(createCopyAction());
193 toolBar.add(createPasteAction());
194
195 toolBar.addSeparator();
196 toolBar.add(createActionControl(createLayoutAction()));
197 toolBar.addSeparator(TOOLBAR_SMALL_SEPARATOR);
198 toolBar.add(createActionControl(createLayoutSettingsAction()));
199
200 return toolBar;
201 }
202
203
209 protected GraphMLIOHandler createGraphMLIOHandler() {
210 final GraphMLIOHandler ioh = new PostprocessorGraphMLIOHandler(new PostprocessorInputHandler() {
211 protected void startModule(YModule module, Graph2D graph, GraphMLParseContext context)
212 throws GraphMLParseException {
213
215 if (module instanceof FlowchartLayoutModule) {
216 layoutModule = (FlowchartLayoutModule) module;
217 }
218 }
219 });
220 ioh.getGraphMLHandler().addOutputHandlerProvider(new PostprocessorOutputHandler());
221
222 return ioh;
223 }
224
225
228 protected void loadGraph(URL resource) {
229 final Graph2D graph = view.getGraph2D();
230 graph.firePreEvent();
231 super.loadGraph(resource);
232 graph.firePostEvent();
233 undoManager.resetQueue();
234
235 EventQueue.invokeLater(new Runnable() {
236 public void run() {
237 layoutModule.start(graph);
238 }
239 });
240 }
241
242
248 JComponent createWorkBench() {
249 JPanel titledOverview = createTitledPanel(createOverview(), "Overview");
250 JPanel titledPalette = createTitledPanel(this.palette, "Palette");
251 JSplitPane overviewPaletteSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, titledOverview, titledPalette);
252 return new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, overviewPaletteSplit, view);
253 }
254
255
260 protected Action createLayoutAction() {
261 final Action action = new AbstractAction("Layout") {
262 public void actionPerformed(ActionEvent e) {
263 layoutModule.start(view.getGraph2D());
264 }
265 };
266 action.putValue(Action.SHORT_DESCRIPTION, "Run the flowchart layout");
267 action.putValue(Action.SMALL_ICON, SHARED_LAYOUT_ICON);
268
269 return action;
270 }
271
272
277 protected Action createLayoutSettingsAction() {
278 final Action action = new AbstractAction("Settings...") {
279 public void actionPerformed(ActionEvent e) {
280 OptionSupport.showDialog(layoutModule, view.getGraph2D(), false, view.getFrame());
281 }
282 };
283 action.putValue(Action.SHORT_DESCRIPTION, "Configure and run the flowchart layout");
284 action.putValue(Action.SMALL_ICON, getIconResource("resource/properties.png"));
285
286 return action;
287 }
288
289
294 protected Action createUndoAction() {
295 Action undoAction = undoManager.getUndoAction();
296 undoAction.putValue(Action.SMALL_ICON, getIconResource("resource/undo.png"));
297 undoAction.putValue(Action.SHORT_DESCRIPTION, "Undo");
298
299 return undoAction;
300 }
301
302
307 protected Action createRedoAction() {
308 Action redoAction = undoManager.getRedoAction();
309 redoAction.putValue(Action.SMALL_ICON, getIconResource("resource/redo.png"));
310 redoAction.putValue(Action.SHORT_DESCRIPTION, "Redo");
311 return redoAction;
312 }
313
314
319 protected Action createCutAction() {
320 Action cutAction = clipboard.getCutAction();
321 cutAction.putValue(Action.SMALL_ICON, getIconResource("resource/cut.png"));
322 cutAction.putValue(Action.SHORT_DESCRIPTION, "Cut");
323
324 view.getCanvasComponent().getActionMap().put("CUT", cutAction);
325 view.getCanvasComponent().getInputMap().put(
326 KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK), "CUT");
327
328 return cutAction;
329 }
330
331
336 protected Action createCopyAction() {
337 Action copyAction = clipboard.getCopyAction();
338 copyAction.putValue(Action.SMALL_ICON, getIconResource("resource/copy.png"));
339 copyAction.putValue(Action.SHORT_DESCRIPTION, "Copy");
340
341 view.getCanvasComponent().getActionMap().put("COPY", copyAction);
342 view.getCanvasComponent().getInputMap().put(
343 KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK), "COPY");
344
345 return copyAction;
346 }
347
348
353 protected Action createPasteAction() {
354 Action pasteAction = clipboard.getPasteAction();
355 pasteAction.putValue(Action.SMALL_ICON, getIconResource("resource/paste.png"));
356 pasteAction.putValue(Action.SHORT_DESCRIPTION, "Paste");
357
358 view.getCanvasComponent().getActionMap().put("PASTE", pasteAction);
359 view.getCanvasComponent().getInputMap().put(
360 KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK), "PASTE");
361
362 return pasteAction;
363 }
364
365
370 protected Overview createOverview() {
371 final Overview overview = new Overview(view);
372 overview.putClientProperty("Overview.PaintStyle", "Funky");
374 overview.putClientProperty("Overview.AllowZooming", Boolean.TRUE);
376 overview.putClientProperty("Overview.AllowKeyboardNavigation", Boolean.TRUE);
378 overview.putClientProperty("Overview.Inverse", Boolean.TRUE);
380
381 overview.setPreferredSize(new Dimension((int) (0.2 * (double) contentPane.getWidth()), 200));
382 return overview;
383 }
384
385
388 protected JPanel createTitledPanel(JComponent content, String title) {
389 JLabel label = new JLabel(title);
390 label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
391 label.setBackground(new Color(231, 219, 182));
392 label.setOpaque(true);
393 label.setForeground(Color.DARK_GRAY);
394 label.setFont(label.getFont().deriveFont(Font.BOLD));
395 label.setFont(label.getFont().deriveFont(13.0f));
396
397 JPanel panel = new JPanel();
398 panel.setLayout(new BorderLayout());
399 panel.add(label, BorderLayout.NORTH);
400 panel.add(content, BorderLayout.CENTER);
401 return panel;
402 }
403
404 public static void main(String[] args) {
405 EventQueue.invokeLater(new Runnable() {
406 public void run() {
407 Locale.setDefault(Locale.ENGLISH);
408 initLnF();
409 final FlowchartDemo demo = new FlowchartDemo();
410 demo.start("Flowchart Editor Demo");
411 }
412 });
413 }
414
415
419 static class PostprocessorGraphMLIOHandler extends GraphMLIOHandler {
420 private final PostprocessorInputHandler postprocessorInputHandler;
421
422 PostprocessorGraphMLIOHandler(PostprocessorInputHandler postprocessorInputHandler) {
423 this.postprocessorInputHandler = postprocessorInputHandler;
424 }
425
426 protected Graph2DGraphMLHandler createGraphMLHandler() {
427 return new Graph2DGraphMLHandler() {
428
429 protected void configureInputHandlers(Graph graph, GraphMLParser parser) {
430 if (graph instanceof Graph2D) {
431 parser.addInputHandlerProvider(new InputHandlerProvider() {
432
433 public void onQueryInputHandler(QueryInputHandlersEvent event) throws GraphMLParseException {
434 final Element keyDefinition = event.getKeyDefinition();
435 if (GraphMLHandler.matchesScope(keyDefinition, KeyScope.GRAPH)
436 && postprocessorInputHandler.acceptKey(keyDefinition.getAttributes())) {
437 event.addInputHandler(postprocessorInputHandler);
438 }
439 }
440 });
441
442 }
443 super.configureInputHandlers(graph, parser);
444 }
445 };
446
447 }
448 }
449
450 }