1
14 package demo.view.layout.hierarchic;
15
16 import demo.module.HierarchicLayoutModule;
17 import demo.view.DemoBase;
18 import y.base.Edge;
19 import y.base.EdgeCursor;
20 import y.base.EdgeMap;
21 import y.base.Node;
22 import y.base.NodeCursor;
23 import y.base.NodeMap;
24 import y.layout.LabelLayoutConstants;
25 import y.layout.PortConstraint;
26 import y.layout.PortConstraintConfigurator;
27 import y.layout.PortConstraintKeys;
28 import y.layout.hierarchic.ClassicLayerSequencer;
29 import y.view.Arrow;
30 import y.view.EdgeLabel;
31 import y.view.EdgeRealizer;
32 import y.view.EditMode;
33 import y.view.Graph2D;
34 import y.view.Graph2DSelectionEvent;
35 import y.view.Graph2DSelectionListener;
36 import y.view.PortAssignmentMoveSelectionMode;
37
38 import javax.swing.AbstractAction;
39 import javax.swing.BorderFactory;
40 import javax.swing.ButtonGroup;
41 import javax.swing.ButtonModel;
42 import javax.swing.JButton;
43 import javax.swing.JCheckBox;
44 import javax.swing.JComboBox;
45 import javax.swing.JPanel;
46 import javax.swing.JRadioButton;
47 import javax.swing.JToolBar;
48 import javax.swing.JScrollPane;
49 import java.awt.BorderLayout;
50 import java.awt.Color;
51 import java.awt.GridBagLayout;
52 import java.awt.GridBagConstraints;
53 import java.awt.event.ActionEvent;
54 import java.awt.event.ActionListener;
55
56
142
143 public class HierarchicLayouterDemo extends DemoBase
144 {
145 private static final String EDGE_LABELING = "EDGE_LABELING";
146 private static final String HIERARCHIC = "HIERARCHIC";
147 private static final String NONE = "NONE";
148
149 private PortSpec sourceSpec, targetSpec;
150 private EdgeMap sourceGroupIdMap, targetGroupIdMap;
151 private JCheckBox labelBox;
152 private EdgeMap sourcePortMap;
153 private EdgeMap targetPortMap;
154
155 private HierarchicLayoutModule layoutModule;
156
157 private NodeMap groupMap;
158 private PortAssignmentMoveSelectionMode paMode;
159
160 public HierarchicLayouterDemo()
161 {
162 final Graph2D graph = view.getGraph2D();
163 groupMap = graph.createNodeMap();
164 graph.addDataProvider(ClassicLayerSequencer.GROUP_KEY, groupMap);
165 EdgeRealizer defaultER = graph.getDefaultEdgeRealizer();
166 defaultER.setArrow(Arrow.STANDARD);
167
168 sourcePortMap = graph.createEdgeMap();
169 targetPortMap = graph.createEdgeMap();
170 sourceGroupIdMap = graph.createEdgeMap();
171 targetGroupIdMap = graph.createEdgeMap();
172 graph.addDataProvider(PortConstraintKeys.SOURCE_GROUPID_KEY, sourceGroupIdMap);
173 graph.addDataProvider(PortConstraintKeys.TARGET_GROUPID_KEY, targetGroupIdMap);
174 graph.addDataProvider(PortConstraintKeys.SOURCE_PORT_CONSTRAINT_KEY,sourcePortMap);
175 graph.addDataProvider(PortConstraintKeys.TARGET_PORT_CONSTRAINT_KEY,targetPortMap);
176
177 paMode.setSpc(sourcePortMap);
178 paMode.setTpc(targetPortMap);
179
180
181 JPanel left = new JPanel(new GridBagLayout());
182 GridBagConstraints gbc = new GridBagConstraints();
183 gbc.fill = GridBagConstraints.BOTH;
184 gbc.anchor = GridBagConstraints.NORTHWEST;
185 gbc.gridx = 0;
186
187 left.add(new JButton(new AbstractAction("Parse Ports"){
188 public void actionPerformed(ActionEvent ae){
189 new PortConstraintConfigurator()
190 .createPortConstraintsFromSketch(graph, sourcePortMap, targetPortMap);
191 }
192 }), gbc);
193
194 gbc.gridx = 1;
195
196 labelBox = new JCheckBox("Label Edges");
197 labelBox.addActionListener(new ActionListener() {
198 public void actionPerformed(ActionEvent ev)
199 {
200 setLabelEdges(labelBox.isSelected());
201 }
202 });
203
204 left.add(labelBox);
205
206 sourceSpec = new PortSpec("Source Port", sourcePortMap, sourceGroupIdMap);
207 targetSpec = new PortSpec("Target Port", targetPortMap, targetGroupIdMap);
208 gbc.gridx = 0;
209 gbc.gridy = 1;
210 left.add(sourceSpec, gbc);
211 gbc.gridx = 1;
212 left.add(targetSpec, gbc);
213 gbc.gridx = 0;
214 gbc.gridy = GridBagConstraints.RELATIVE;
215
216 JPanel groupSpec;
217 groupSpec = new JPanel(new GridBagLayout());
218 groupSpec.setBorder(BorderFactory.createTitledBorder("Node Groups"));
219
220 Color[] groupColors = new Color[]{ null, Color.blue, Color.yellow, Color.red };
222
223 for (int i = 0; i < groupColors.length; i++){
224 JButton groupButton = new GroupButton(groupColors[i], i);
225 groupSpec.add(groupButton, gbc);
226 }
227 gbc.weightx = gbc.weighty = 1;
228 groupSpec.add(new JPanel(), gbc);
229 gbc.weightx = gbc.weighty = 0;
230 gbc.gridwidth = 2;
231 left.add(groupSpec, gbc);
232 gbc.gridwidth = 1;
233
234 gbc.weighty = 1.0d;
235 left.add(new JPanel(), gbc);
236
237 contentPane.add(new JScrollPane(left), BorderLayout.WEST);
238
239 graph.addGraph2DSelectionListener(new Graph2DSelectionListener() {
240 public void onGraph2DSelectionEvent(Graph2DSelectionEvent ev)
241 {
242 if(ev.getSubject() instanceof Edge)
243 {
244 Edge e = (Edge)ev.getSubject();
245 if(ev.getGraph2D().isSelected(e))
246 {
247 PortConstraint pc = getSPC(e);
248 sourceSpec.setSide(pc.getSide());
249 sourceSpec.setStrong(pc.isStrong());
250 sourceSpec.setGroupId(sourceGroupIdMap.get(e));
251 pc = getTPC(e);
252 targetSpec.setSide(pc.getSide());
253 targetSpec.setStrong(pc.isStrong());
254 targetSpec.setGroupId(targetGroupIdMap.get(e));
255 }
256 }
257 }
258 });
259
260 layoutModule = new HierarchicLayoutModule();
261 }
262
263 protected JToolBar createToolBar()
264 {
265 JToolBar bar = super.createToolBar();
266 bar.add(new LayoutAction());
267 bar.add(new OptionAction());
268 return bar;
269 }
270
271
275 protected void assignGroup(Color color, int index){
276 Graph2D graph = view.getGraph2D();
277 for(NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next())
278 {
279 Node n = nc.node();
280 if (color == null){
281 color = graph.getDefaultNodeRealizer().getFillColor();
282 groupMap.set(n, null);
284 } else {
285 groupMap.setInt(n, index);
287 }
288 graph.getRealizer(n).setFillColor(color);
290
291 }
292 graph.updateViews();
293 }
294
295
296 class GroupButton extends JButton implements ActionListener{
298 Color color;
299 int index;
300 GroupButton(Color color, int index){
301 super("");
302 setText(index > 0? "Group "+index : "No Group");
303 this.color = color;
304 this.index = index;
305 setBackground(color);
306 this.addActionListener(this);
307 }
308
309 public void actionPerformed(ActionEvent e)
310 {
311 HierarchicLayouterDemo.this.assignGroup(color, index);
312 }
313 }
314
315 class LayoutAction extends AbstractAction
316 {
317 LayoutAction()
318 {
319 super("Layout");
320 }
321
322 public void actionPerformed(ActionEvent ev)
323 {
324
325 Graph2D graph = view.getGraph2D();
326 layoutModule.start(graph);
337 }
338 }
339
340 class OptionAction extends AbstractAction
341 {
342 OptionAction()
343 {
344 super("Option...");
345 }
346
347 public void actionPerformed(ActionEvent ev)
348 {
349 layoutModule.getOptionHandler().showEditor();
350 }
351 }
352
353
354
355 PortConstraint getSPC(Edge e)
356 {
357 PortConstraint pc = (e != null) ? (PortConstraint)sourcePortMap.get(e) : null;
358
359 if (pc == null) pc = PortConstraint.create(PortConstraint.ANY_SIDE);
360
361 return pc;
362 }
363
364 PortConstraint getTPC(Edge e)
365 {
366 PortConstraint pc = (e != null) ? (PortConstraint)targetPortMap.get(e) : null;
367
368 if (pc == null) pc = PortConstraint.create(PortConstraint.ANY_SIDE);
369
370 return pc;
371 }
372
373 void setPC(EdgeMap portMap,EdgeMap groupMap, byte side, boolean strong, Object groupId)
374 {
375 Graph2D graph = view.getGraph2D();
376 PortConstraint pc = PortConstraint.create(side, strong);
377 String preText = pc.toString();
378 if (groupId != null){
379 preText = preText + '[' + groupId + ']';
380 }
381 for(EdgeCursor ec = graph.selectedEdges(); ec.ok(); ec.next())
382 {
383 Edge e = ec.edge();
384 portMap.set(e,pc);
385 getSPC(e);
386 getTPC(e);
387 groupMap.set(e, groupId);
388 if(graph.getRealizer(e).labelCount() >= 2)
389 {
390 String text = portMap == sourcePortMap ? "source " + preText: "target" + preText;
391 graph.getRealizer(e).getLabel(portMap == sourcePortMap ? 0 : 1).setText(text);
392 }
393 }
394 graph.updateViews();
395 }
396
397
400 public static void main(String args[])
401 {
402 initLnF();
403 HierarchicLayouterDemo demo = new HierarchicLayouterDemo();
404
405 demo.start("Hierarchic Layouter Demo");
406 }
407
408
409
410 class PortSpec extends JPanel
411 {
412 JRadioButton anySideB, northB, southB, eastB, westB;
413 JCheckBox cb;
414 JComboBox box;
415 EdgeMap portMap;
416 EdgeMap groupMap;
417
418 Object[] items = new Object[]{"no Group",new Integer(1), new Integer(2), new Integer(3), new Integer(4),
419 new Integer(5), new Integer(6), new Integer(7)};
420
421 PortSpec(String title, EdgeMap portMap, EdgeMap groupMap)
422 {
423 super(new GridBagLayout());
424 GridBagConstraints gbc = new GridBagConstraints();
425 gbc.fill = GridBagConstraints.BOTH;
426 gbc.gridx = 0;
427 gbc.anchor = GridBagConstraints.NORTHWEST;
428 this.setBorder(BorderFactory.createTitledBorder(title));
429 this.portMap = portMap;
430 this.groupMap = groupMap;
431 final ButtonGroup bg = new ButtonGroup();
432
433
434 anySideB = new JRadioButton("ANY_SIDE");
435 northB = new JRadioButton("NORTH");
436 southB = new JRadioButton("SOUTH");
437 eastB = new JRadioButton("EAST");
438 westB = new JRadioButton("WEST");
439 anySideB.setSelected(true);
440
441 cb = new JCheckBox("Strong");
442
443
444 box = new JComboBox(items);
445
446 ActionListener rl = new ActionListener() {
447 public void actionPerformed(ActionEvent ev) {
448 ButtonModel bm = bg.getSelection();
449 byte side = PortConstraint.ANY_SIDE;
450 if ( bm == southB.getModel() ) {
451 side = PortConstraint.SOUTH;
452 } else if ( bm == northB.getModel() ) {
453 side = PortConstraint.NORTH;
454 } else if ( bm == eastB.getModel() ) {
455 side = PortConstraint.EAST;
456 } else if ( bm == westB.getModel() ) side = PortConstraint.WEST;
457 boolean strong = cb.isSelected();
458 Object groupId = box.getSelectedItem();
459 if (groupId instanceof String){
460 groupId = null;
461 }
462 setPC(PortSpec.this.portMap, PortSpec.this.groupMap, side, strong, groupId);
463 }
464 };
465
466 addButton(anySideB, bg, rl, gbc);
467 addButton(northB, bg, rl, gbc);
468 addButton(southB, bg, rl, gbc);
469 addButton(eastB, bg, rl, gbc);
470 addButton(westB, bg, rl, gbc);
471 this.add(cb, gbc);
472 this.add(box, gbc);
473 box.addActionListener(rl);
474 cb.addActionListener(rl);
475 }
476
477 void addButton(JRadioButton b, ButtonGroup bg, ActionListener rl, GridBagConstraints gbc)
478 {
479 bg.add(b);
480 this.add(b, gbc);
481 b.addActionListener(rl);
482 }
483
484 void setSide(byte side)
485 {
486 switch(side) {
487 case PortConstraint.ANY_SIDE:
488 anySideB.setSelected(true);
489 break;
490 case PortConstraint.NORTH:
491 northB.setSelected(true);
492 break;
493 case PortConstraint.SOUTH:
494 southB.setSelected(true);
495 break;
496 case PortConstraint.WEST:
497 westB.setSelected(true);
498 break;
499 case PortConstraint.EAST:
500 eastB.setSelected(true);
501 break;
502 }
503 }
504
505 void setStrong(boolean strong){
506 cb.setSelected(strong);
507 }
508
509 void setGroupId(Object id){
510 if (id == null){
511 box.setSelectedIndex(0);
512 } else {
513 box.setSelectedItem(id);
514 }
515 }
516 }
517
518 void setLabelEdges(boolean labelEdges)
519 {
520 Graph2D graph = view.getGraph2D();
521
522 if(labelEdges)
523 {
524 addLabels(graph.getDefaultEdgeRealizer());
525 for(EdgeCursor ec = graph.edges(); ec.ok();ec.next())
526 {
527 addLabels(graph.getRealizer(ec.edge()));
528 }
529 layoutModule.getOptionHandler().set(EDGE_LABELING,HIERARCHIC);
530 }
531 else
532 {
533 removeLabels(graph.getDefaultEdgeRealizer());
534 for(EdgeCursor ec = graph.edges(); ec.ok();ec.next())
535 {
536 removeLabels(graph.getRealizer(ec.edge()));
537 }
538 layoutModule.getOptionHandler().set(EDGE_LABELING, NONE);
539 }
540
541 view.updateView();
542
543 }
544
545
546 void addLabels(EdgeRealizer er)
547 {
548 removeLabels(er);
549
550 EdgeLabel el = new EdgeLabel(getSPC(er.getEdge()).toString());
551 el.setModel(EdgeLabel.CENTER_SLIDER);
552 el.setPosition(EdgeLabel.SCENTR);
553 el.setPreferredPlacement(LabelLayoutConstants.PLACE_AT_SOURCE);
554 er.addLabel(el);
555
556
557 el = new EdgeLabel(getTPC(er.getEdge()).toString());
558 el.setModel(EdgeLabel.CENTER_SLIDER);
559 el.setPosition(EdgeLabel.TCENTR);
560 el.setPreferredPlacement(LabelLayoutConstants.PLACE_AT_TARGET);
561 er.addLabel(el);
562
563 el = new EdgeLabel("Center");
564 el.setModel(EdgeLabel.CENTER_SLIDER);
565 el.setPosition(EdgeLabel.CENTER);
566 el.setPreferredPlacement(LabelLayoutConstants.PLACE_AT_CENTER);
567 er.addLabel(el);
568 }
569
570 void removeLabels(EdgeRealizer er)
571 {
572 while(er.labelCount() > 0) er.removeLabel(er.getLabel(er.labelCount()-1));
573 }
574
575 protected void registerViewModes() {
576 EditMode mode = new EditMode();
577 mode.setMoveSelectionMode(paMode = new PortAssignmentMoveSelectionMode(null, null));
578 view.addViewMode( mode );
579 }
580 }
581