1
28 package demo.layout.router;
29
30 import demo.view.DemoBase;
31 import y.base.DataProvider;
32 import y.base.Edge;
33 import y.base.EdgeCursor;
34 import y.base.EdgeMap;
35 import y.base.Node;
36 import y.base.NodeCursor;
37 import y.layout.Layouter;
38 import y.layout.PortConstraintConfigurator;
39 import y.layout.PortConstraintKeys;
40 import y.layout.router.ChannelEdgeRouter;
41 import y.layout.router.OrthogonalEdgeRouter;
42 import y.layout.router.polyline.EdgeRouter;
43 import demo.layout.module.ChannelEdgeRouterModule;
44 import demo.layout.module.OrthogonalEdgeRouterModule;
45 import demo.layout.module.PolylineEdgeRouterModule;
46 import y.module.YModule;
47 import y.option.OptionHandler;
48 import y.util.DataProviderAdapter;
49 import y.view.Bend;
50 import y.view.BendCursor;
51 import y.view.BendList;
52 import y.view.CreateEdgeMode;
53 import y.view.EdgeRealizer;
54 import y.view.EditMode;
55 import y.view.Graph2D;
56 import y.view.HotSpotMode;
57 import y.view.MovePortMode;
58 import y.view.PolyLineEdgeRealizer;
59 import y.view.Port;
60 import y.view.PortAssignmentMoveSelectionMode;
61 import y.view.Selections;
62
63 import javax.swing.AbstractAction;
64 import javax.swing.JComboBox;
65 import javax.swing.JToolBar;
66 import java.awt.EventQueue;
67 import java.awt.event.ActionEvent;
68 import java.awt.event.ActionListener;
69 import java.util.HashSet;
70 import java.util.Locale;
71 import java.util.Set;
72
73
74
104 public class EdgeRouterDemo extends DemoBase {
105 RouterStrategy strategy;
106 PortAssignmentMoveSelectionMode paMode;
107
108 private OrthogonalEdgeRouterStrategy orthogonalEdgeRouterStrategy;
110 private ChannelEdgeRouterStrategy channelEdgeRouterStrategy;
111 private PolyLineEdgeRouterStrategy polylineEdgeRouterStrategy;
112
113 public EdgeRouterDemo() {
114 Graph2D graph = view.getGraph2D();
115 EdgeMap sourcePortMap = graph.createEdgeMap();
116 EdgeMap targetPortMap = graph.createEdgeMap();
117 graph.addDataProvider(PortConstraintKeys.SOURCE_PORT_CONSTRAINT_KEY, sourcePortMap);
118 graph.addDataProvider(PortConstraintKeys.TARGET_PORT_CONSTRAINT_KEY, targetPortMap);
119 paMode.setSpc(sourcePortMap);
120 paMode.setTpc(targetPortMap);
121
122 createInitialGraph();
123 }
124
125 protected void initialize() {
126 channelEdgeRouterStrategy = new ChannelEdgeRouterStrategy();
127 orthogonalEdgeRouterStrategy = new OrthogonalEdgeRouterStrategy();
128 polylineEdgeRouterStrategy = new PolyLineEdgeRouterStrategy();
129 }
130
131 protected void createInitialGraph() {
132 Graph2D graph = view.getGraph2D();
133 graph.createEdge(graph.createNode(100,100,"1"), graph.createEdge(graph.createNode(200,200,"2"), graph.createNode(300,100,"3")).source());
134 }
135
136
139 protected JToolBar createToolBar() {
140 final JComboBox comboBox = new JComboBox(new Object[]{"Polyline Edge Router", "Orthogonal Edge Router", "Channel Edge Router"});
141 comboBox.setMaximumSize(comboBox.getPreferredSize());
142 comboBox.addActionListener(new ActionListener() {
143 public void actionPerformed(ActionEvent e) {
144 switch (comboBox.getSelectedIndex()) {
145 case 0:
146 strategy = polylineEdgeRouterStrategy;
147 setSmoothedBends(false);
148 break;
149 case 1:
150 strategy = orthogonalEdgeRouterStrategy;
151 setSmoothedBends(true);
152 break;
153 case 2:
154 strategy = channelEdgeRouterStrategy;
155 setSmoothedBends(true);
156 }
157 strategy.getModule().start(view.getGraph2D());
158 }
159 });
160 strategy = polylineEdgeRouterStrategy;
161
162 JToolBar toolBar = super.createToolBar();
163 toolBar.addSeparator();
164 toolBar.add(createActionControl(new LayoutAction()));
165 toolBar.addSeparator(TOOLBAR_SMALL_SEPARATOR);
166 toolBar.add(comboBox);
167 toolBar.addSeparator(TOOLBAR_SMALL_SEPARATOR);
168 toolBar.add(createActionControl(new OptionAction()));
169
170 return toolBar;
171 }
172
173 private void setSmoothedBends(boolean smoothBends) {
174 Graph2D graph = view.getGraph2D();
175
176 for (EdgeCursor ec = graph.edges(); ec.ok(); ec.next()) {
177 final Edge edge = ec.edge();
178 EdgeRealizer realizer = graph.getRealizer(edge);
179 ((PolyLineEdgeRealizer) realizer).setSmoothedBends(smoothBends);
180 }
181
182 ((PolyLineEdgeRealizer) graph.getDefaultEdgeRealizer()).setSmoothedBends(smoothBends);
184 }
185
186
187
190 class OptionAction extends AbstractAction {
191 OptionAction() {
192 super("Settings...", getIconResource("resource/properties.png"));
193 }
194
195 public void actionPerformed(ActionEvent e) {
196 OptionSupport.showDialog(strategy.getModule(), view.getGraph2D(), false, view.getFrame());
197 }
198 }
199
200
203 class LayoutAction extends AbstractAction {
204 LayoutAction() {
205 super("Route Edges", SHARED_LAYOUT_ICON);
206 }
207
208 public void actionPerformed(ActionEvent e) {
209 strategy.getModule().start(view.getGraph2D());
210 }
211 }
212
213
218 protected void registerViewModes() {
219 EditMode mode = new EditMode();
220 mode.setMoveSelectionMode(paMode = new MyMoveSelectionMode());
221 mode.setCreateEdgeMode(new MyCreateEdgeMode());
222 mode.setHotSpotMode(new MyHotSpotMode());
223 mode.setMovePortMode(new MyMovePortMode());
224 view.addViewMode(mode);
225 }
226
227
228 class MyCreateEdgeMode extends CreateEdgeMode {
229 MyCreateEdgeMode() {
230 super();
231 allowSelfloopCreation(false);
232 }
233
234 protected void edgeCreated(final Edge e) {
235 final Graph2D graph = view.getGraph2D();
236
237 strategy.routeEdge(e);
238
239 graph.updateViews();
240 }
241 }
242
243
244
245 class MyHotSpotMode extends HotSpotMode {
246 public void mouseReleasedLeft(double x, double y) {
247 super.mouseReleasedLeft(x, y);
248
249 final Graph2D graph = view.getGraph2D();
250
251 DataProvider selectedNodes = Selections.createSelectionDataProvider(graph);
252 strategy.rerouteAdjacentEdges(selectedNodes, graph);
253 graph.updateViews();
254 }
255 }
256
257
258 class MyMoveSelectionMode extends PortAssignmentMoveSelectionMode {
259
260 MyMoveSelectionMode() {
261 super(null, null);
262 }
263
264 private boolean routeEdgesOnMove = true;
265
266 protected BendList getBendsToBeMoved() {
267 BendList bends = super.getBendsToBeMoved();
268
269 for (NodeCursor nodeCursor = getGraph2D().selectedNodes(); nodeCursor.ok(); nodeCursor.next()) {
271 Node node = nodeCursor.node();
272 for(EdgeCursor edgeCursor = node.outEdges(); edgeCursor.ok(); edgeCursor.next()) {
273 Edge edge = edgeCursor.edge();
274 if(getGraph2D().isSelected(edge.target())){
275 for(BendCursor bendCursor = getGraph2D().getRealizer(edge).bends(); bendCursor.ok(); bendCursor.next()){
276 Bend bend = bendCursor.bend();
277 bends.add(bend);
278 }
279 }
280 }
281 }
282 return bends;
283 }
284
285 protected void selectionOnMove(double dx, double dy, double x, double y) {
286 super.selectionOnMove(dx, dy, x, y);
287 if (routeEdgesOnMove) {
288 routeEdgesToSelection(false);
289 }
290 }
291
292 protected void selectionMovedAction(double dx, double dy, double x, double y) {
293 super.selectionMovedAction(dx, dy, x, y);
294 routeEdgesToSelection(true);
295 }
296
297 void routeEdgesToSelection(boolean includeBends) {
298 final Graph2D graph = view.getGraph2D();
299 if (graph.selectedNodes().ok() || (includeBends && graph.selectedBends().ok())) {
300 strategy.routeEdgesToSelection(graph);
301 graph.updateViews();
302 }
303 }
304 }
305
306 class MyMovePortMode extends MovePortMode {
307 MyMovePortMode() {
308 setChangeEdgeEnabled(true);
309 setIndicatingTargetNode(true);
310 }
311
312 protected void portMoved(Port port, double x, double y) {
313 super.portMoved(port, x, y);
314 final Edge edge = port.getOwner().getEdge();
315 strategy.routeEdge(edge);
316 }
317 }
318
319
320
321 public static void main(String[] args) {
322 EventQueue.invokeLater(new Runnable() {
323 public void run() {
324 Locale.setDefault(Locale.ENGLISH);
325 initLnF();
326 (new EdgeRouterDemo()).start("Orthogonal Edge Router Demo");
327 }
328 });
329 }
330
331 abstract static class RouterStrategy {
332 abstract YModule getModule();
333
334 abstract void routeEdge(final Edge e);
335
336 abstract void rerouteAdjacentEdges(final DataProvider selectedNodes, final Graph2D graph);
337
338 abstract void routeEdgesToSelection(final Graph2D graph);
339
340 abstract void route(final Graph2D graph);
341
342 protected void routeEdge(final Edge e, final Graph2D graph) {
343 EdgeMap spc = (EdgeMap) graph.getDataProvider(PortConstraintKeys.SOURCE_PORT_CONSTRAINT_KEY);
344 EdgeMap tpc = (EdgeMap) graph.getDataProvider(PortConstraintKeys.TARGET_PORT_CONSTRAINT_KEY);
345
346 PortConstraintConfigurator pcc = new PortConstraintConfigurator();
347 if (spc != null && tpc != null) {
348 spc.set(e, pcc.createPortConstraintFromSketch(graph, e, true, false));
349 tpc.set(e, pcc.createPortConstraintFromSketch(graph, e, false, false));
350 route(graph);
351 spc.set(e, null);
352 tpc.set(e, null);
353 } else {
354 route(graph);
355 }
356 }
357
358 protected void routeEdgesToSelection(final Graph2D graph, final Object affectedEdgesKey) {
359 final Set selectedEdges = new HashSet();
360 for (EdgeCursor ec = graph.edges(); ec.ok(); ec.next()) {
361 final Edge edge = ec.edge();
362 if (graph.isSelected(edge.source()) ^ graph.isSelected(edge.target())) {
363 selectedEdges.add(edge);
364 continue;
365 }
366 for (BendCursor bc = graph.selectedBends(); bc.ok(); bc.next()) {
367 final Bend bend = (Bend) bc.current();
368 if (bend.getEdge() == edge) {
369 selectedEdges.add(edge);
370 break;
371 }
372 }
373 }
374 graph.addDataProvider(affectedEdgesKey, new DataProviderAdapter() {
375 public boolean getBool(Object dataHolder) {
376 return selectedEdges.contains(dataHolder);
377 }
378 });
379 route(graph);
380 graph.removeDataProvider(affectedEdgesKey);
381 }
382
383 protected void routeEdge(final Edge e, final Graph2D graph, final Object selectedEdgesKey) {
384 graph.addDataProvider(selectedEdgesKey, new DataProviderAdapter() {
385 public boolean getBool(Object o) {
386 return e == o;
387 }
388 });
389 routeEdge(e, graph);
390 graph.removeDataProvider(selectedEdgesKey);
391 }
392 }
393
394 static class OrthogonalEdgeRouterStrategy extends RouterStrategy {
395 private final MyOrthogonalEdgeRouterModule module;
396
397 public OrthogonalEdgeRouterStrategy() {
398 module = new MyOrthogonalEdgeRouterModule();
399 module.setMorphingEnabled(false);
401 }
402
403 public YModule getModule() {
404 return module;
405 }
406
407 public void routeEdge(final Edge e) {
408 final Graph2D graph = (Graph2D) e.getGraph();
409 module.setSphereOfAction(OrthogonalEdgeRouter.ROUTE_SELECTED_EDGES);
410 routeEdge(e, graph, Layouter.SELECTED_EDGES);
411 module.resetSphereOfAction();
412 }
413
414 public void rerouteAdjacentEdges(final DataProvider selectedNodes, final Graph2D graph) {
415 module.setSphereOfAction(OrthogonalEdgeRouter.ROUTE_EDGES_AT_SELECTED_NODES);
416 graph.addDataProvider(Layouter.SELECTED_NODES, selectedNodes);
417 this.route(graph);
418 graph.removeDataProvider(Layouter.SELECTED_NODES);
419 module.resetSphereOfAction();
420 }
421
422 public void routeEdgesToSelection(final Graph2D graph) {
423 module.setSphereOfAction(OrthogonalEdgeRouter.ROUTE_SELECTED_EDGES);
424 routeEdgesToSelection(graph, Layouter.SELECTED_EDGES);
425 module.resetSphereOfAction();
426 }
427
428 void route(final Graph2D graph) {
429 module.start(graph);
430 }
431 }
432
433
437 private static class MyOrthogonalEdgeRouterModule extends OrthogonalEdgeRouterModule {
438 private final byte UNDEFINED = -1;
439 private byte sphereOfAction = UNDEFINED;
440
441 protected void configure(final OrthogonalEdgeRouter orthogonal, final OptionHandler options) {
442 super.configure(orthogonal, options);
443
444 if (sphereOfAction != UNDEFINED) {
445 orthogonal.setSphereOfAction(sphereOfAction);
446 }
447 }
448
449 public void setSphereOfAction(final byte sphereOfAction) {
450 this.sphereOfAction = sphereOfAction;
451 }
452
453 public void resetSphereOfAction() {
454 sphereOfAction = UNDEFINED;
455 }
456 }
457
458 static class ChannelEdgeRouterStrategy extends RouterStrategy {
459 private final ChannelEdgeRouterModule module;
460
461 public ChannelEdgeRouterStrategy() {
462 module = new ChannelEdgeRouterModule();
463 module.setMorphingEnabled(false);
465 }
466
467 public YModule getModule() {
468 return module;
469 }
470
471 public void routeEdge(final Edge e) {
472 final Graph2D graph = (Graph2D) e.getGraph();
473 routeEdge(e, graph, ChannelEdgeRouter.AFFECTED_EDGES);
474 }
475
476 public void rerouteAdjacentEdges(final DataProvider selectedNodes, final Graph2D graph) {
477 graph.addDataProvider(ChannelEdgeRouter.AFFECTED_EDGES, new DataProviderAdapter() {
478 public boolean getBool(Object dataHolder) {
479 return selectedNodes.getBool((((Edge) dataHolder).source())) || selectedNodes.getBool(((Edge) dataHolder).target());
480 }
481 });
482 this.route(graph);
483 graph.removeDataProvider(ChannelEdgeRouter.AFFECTED_EDGES);
484 }
485
486 public void routeEdgesToSelection(final Graph2D graph) {
487 routeEdgesToSelection(graph, ChannelEdgeRouter.AFFECTED_EDGES);
488 }
489
490 void route(final Graph2D graph) {
491 module.start(graph);
492 }
493 }
494
495 static class PolyLineEdgeRouterStrategy extends RouterStrategy {
496 private final MyPolylineEdgeRouterModule module;
497
498 PolyLineEdgeRouterStrategy() {
499 module = new MyPolylineEdgeRouterModule();
500 module.setMorphingEnabled(false);
502 }
503
504 YModule getModule() {
505 return module;
506 }
507
508 void routeEdge(final Edge e) {
509 final Graph2D graph = (Graph2D) e.getGraph();
510 module.setSphereOfAction(EdgeRouter.ROUTE_SELECTED_EDGES);
511 routeEdge(e, graph, Layouter.SELECTED_EDGES);
512 module.resetSphereOfAction();
513 }
514
515 void rerouteAdjacentEdges(final DataProvider selectedNodes, final Graph2D graph) {
516 module.setSphereOfAction(EdgeRouter.ROUTE_SELECTED_EDGES);
517 graph.addDataProvider(Layouter.SELECTED_EDGES, new DataProviderAdapter() {
518 public boolean getBool(Object dataHolder) {
519 return selectedNodes.getBool(((Edge) dataHolder).source())
520 || selectedNodes.getBool(((Edge) dataHolder).target());
521 }
522 });
523 this.route(graph);
524 graph.removeDataProvider(Layouter.SELECTED_EDGES);
525 module.resetSphereOfAction();
526 }
527
528 void routeEdgesToSelection(final Graph2D graph) {
529 module.setSphereOfAction(EdgeRouter.ROUTE_SELECTED_EDGES);
530 routeEdgesToSelection(graph, Layouter.SELECTED_EDGES);
531 module.resetSphereOfAction();
532 }
533
534 void route(final Graph2D graph) {
535 module.start(graph);
536 }
537 }
538
539
543 private static class MyPolylineEdgeRouterModule extends PolylineEdgeRouterModule {
544 private static final byte UNDEFINED = -1;
545 private byte sphereOfAction = UNDEFINED;
546
547 protected OptionHandler createOptionHandler() {
548 final OptionHandler options = super.createOptionHandler();
549 options.set(ITEM_ENABLE_POLYLINE_ROUTING, Boolean.TRUE);
550 return options;
551 }
552
553 protected void configure(EdgeRouter router, OptionHandler options) {
554 super.configure(router, options);
555
556 if (sphereOfAction != UNDEFINED) {
557 router.setSphereOfAction(EdgeRouter.ROUTE_SELECTED_EDGES);
558 }
559 }
560
561 public void setSphereOfAction(final byte sphereOfAction) {
562 this.sphereOfAction = sphereOfAction;
563 }
564
565 public void resetSphereOfAction() {
566 sphereOfAction = UNDEFINED;
567 }
568 }
569 }
570
571
572
573