1
14 package demo.view.layout.router;
15
16 import demo.view.DemoBase;
17 import y.base.DataProvider;
18 import y.base.Edge;
19 import y.base.EdgeMap;
20 import y.base.Node;
21 import y.base.NodeList;
22 import y.io.GMLIOHandler;
23 import y.layout.LayoutGraph;
24 import y.layout.Layouter;
25 import y.layout.PortConstraintConfigurator;
26 import y.layout.PortConstraintKeys;
27 import y.layout.router.ChannelEdgeRouter;
28 import y.layout.router.OrthogonalEdgeRouter;
29 import y.module.ChannelEdgeRouterModule;
30 import y.module.OrthogonalEdgeRouterModule;
31 import y.module.YModule;
32 import y.option.OptionHandler;
33 import y.util.DataProviderAdapter;
34 import y.view.Arrow;
35 import y.view.CreateEdgeMode;
36 import y.view.DefaultGraph2DRenderer;
37 import y.view.Drawable;
38 import y.view.EditMode;
39 import y.view.Graph2D;
40 import y.view.HotSpotMode;
41 import y.view.MoveSelectionMode;
42 import y.view.Selections;
43
44 import javax.swing.AbstractAction;
45 import javax.swing.JComboBox;
46 import javax.swing.JToolBar;
47 import java.awt.Graphics2D;
48 import java.awt.Rectangle;
49 import java.awt.event.ActionEvent;
50 import java.awt.event.ActionListener;
51
52
72 public class MazeRouterDemo extends DemoBase
73 {
74 private RouterStrategy strategy;
75 private Graph2D demoG, mazeG;
76 private Drawable mazeD;
77 private NodeList mazeNodes;
78 private OrthogonalEdgeRouterStrategy orthogonalEdgeRouterStrategy = new OrthogonalEdgeRouterStrategy();
79 private ChannelEdgeRouterStrategy channelEdgeRouterStrategy = new ChannelEdgeRouterStrategy();
80
81 public MazeRouterDemo()
82 {
83 strategy = orthogonalEdgeRouterStrategy;
84
85 demoG = view.getGraph2D();
86 demoG.getDefaultEdgeRealizer().setTargetArrow(Arrow.STANDARD);
87
88 initializeMaze();
89 }
90
91
94 protected JToolBar createToolBar()
95 {
96 JToolBar toolBar = super.createToolBar();
97 toolBar.addSeparator();
98 toolBar.add(new LayoutAction());
99 toolBar.add(new OptionAction());
100 final JComboBox comboBox = new JComboBox(new Object[]{"Orthogonal Edge Router", "Channel Edge Router"});
101 comboBox.addActionListener(new ActionListener() {
102 public void actionPerformed(ActionEvent e) {
103 switch (comboBox.getSelectedIndex()) {
104 default:
105 case 0:
106 strategy = orthogonalEdgeRouterStrategy;
107 break;
108 case 1:
109 strategy = channelEdgeRouterStrategy;
110 break;
111 }
112 }
113 });
114 toolBar.add(comboBox);
115 return toolBar;
116 }
117
118
121 class FitContent extends AbstractAction
122 {
123 FitContent()
124 {
125 super("Fit Content");
126 }
127
128 public void actionPerformed(ActionEvent e)
129 {
130 Graph2D graph = view.getGraph2D();
131
132 Rectangle r = graph.getBoundingBox();
133 r.add(mazeD.getBounds());
134 view.fitRectangle(r);
135 graph.updateViews();
136 }
137 }
138
139
142 class OptionAction extends AbstractAction
143 {
144 OptionAction()
145 {
146 super("Router Options...");
147 }
148
149 public void actionPerformed(ActionEvent e)
150 {
151 OptionHandler op = strategy.getModule().getOptionHandler();
153 if (op != null) {
154 op.showEditor();
155 }
156 }
157 }
158
159
162 class LayoutAction extends AbstractAction
163 {
164 LayoutAction()
165 {
166 super("Route Edges");
167 }
168
169 public void actionPerformed(ActionEvent e)
170 {
171 Graph2D graph = view.getGraph2D();
172 addMazeGraph();
173 strategy.getModule().start(graph);
175 subtractMazeGraph();
176 }
177 }
178
179
185 protected void registerViewModes() {
186 EditMode mode = new EditMode();
187 view.addViewMode( mode );
188
189 mode.setMoveSelectionMode(new MyMoveSelectionMode());
190 mode.setCreateEdgeMode(new MyCreateEdgeMode());
191 mode.setHotSpotMode(new MyHotSpotMode());
192 }
193
194
197 class MyCreateEdgeMode extends CreateEdgeMode
198 {
199 private Node source;
200 protected boolean acceptSourceNode(Node s, double x, double y)
201 {
202 source = s;
203 return true;
204 }
205 protected boolean acceptTargetNode(Node t, double x, double y)
206 {
207 return (source != t);
208 }
209 protected void edgeCreated(final Edge e)
210 {
211 final Graph2D graph = view.getGraph2D();
212
213 addMazeGraph();
214 strategy.routeNewEdge(e);
215 subtractMazeGraph();
216 graph.updateViews();
217 }
218 }
219
220
223 class MyHotSpotMode extends HotSpotMode
224 {
225 public void mouseReleasedLeft(double x,double y)
226 {
227 super.mouseReleasedLeft(x, y);
228
229 final Graph2D graph = view.getGraph2D();
230
231 DataProvider selectedNodes = Selections.createSelectionDataProvider(graph);
232 addMazeGraph();
233 strategy.rerouteAdjacentEdges(selectedNodes, graph);
234 subtractMazeGraph();
235 graph.updateViews();
236 }
237 }
238
239
242 class MyMoveSelectionMode extends MoveSelectionMode
243 {
244 private static final boolean ROUTE_EDGES_ON_MOVE = false;
245
246 protected void selectionOnMove(double dx, double dy, double x, double y)
247 {
248 if (ROUTE_EDGES_ON_MOVE) {
249 routeEdgesToSelection();
250 }
251 }
252 protected void selectionMovedAction(double dx, double dy, double x, double y)
253 {
254 routeEdgesToSelection();
255 }
256
257 void routeEdgesToSelection()
258 {
259 final Graph2D graph = view.getGraph2D();
260
261 if (graph.selectedNodes().ok())
262 {
263 addMazeGraph();
264 strategy.routeEdgesToSelection(graph);
265 subtractMazeGraph();
266 graph.updateViews();
267 }
268 }
269 }
270
271
275 private void addMazeGraph()
276 {
277 mazeNodes = new NodeList(mazeG.nodes());
278 mazeG.moveSubGraph(mazeNodes, demoG);
279 }
280
281
284 private void subtractMazeGraph()
285 {
286 demoG.moveSubGraph(mazeNodes, mazeG);
287 }
288
291 private void initializeMaze()
292 {
293 mazeG = new Graph2D();
294 try {
295 GMLIOHandler ioHandler = new GMLIOHandler();
296 ioHandler.read(mazeG, getClass().getResource("resource/maze.gml"));
297 } catch (Exception e){
298 System.out.println("Could not initialize maze!");
299 e.printStackTrace();
300 System.exit(-1);
301 }
302 mazeD = new MazeDrawable(mazeG);
305 view.addBackgroundDrawable(mazeD);
306 view.fitRectangle(mazeD.getBounds());
307 }
308
309
312 public static void main(String[] args)
313 {
314 initLnF();
315 MazeRouterDemo demo = new MazeRouterDemo();
316 demo.start("Orthogonal Edge Router Maze Demo");
317 }
318
319
322 static class MazeDrawable implements Drawable
323 {
324 private Graph2D mazeG;
325 private DefaultGraph2DRenderer render;
326
327 public MazeDrawable(Graph2D g)
328 {
329 mazeG = g;
330 render = new DefaultGraph2DRenderer();
331 }
332
333 public Rectangle getBounds(){ return mazeG.getBoundingBox(); }
334 public void paint(Graphics2D gfx){ render.paint(gfx, mazeG); }
335 }
336
337 abstract static class RouterStrategy {
338 abstract YModule getModule();
339
340 abstract void routeNewEdge(Edge e);
341
342 abstract void rerouteAdjacentEdges(DataProvider selectedNodes, LayoutGraph graph);
343
344 abstract void routeEdgesToSelection(Graph2D graph);
345
346 abstract void route(Layouter router, LayoutGraph graph);
347
348 protected void routeNewEdge(Layouter router, final Edge e, Graph2D graph) {
349 EdgeMap spc = (EdgeMap) graph.getDataProvider(PortConstraintKeys.SOURCE_PORT_CONSTRAINT_KEY);
350 EdgeMap tpc = (EdgeMap) graph.getDataProvider(PortConstraintKeys.TARGET_PORT_CONSTRAINT_KEY);
351
352 PortConstraintConfigurator pcc = new PortConstraintConfigurator();
353 if (spc != null && tpc != null) {
354 spc.set(e, pcc.createPortConstraintFromSketch(graph, e, true, false));
355 tpc.set(e, pcc.createPortConstraintFromSketch(graph, e, false, false));
356 route(router, graph);
357 spc.set(e, null);
358 tpc.set(e, null);
359 } else {
360 route(router, graph);
361 }
362 }
363
364 protected void routeEdgesToSelection(final Graph2D graph, Layouter router, Object affectedEdgesKey) {
365 graph.addDataProvider(affectedEdgesKey, new DataProviderAdapter() {
366 public boolean getBool(Object dataHolder) {
367 return graph.isSelected(((Edge) dataHolder).source()) || graph.isSelected(((Edge) dataHolder).target());
368 }
369 });
370 route(router, graph);
371 graph.removeDataProvider(affectedEdgesKey);
372 }
373
374 protected void routeNewEdge(final Edge e, Graph2D graph, Layouter router, Object selectedEdgesKey) {
375 DataProvider activeEdges = new DataProviderAdapter() {
376 public boolean getBool(Object o) {
377 return e == o;
378 }
379 };
380 graph.addDataProvider(selectedEdgesKey, activeEdges);
381 routeNewEdge(router, e, graph);
382 graph.removeDataProvider(selectedEdgesKey);
383 }
384 }
385
386 static class OrthogonalEdgeRouterStrategy extends RouterStrategy {
387 private OrthogonalEdgeRouterModule module = new OrthogonalEdgeRouterModule();
388
389 public YModule getModule() {
390 return module;
391 }
392
393 public void routeNewEdge(final Edge e) {
394 Graph2D graph = (Graph2D) e.getGraph();
395 OrthogonalEdgeRouter router = new OrthogonalEdgeRouter();
396 module.configure(router);
397 router.setSphereOfAction(OrthogonalEdgeRouter.ROUTE_SELECTED_EDGES);
398 routeNewEdge(e, graph, router, Layouter.SELECTED_EDGES);
399 }
400
401 public void rerouteAdjacentEdges(DataProvider selectedNodes, LayoutGraph graph) {
402 OrthogonalEdgeRouter router = new OrthogonalEdgeRouter();
403 module.configure(router);
404 router.setSphereOfAction(OrthogonalEdgeRouter.ROUTE_EDGES_AT_SELECTED_NODES);
405 graph.addDataProvider(Layouter.SELECTED_NODES, selectedNodes);
406 this.route(router, graph);
407 graph.removeDataProvider(Layouter.SELECTED_NODES);
408 }
409
410 public void routeEdgesToSelection(final Graph2D graph) {
411 OrthogonalEdgeRouter router = new OrthogonalEdgeRouter();
412 module.configure(router);
413 router.setSphereOfAction(OrthogonalEdgeRouter.ROUTE_SELECTED_EDGES);
414 routeEdgesToSelection(graph, router, Layouter.SELECTED_EDGES);
415 }
416
417 void route(Layouter router, LayoutGraph graph) {
418 router.doLayout(graph);
419 }
420 }
421
422 static class ChannelEdgeRouterStrategy extends RouterStrategy {
423 private ChannelEdgeRouterModule module;
424
425 public ChannelEdgeRouterStrategy(){
426 module = new ChannelEdgeRouterModule();
427 module.getOptionHandler().set("PATHFINDER", "ORTHOGONAL_SHORTESTPATH_PATH_FINDER");
428 }
429
430 public YModule getModule() {
431 return module;
432 }
433
434 public void routeNewEdge(final Edge e) {
435 final Graph2D graph = (Graph2D) e.getGraph();
436 ChannelEdgeRouter router = new ChannelEdgeRouter();
437 module.configure(router);
438 routeNewEdge(e, graph, router, ChannelEdgeRouter.AFFECTED_EDGES);
439 }
440
441 public void rerouteAdjacentEdges(final DataProvider selectedNodes, LayoutGraph graph) {
442 ChannelEdgeRouter router = new ChannelEdgeRouter();
443 module.configure(router);
444 graph.addDataProvider(ChannelEdgeRouter.AFFECTED_EDGES, new DataProviderAdapter() {
445 public boolean getBool(Object dataHolder) {
446 return selectedNodes.getBool((((Edge) dataHolder).source())) || selectedNodes.getBool(((Edge) dataHolder).target());
447 }
448 });
449 this.route(router, graph);
450 graph.removeDataProvider(ChannelEdgeRouter.AFFECTED_EDGES);
451 }
452
453 public void routeEdgesToSelection(final Graph2D graph) {
454 ChannelEdgeRouter router = new ChannelEdgeRouter();
455 module.configure(router);
456 routeEdgesToSelection(graph, router, ChannelEdgeRouter.AFFECTED_EDGES);
457 }
458
459 void route(Layouter router, LayoutGraph graph) {
460 router.doLayout(graph);
461 }
462 }
463 }
464