1
14 package demo.view.layout.hierarchic;
15
16 import demo.view.DemoBase;
17 import demo.view.advanced.DragAndDropDemo;
18 import demo.view.realizer.GenericNodeRealizerDemo;
19 import y.anim.AnimationFactory;
20 import y.anim.AnimationPlayer;
21 import y.base.DataMap;
22 import y.base.DataProvider;
23 import y.base.Edge;
24 import y.base.Node;
25 import y.base.NodeCursor;
26 import y.base.NodeList;
27 import y.layout.BufferedLayouter;
28 import y.layout.GraphLayout;
29 import y.layout.PortCandidate;
30 import y.layout.PortCandidateSet;
31 import y.layout.PortConstraint;
32 import y.layout.hierarchic.IncrementalHierarchicLayouter;
33 import y.layout.hierarchic.incremental.IncrementalHintsFactory;
34 import y.layout.hierarchic.incremental.SimplexNodePlacer;
35 import y.util.DataProviderAdapter;
36 import y.util.DataProviders;
37 import y.util.Maps;
38 import y.view.Arrow;
39 import y.view.BridgeCalculator;
40 import y.view.DefaultGraph2DRenderer;
41 import y.view.EdgeRealizer;
42 import y.view.EditMode;
43 import y.view.GenericNodeRealizer;
44 import y.view.Graph2D;
45 import y.view.Graph2DView;
46 import y.view.HitInfo;
47 import y.view.LayoutMorpher;
48 import y.view.NodeRealizer;
49 import y.view.GeneralPathNodePainter;
50
51 import javax.swing.AbstractAction;
52 import javax.swing.JScrollPane;
53 import javax.swing.JToolBar;
54 import javax.swing.SwingUtilities;
55 import java.awt.BorderLayout;
56 import java.awt.Color;
57 import java.awt.Cursor;
58 import java.awt.event.ActionEvent;
59 import java.awt.geom.Ellipse2D;
60 import java.awt.geom.GeneralPath;
61 import java.awt.geom.RoundRectangle2D;
62 import java.util.ArrayList;
63 import java.util.HashMap;
64 import java.util.Iterator;
65 import java.util.List;
66 import java.util.Map;
67
68
72 public class FlowChartDemo extends DemoBase {
73
74 private IncrementalHierarchicLayouter layouter;
76 private DataMap hintMap;
78
79 public FlowChartDemo() {
80 configureView();
81
82 final List nodeRealizerList = new ArrayList();
83 addNodeRealizerTemplates(nodeRealizerList);
84
85 DragAndDropDemo.DragAndDropSupport dndSupport = new DragAndDropDemo.DragAndDropSupport(nodeRealizerList, view) {
87
88 protected String getTextValue(NodeRealizer selected) {
90 if (selected instanceof GenericNodeRealizer) {
91 GenericNodeRealizer gnr = (GenericNodeRealizer) selected;
92 return gnr.getConfiguration();
93 } else {
94 return null;
95 }
96 }
97
98 protected NodeRealizer createNodeRealizerFromTextValue(String s) {
100 try {
101 for (Iterator iterator = nodeRealizerList.iterator(); iterator.hasNext();) {
102 GenericNodeRealizer genericNodeRealizer = (GenericNodeRealizer) iterator.next();
103 if (genericNodeRealizer.getConfiguration().equals(s)) {
104 return genericNodeRealizer;
105 }
106 }
107 } catch (IllegalArgumentException iae){
108 }
109 return null;
110 }
111
112 protected boolean dropRealizer(Graph2DView view, NodeRealizer r, double worldCoordX, double worldCoordY) {
114 final Graph2D graph = view.getGraph2D();
115 final HitInfo hitInfo = new HitInfo(view, worldCoordX, worldCoordY, true, HitInfo.NODE);
116 r = r.createCopy();
117 r.setCenter(worldCoordX, worldCoordY);
118 final Node node = graph.createNode(r);
119 if (hitInfo.getHitNode() != null) {
120 graph.createEdge(hitInfo.getHitNode(), node);
121 SwingUtilities.invokeLater(new Runnable() {
122 public void run() {
123 runIncrementalLayout(new NodeList(node).nodes());
124 }
125 });
126 } else {
127 view.updateView();
128 }
129 return true;
130 }
131 };
132
133 contentPane.add(new JScrollPane(dndSupport.getList()), BorderLayout.WEST);
135 layouter = createLayouter();
136 }
137
138
141 protected EditMode createEditMode() {
142 final EditMode editMode = super.createEditMode();
143 editMode.assignNodeLabel(false);
144 editMode.allowResizeNodes(false);
145 return editMode;
146 }
147
148
151 protected JToolBar createToolBar() {
152 final JToolBar toolBar = super.createToolBar();
153 toolBar.add(new AbstractAction("Layout") {
154 public void actionPerformed(ActionEvent e) {
155 runLayout();
156 }
157 });
158 return toolBar;
159 }
160
161
164 private void configureView() {
165 final EdgeRealizer defaultEdgeRealizer = view.getGraph2D().getDefaultEdgeRealizer();
166 defaultEdgeRealizer.setTargetArrow(Arrow.STANDARD);
167 ((DefaultGraph2DRenderer) view.getGraph2DRenderer()).setBridgeCalculator(new BridgeCalculator());
168 }
169
170
173 private IncrementalHierarchicLayouter createLayouter(){
174 final IncrementalHierarchicLayouter layouter = new IncrementalHierarchicLayouter();
175 ((SimplexNodePlacer) layouter.getNodePlacer()).setBaryCenterModeEnabled(true);
176 layouter.setLayoutMode(IncrementalHierarchicLayouter.LAYOUT_MODE_FROM_SCRATCH);
177 layouter.getEdgeLayoutDescriptor().setOrthogonallyRouted(true);
178 final Graph2D graph = view.getGraph2D();
179
180 hintMap = Maps.createDataMap(new HashMap());
182 graph.addDataProvider(IncrementalHierarchicLayouter.INCREMENTAL_HINTS_DPKEY, hintMap);
183
184 graph.addDataProvider(PortCandidateSet.NODE_DP_KEY, new DataProviderAdapter() {
186 public Object get(Object dataHolder) {
187 final Node node = (Node) dataHolder;
188 final NodeRealizer realizer = graph.getRealizer(node);
189 if (realizer instanceof GenericNodeRealizer){
190 return (PortCandidateSet) ((GenericNodeRealizer) realizer).getUserData();
191 } else {
192 return null;
193 }
194 }
195 });
196
197 graph.addDataProvider(PortConstraint.SOURCE_GROUPID_KEY, new DataProviderAdapter() {
199 public Object get(Object dataHolder) {
200 Edge edge = (Edge) dataHolder;
201 Node source = edge.source();
202 GenericNodeRealizer gnr = (GenericNodeRealizer) graph.getRealizer(source);
203 String sourceConfiguration = gnr.getConfiguration();
204 if (sourceConfiguration.equals("start")) {
205 return source;
206 }
207 return null;
208 }
209 });
210
211 graph.addDataProvider(PortConstraint.TARGET_GROUPID_KEY, new DataProviderAdapter() {
213 public Object get(Object dataHolder) {
214 Edge edge = (Edge) dataHolder;
215 Node target = edge.target();
216 GenericNodeRealizer gnr = (GenericNodeRealizer) graph.getRealizer(target);
217 String targetConfiguration = gnr.getConfiguration();
218 if (targetConfiguration.equals("switch") || targetConfiguration.equals("branch")) {
219 return target;
220 }
221 return null;
222 }
223 });
224
225 final DataProvider southDP = DataProviders.createConstantDataProvider(PortConstraint.create(PortConstraint.SOUTH));
227 graph.addDataProvider(PortConstraint.SOURCE_PORT_CONSTRAINT_KEY, southDP);
228 final DataProvider northDP = DataProviders.createConstantDataProvider(PortConstraint.create(PortConstraint.NORTH));
229 graph.addDataProvider(PortConstraint.TARGET_PORT_CONSTRAINT_KEY, northDP);
230 return layouter;
231 }
232
233
236 private void runLayout() {
237 Cursor oldCursor = view.getCanvasComponent().getCursor();
238 try {
239 view.getCanvasComponent().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
240 GraphLayout result = new BufferedLayouter(layouter).calcLayout(view.getGraph2D());
241 LayoutMorpher morpher = new LayoutMorpher(view, result);
242 morpher.setSmoothViewTransform(true);
243 morpher.setPreferredDuration(300);
244 final AnimationPlayer player = new AnimationPlayer();
245 player.addAnimationListener(view);
246 player.setFps(120);
247 player.animate(AnimationFactory.createEasedAnimation(morpher));
248 } finally {
249 view.getCanvasComponent().setCursor(oldCursor);
250 }
251 }
252
253
256 private void runIncrementalLayout(NodeCursor incrementalNodes) {
257 Cursor oldCursor = view.getCanvasComponent().getCursor();
258 try {
259 view.getCanvasComponent().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
260 layouter.setLayoutMode(IncrementalHierarchicLayouter.LAYOUT_MODE_INCREMENTAL);
261 final IncrementalHintsFactory factory = layouter.createIncrementalHintsFactory();
262 for (incrementalNodes.toFirst(); incrementalNodes.ok(); incrementalNodes.next()){
263 hintMap.set(incrementalNodes.node(), factory.createLayerIncrementallyHint(incrementalNodes.node()));
264 }
265 GraphLayout result = new BufferedLayouter(layouter).calcLayout(view.getGraph2D());
266 LayoutMorpher morpher = new LayoutMorpher(view, result);
267 morpher.setSmoothViewTransform(true);
268 morpher.setPreferredDuration(300);
269 final AnimationPlayer player = new AnimationPlayer();
270 player.addAnimationListener(view);
271 player.setFps(120);
272 player.animate(AnimationFactory.createEasedAnimation(morpher));
273 } finally {
274 layouter.setLayoutMode(IncrementalHierarchicLayouter.LAYOUT_MODE_FROM_SCRATCH);
275 for (incrementalNodes.toFirst(); incrementalNodes.ok(); incrementalNodes.next()){
276 hintMap.set(incrementalNodes.node(), null);
277 }
278 view.getCanvasComponent().setCursor(oldCursor);
279 }
280 }
281
282
284 private void addNodeRealizerTemplates(List nodeRealizerList) {
285 final GenericNodeRealizer.Factory factory = GenericNodeRealizer.getFactory();
287 {
288 final Map map = GenericNodeRealizer.getFactory().createDefaultConfigurationMap();
290 Ellipse2D.Double outer = new Ellipse2D.Double(0,0, 1,1);
291 Ellipse2D.Double inner = new Ellipse2D.Double(0.1, 0.1, 0.8, 0.8);
292 Ellipse2D.Double inner2 = new Ellipse2D.Double(0.2, 0.2, 0.6, 0.6);
293 GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 6);
294 gp.append(outer, true);
295 gp.append(inner, false);
296 gp.append(inner2, false);
297 final GeneralPathNodePainter painter = new GeneralPathNodePainter(gp);
298 final GenericNodeRealizerDemo.RectangularShapePainter containsTest = new GenericNodeRealizerDemo.RectangularShapePainter(outer);
299 map.put(GenericNodeRealizer.Painter.class, painter);
300 map.put(GenericNodeRealizer.ContainsTest.class, containsTest);
301 factory.addConfiguration("start", map);
302
303 final GenericNodeRealizer startRealizer = new GenericNodeRealizer("start");
305 startRealizer.setFillColor(Color.black);
306
307 PortCandidateSet candidateSet = new PortCandidateSet();
310 candidateSet.add(PortCandidate.createCandidate(0.0d, 0.0d, PortCandidate.ANY, 0), Integer.MAX_VALUE);
311 startRealizer.setUserData(candidateSet);
312
313 nodeRealizerList.add(startRealizer);
315 }
316 {
317 final Map map = GenericNodeRealizer.getFactory().createDefaultConfigurationMap();
318 RoundRectangle2D.Double rr = new RoundRectangle2D.Double(0,0,100, 100, 20, 20);
319 final GenericNodeRealizerDemo.RectangularShapePainter painter = new GenericNodeRealizerDemo.RectangularShapePainter(rr);
320 map.put(GenericNodeRealizer.Painter.class, painter);
321 map.put(GenericNodeRealizer.ContainsTest.class, painter);
322 factory.addConfiguration("state", map);
323
324 final GenericNodeRealizer stateRealizer = new GenericNodeRealizer("state");
326 stateRealizer.setFillColor(Color.yellow);
327
328 PortCandidateSet candidateSet = new PortCandidateSet();
330 candidateSet.add(PortCandidate.createCandidate(PortCandidate.NORTH, 0), Integer.MAX_VALUE);
331 candidateSet.add(PortCandidate.createCandidate(PortCandidate.SOUTH, 0), Integer.MAX_VALUE);
332 stateRealizer.setUserData(candidateSet);
333
334 nodeRealizerList.add(stateRealizer);
336 }
337 {
338 final Map map = GenericNodeRealizer.getFactory().createDefaultConfigurationMap();
339 GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 6);
340 gp.moveTo(0.5f,0f);
341 gp.lineTo(1.0f, 0.5f);
342 gp.lineTo(0.5f, 1.0f);
343 gp.lineTo(0,0.5f);
344 gp.closePath();
345 final GeneralPathNodePainter painter = new GeneralPathNodePainter(gp);
346 map.put(GenericNodeRealizer.Painter.class, painter);
347 map.put(GenericNodeRealizer.ContainsTest.class, painter);
348 factory.addConfiguration("switch", map);
349
350 final GenericNodeRealizer switchRealizer = new GenericNodeRealizer("switch");
352
353 PortCandidateSet candidateSet = new PortCandidateSet();
355 candidateSet.add(PortCandidate.createCandidate(0, -15, PortCandidate.NORTH, 0), 1);
356 candidateSet.add(PortCandidate.createCandidate(0, 15, PortCandidate.SOUTH, 0), 1);
357 candidateSet.add(PortCandidate.createCandidate(15, 0,PortCandidate.EAST, 0), 1);
358 candidateSet.add(PortCandidate.createCandidate(-15, 0,PortCandidate.WEST, 0), 1);
359 candidateSet.add(PortCandidate.createCandidate(0, -15, PortCandidate.NORTH, 1), Integer.MAX_VALUE);
360 candidateSet.add(PortCandidate.createCandidate(0, 15, PortCandidate.SOUTH, 1), Integer.MAX_VALUE);
361 switchRealizer.setUserData(candidateSet);
362
363 nodeRealizerList.add(switchRealizer);
365 }
366 {
367 final Map map = GenericNodeRealizer.getFactory().createDefaultConfigurationMap();
368 GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 6);
369 gp.moveTo(0.5f,0.3f);
370 gp.lineTo(1, 1);
371 gp.lineTo(0, 1);
372 gp.closePath();
373 final GeneralPathNodePainter painter = new GeneralPathNodePainter(gp);
374 map.put(GenericNodeRealizer.Painter.class, painter);
375 map.put(GenericNodeRealizer.ContainsTest.class, painter);
376 factory.addConfiguration("branch", map);
377
378 final GenericNodeRealizer branch = new GenericNodeRealizer("branch");
380
381 PortCandidateSet candidateSet = new PortCandidateSet();
383 candidateSet.add(PortCandidate.createCandidate(0, 0, PortCandidate.NORTH, 0), Integer.MAX_VALUE);
384 candidateSet.add(PortCandidate.createCandidate(PortCandidate.SOUTH, 0), 3);
385 candidateSet.add(PortCandidate.createCandidate(0, 0,PortCandidate.EAST, 1), Integer.MAX_VALUE);
386 candidateSet.add(PortCandidate.createCandidate(0, 0,PortCandidate.WEST, 1), Integer.MAX_VALUE);
387 branch.setUserData(candidateSet);
388
389 nodeRealizerList.add(branch);
391 }
392 {
393 final Map map = GenericNodeRealizer.getFactory().createDefaultConfigurationMap();
394 Ellipse2D.Double outer = new Ellipse2D.Double(0.2, 0.2, 0.6, 0.6);
395 GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 6);
396 gp.append(outer, true);
397
398 final GeneralPathNodePainter painter = new GeneralPathNodePainter(gp);
399 map.put(GenericNodeRealizer.Painter.class, painter);
400 map.put(GenericNodeRealizer.ContainsTest.class, painter);
401 factory.addConfiguration("end", map);
402
403 final GenericNodeRealizer endRealizer = new GenericNodeRealizer("end");
405 endRealizer.setFillColor(Color.black);
406
407 PortCandidateSet candidateSet = new PortCandidateSet();
409 candidateSet.add(PortCandidate.createCandidate(0, 0,PortCandidate.NORTH, 0), 1);
410 candidateSet.add(PortCandidate.createCandidate(0, 0,PortCandidate.EAST, 1), 1);
411 candidateSet.add(PortCandidate.createCandidate(0, 0,PortCandidate.WEST, 1), 1);
412 candidateSet.add(PortCandidate.createCandidate(0, 0,PortCandidate.EAST, 2), Integer.MAX_VALUE);
413 candidateSet.add(PortCandidate.createCandidate(0, 0,PortCandidate.WEST, 2), Integer.MAX_VALUE);
414 endRealizer.setUserData(candidateSet);
415
416 nodeRealizerList.add(endRealizer);
418 }
419 }
420
421 public static void main(String[] args) {
422 initLnF();
423 new FlowChartDemo().start("Flow Chart Demo");
424 }
425 }
426