1
14 package demo.view.hierarchy;
15
16 import demo.view.DemoBase;
17 import y.algo.GraphConnectivity;
18 import y.algo.Trees;
19 import y.base.EdgeCursor;
20 import y.base.Graph;
21 import y.base.Node;
22 import y.base.NodeCursor;
23 import y.base.NodeList;
24 import y.geom.YPoint;
25 import y.module.LaunchModuleAction;
26 import y.view.Arrow;
27 import y.view.EditMode;
28 import y.view.Graph2D;
29 import y.view.NodeLabel;
30 import y.view.NodeRealizer;
31 import y.view.Overview;
32 import y.view.PopupMode;
33 import y.view.ProxyShapeNodeRealizer;
34 import y.view.ViewMode;
35 import y.view.hierarchy.DefaultNodeChangePropagator;
36 import y.view.hierarchy.GroupNodeRealizer;
37 import y.view.hierarchy.HierarchyEditMode;
38 import y.view.hierarchy.HierarchyJTree;
39 import y.view.hierarchy.HierarchyManager;
40 import y.view.hierarchy.HierarchyTreeModel;
41 import y.view.hierarchy.HierarchyTreeTransferHandler;
42 import y.view.hierarchy.DefaultHierarchyGraphFactory;
43 import y.view.hierarchy.ProxyAutoBoundsNodeRealizer;
44 import y.layout.LayoutTool;
45 import y.layout.BufferedLayouter; import y.layout.tree.BalloonLayouter; import y.layout.tree.TreeReductionStage;
49 import javax.swing.AbstractAction;
50 import javax.swing.Action;
51 import javax.swing.JMenu;
52 import javax.swing.JMenuBar;
53 import javax.swing.JMenuItem;
54 import javax.swing.JPanel;
55 import javax.swing.JPopupMenu;
56 import javax.swing.JScrollPane;
57 import javax.swing.JSplitPane;
58 import javax.swing.JToolBar;
59 import javax.swing.JTree;
60 import java.awt.BorderLayout;
61 import java.awt.Dimension;
62 import java.awt.Rectangle;
63 import java.awt.event.ActionEvent;
64 import java.awt.event.MouseEvent;
65 import java.awt.geom.Rectangle2D;
66
67
108 public class HierarchyDemo extends DemoBase
109 {
110
111
115 protected HierarchyManager hierarchy;
116
117
118
121 public HierarchyDemo()
122 {
123 Graph2D rootGraph = view.getGraph2D();
124
125 rootGraph.getDefaultEdgeRealizer().setTargetArrow(Arrow.STANDARD);
127
128 hierarchy = new HierarchyManager(rootGraph);
130
131 hierarchy.addHierarchyListener(new GroupNodeRealizer.StateChangeListener());
134
135 rootGraph.addGraph2DListener(new DefaultNodeChangePropagator());
138
139 HierarchyTreeModel htm = new HierarchyTreeModel(hierarchy);
141
142 htm.setChildComparator(HierarchyTreeModel.createNodeStateComparator(hierarchy));
144
145 JTree tree = new HierarchyJTree(hierarchy, htm);
147
148 tree.addMouseListener(new HierarchyJTreeDoubleClickListener(view));
150
151 tree.setDragEnabled(true);
154 tree.setTransferHandler(new HierarchyTreeTransferHandler(hierarchy));
155
156
157 view.addViewMode(new HierarchicClickViewMode());
160
161 JScrollPane scrollPane = new JScrollPane(tree);
163 scrollPane.setPreferredSize(new Dimension(150,0));
164 JPanel leftPane = new JPanel(new BorderLayout());
165
166 view.fitContent();
167
168 Overview overView = new Overview(view);
169 overView.setPreferredSize(new Dimension(150,150));
170 leftPane.add(overView,BorderLayout.NORTH);
171 leftPane.add(scrollPane);
172
173 JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPane, view);
174
175 contentPane.add(splitPane,BorderLayout.CENTER);
176
177 loadInitialGraph();
178 for (NodeCursor nc = rootGraph.nodes(); nc.ok(); nc.next()) {
181 Node n = nc.node();
182 if (hierarchy.isNormalNode(n)) {
183 rootGraph.setDefaultNodeRealizer(rootGraph.getRealizer(n).createCopy());
184 break;
185 }
186 }
187 for (NodeCursor nc = rootGraph.nodes(); nc.ok(); nc.next()) {
188 Node n = nc.node();
189 if (!hierarchy.isNormalNode(n)) {
190 DefaultHierarchyGraphFactory hgf = (DefaultHierarchyGraphFactory) hierarchy.getGraphFactory();
191 if (rootGraph.getRealizer(n) instanceof ProxyAutoBoundsNodeRealizer) {
192 hgf.setProxyNodeRealizerEnabled(true);
193 ProxyAutoBoundsNodeRealizer pnr = (ProxyAutoBoundsNodeRealizer) rootGraph.getRealizer(n);
194 hgf.setDefaultGroupNodeRealizer(pnr.getRealizer(0).createCopy());
195 hgf.setDefaultFolderNodeRealizer(pnr.getRealizer(1).createCopy());
196 break;
197 }
198 }
199 }
200 }
201
202 protected void loadInitialGraph() {
203 loadGraph("resource/hierarchy.ygf");
204 }
205
206
209 protected JToolBar createToolBar()
210 {
211 JToolBar jtb = super.createToolBar();
212 jtb.add(new ViewParentAction());
213 return jtb;
214 }
215
216 protected JMenuBar createMenuBar(){
217 JMenuBar mb = super.createMenuBar();
218 JMenu menu = new JMenu("Tools");
219 menu.add(new JMenuItem(new FoldComponentsAction()));
220 menu.add(new JMenuItem(new FoldSubtreesAction()));
221 menu.add(new JMenuItem(new UnfoldAllAction()));
222
223 menu.addSeparator(); Action a; a = new LaunchModuleAction(view, new demo.module.HierarchicLayoutModule()); a.putValue(Action.NAME, "Hierarchical Layout"); menu.add(a); a = new LaunchModuleAction(view, new demo.module.OrthogonalLayoutModule()); a.putValue(Action.NAME, "Orthogonal Layout"); menu.add(a); a = new LaunchModuleAction(view, new demo.module.OrganicLayoutModule()); a.putValue(Action.NAME, "Organic Layout"); menu.add(a); mb.add(menu);
239 menu.addSeparator();
240 menu.add(new JMenuItem(new LoadInitialGraphAction()));
241
242 return mb;
243 }
244
245 protected EditMode createEditMode() {
246 EditMode mode = new HierarchyEditMode();
247 mode.setPopupMode(new HierarchicPopupMode());
249 return mode;
250 }
251
252 protected void registerViewModes() {
253 view.addViewMode(createEditMode());
254 }
255
256
257
260 public static void main(String[] args)
261 {
262 initLnF();
263 (new HierarchyDemo()).start("Hierarchy Demo");
264 }
265
266
267
271
274 class HierarchicPopupMode extends PopupMode
275 {
276 public JPopupMenu getPaperPopup(double x, double y)
277 {
278 return addFolderPopupItems(new JPopupMenu(), x,y, null, false);
279 }
280
281 public JPopupMenu getNodePopup(Node v)
282 {
283 Graph2D graph = getGraph2D();
284 return addFolderPopupItems(new JPopupMenu(),
285 graph.getCenterX(v),
286 graph.getCenterY(v),
287 v, true);
288 }
289
290 public JPopupMenu getSelectionPopup(double x, double y)
291 {
292 return addFolderPopupItems(new JPopupMenu(),x,y, null, getGraph2D().selectedNodes().ok());
293 }
294
295 JPopupMenu addFolderPopupItems(JPopupMenu pm, double x, double y, Node node, boolean selected)
296 {
297 AbstractAction action;
298 action = new GroupSelectionAction(x, y);
299 pm.add(action);
300 action = new UngroupSelectionAction();
301 pm.add(action);
302 action = new CloseGroupAction(node);
303 action.setEnabled(node != null && hierarchy.isGroupNode(node));
304 pm.add(action);
305 pm.addSeparator();
306 action = new CreateFolderNodeAction(getGraph2D(),x,y);
307 action.setEnabled(node == null);
308 pm.add(action);
309 action = new FoldSelectionAction();
310 action.setEnabled(selected);
311 pm.add(action);
312 action = new UnfoldSelectionAction();
313 action.setEnabled(selected && !hierarchy.isRootGraph(getGraph2D()));
314 pm.add(action);
315 action = new ExtractFolderAction(node);
316 action.setEnabled(node != null && hierarchy.isFolderNode(node));
317 pm.add(action);
318 action = new OpenFolderAction(node);
319 action.setEnabled(node != null && hierarchy.isFolderNode(node));
320 pm.add(action);
321 action = new RemoveGroupAction(node);
322 action.setEnabled(node != null && hierarchy.isGroupNode(node));
323 pm.add(action);
324 return pm;
325 }
326 }
327
328
332 class HierarchicClickViewMode extends ViewMode
333 {
334 public void mouseClicked(MouseEvent e)
335 {
336 if(e.getClickCount() == 2)
337 {
338 Node v = getHitInfo(e).getHitNode();
339 if(v != null)
340 {
341 navigateToInnerGraph(v);
342 }
343 else
344 {
345 navigateToParentGraph();
346 }
347 } else {
348 Node v = getHitInfo(e).getHitNode();
349 if(v != null && !hierarchy.isNormalNode(v))
350 {
351 double x = translateX(e.getX());
352 double y = translateY(e.getY());
353 Graph2D graph = this.view.getGraph2D();
354 NodeRealizer r = graph.getRealizer(v);
355 GroupNodeRealizer gnr = null;
356 if(r instanceof GroupNodeRealizer)
357 {
358 gnr = (GroupNodeRealizer)r;
359 }
360 else if(r instanceof ProxyShapeNodeRealizer &&
361 ((ProxyShapeNodeRealizer)r).getRealizerDelegate() instanceof GroupNodeRealizer)
362 {
363 gnr = (GroupNodeRealizer)((ProxyShapeNodeRealizer)r).getRealizerDelegate();
364 }
365 if(gnr != null)
366 {
367 NodeLabel handle = gnr.getStateLabel();
368 if(handle.getBox().contains(x,y))
369 {
370 if(hierarchy.isFolderNode(v))
371 {
372 openFolder(v);
373 }
374 else
375 {
376 closeGroup(v);
377 }
378 }
379 }
380 }
381 }
382 }
383 }
384
385
389
392 public void navigateToInnerGraph(Node folderNode)
393 {
394 if(hierarchy.isFolderNode(folderNode))
395 {
396 Graph2D innerGraph = (Graph2D)hierarchy.getInnerGraph(folderNode);
397 Rectangle box = innerGraph.getBoundingBox();
398 view.setGraph2D(innerGraph);
399 view.setCenter(box.x+box.width/2,box.y+box.height/2);
400 innerGraph.updateViews();
401 }
402 }
403
404
408 public void navigateToParentGraph()
409 {
410 Graph2D graph = view.getGraph2D();
411 if(!hierarchy.isRootGraph(graph))
412 {
413 Graph2D parentGraph = (Graph2D)hierarchy.getParentGraph(graph);
414 view.setGraph2D(parentGraph);
415 Node anchor = hierarchy.getAnchorNode(graph);
416 view.setZoom(1.0);
417 view.setCenter(parentGraph.getCenterX(anchor),parentGraph.getCenterY(anchor));
418 view.getGraph2D().updateViews();
419 }
420 }
421
422
426 void foldSelection()
427 {
428 Graph2D graph = view.getGraph2D();
429 Node folderNode = hierarchy.createFolderNode(graph);
430 graph.setLabelText(folderNode, "Folder");
431
432 hierarchy.foldSubgraph(new NodeList(graph.selectedNodes()), folderNode);
433
434 Graph2D innerGraph = (Graph2D)hierarchy.getInnerGraph(folderNode);
435 innerGraph.unselectAll();
436
437 Rectangle box = innerGraph.getBoundingBox();
438 graph.setSize(folderNode,box.width+10, box.height+10);
439 graph.setLocation(folderNode,box.x-5,box.y-5);
440 graph.updateViews();
441 }
442
443
444
449 void unfoldSelection()
450 {
451 Graph2D graph = view.getGraph2D();
452 NodeList selectedNodes = new NodeList(graph.selectedNodes());
453
454 if(!selectedNodes.isEmpty() && !hierarchy.isRootGraph(graph))
455 {
456 hierarchy.unfoldSubgraph(graph, selectedNodes );
457 }
458 graph.updateViews();
459 }
460
461
465 void extractFolder(Node folderNode)
466 {
467 Graph2D graph = (Graph2D)folderNode.getGraph();
468 Graph innerGraph = hierarchy.getInnerGraph(folderNode);
469 NodeList subNodes = new NodeList(innerGraph.nodes());
470 hierarchy.unfoldSubgraph(innerGraph, subNodes);
471
472 graph.removeNode(folderNode);
475
476 for(NodeCursor nc = subNodes.nodes(); nc.ok(); nc.next())
478 {
479 graph.setSelected(nc.node(),true);
480 }
481
482 graph.updateViews();
483 }
484
485
489 void foldComponents()
490 {
491 Graph2D graph = view.getGraph2D();
492 for (NodeCursor nodeCursor = graph.nodes(); nodeCursor.ok(); nodeCursor.next()) {
494 Node node = nodeCursor.node();
495 if(hierarchy.isGroupNode(node)){
496 graph.removeNode(node);
497 }
498 }
499
500 NodeList[] components = GraphConnectivity.connectedComponents(graph);
501
502 if(components.length > 1)
503 {
504 for(int i = 0; i < components.length; i++)
505 {
506 NodeList subNodes = components[i];
507 Node folderNode = hierarchy.createFolderNode(graph);
508 graph.setCenter(folderNode,150*(i+1),0);
509 graph.setLabelText(folderNode,"Comp " + (i+1));
510 hierarchy.setParentNode(subNodes, folderNode);
511 }
512 view.fitContent();
513 view.getGraph2D().updateViews();
514 }
515
516 }
517
518
530 void foldSubtrees()
531 {
532 Graph2D graph = view.getGraph2D();
533
534 for (NodeCursor nodeCursor = graph.nodes(); nodeCursor.ok(); nodeCursor.next()) {
536 Node node = nodeCursor.node();
537 if(hierarchy.isGroupNode(node)){
538 graph.removeNode(node);
539 }
540 }
541
542 NodeList[] trees = Trees.getTreeNodes(graph);
543
544 for(int i = 0; i < trees.length; i++)
545 {
546 NodeList tree = trees[i];
547
548 Node folderNode = hierarchy.createFolderNode(graph);
549
550 hierarchy.foldSubgraph(tree, folderNode);
551
552 Graph2D innerGraph = (Graph2D)hierarchy.getInnerGraph(folderNode);
553
554 BalloonLayouter balloonLayouter = new BalloonLayouter(); balloonLayouter.appendStage(new TreeReductionStage()); new BufferedLayouter(balloonLayouter).doLayout(innerGraph);
558 Node root = tree.firstNode();
560 String rootName = innerGraph.getLabelText(root);
561 graph.setLabelText(folderNode,rootName + " Tree");
562
563 Rectangle box = innerGraph.getBoundingBox();
564 if(box.height > box.width)
565 {
566 graph.setSize(folderNode, Math.max(150*box.width/box.height, 40), 170);
567 }
568 else
569 {
570 graph.setSize(folderNode, 150, Math.max(40,150*box.height/box.width+20));
571 }
572 }
573
574 view.fitContent();
575 graph.updateViews();
576 }
577
578
581 void unfoldAll()
582 {
583 NodeList result = hierarchy.getFolderNodes(view.getGraph2D(),true);
584 while(!result.isEmpty())
585 {
586 Node folderNode = result.popNode();
587 extractFolder(folderNode);
588 }
589 }
590
591
592 protected void closeGroup(Node groupNode)
593 {
594 Graph2D graph = view.getGraph2D();
595
596 final double w = graph.getWidth(groupNode);
597 final double h = graph.getHeight(groupNode);
598
599 NodeList groupNodes = new NodeList();
600 if(groupNode == null)
601 {
602 for(NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next())
604 {
605 Node v = nc.node();
606 if(hierarchy.isGroupNode(v) && hierarchy.getLocalGroupDepth(v) == 0)
607 {
608 groupNodes.add(v);
609 }
610 }
611 }
612 else
613 {
614 groupNodes.add(groupNode);
615 }
616
617 graph.firePreEvent();
618 for(NodeCursor nc = groupNodes.nodes(); nc.ok(); nc.next())
619 {
620 hierarchy.closeGroup(nc.node());
621 }
622 graph.firePostEvent();
623
624 graph.unselectAll();
625 for(NodeCursor nc = groupNodes.nodes(); nc.ok(); nc.next())
626 {
627 graph.setSelected(nc.node(), true);
628 }
629
630 if (w != graph.getWidth(groupNode) || h != graph.getHeight(groupNode)) {
634 for (EdgeCursor ec = groupNode.outEdges(); ec.ok(); ec.next()) {
635 graph.setSourcePointRel(ec.edge(), YPoint.ORIGIN);
636 }
637 for (EdgeCursor ec = groupNode.inEdges(); ec.ok(); ec.next()) {
638 graph.setTargetPointRel(ec.edge(), YPoint.ORIGIN);
639 }
640 }
641
642 graph.updateViews();
643 }
644
645 protected void removeGroup(Node groupNode){
646 hierarchy.removeGroupNode(groupNode);
647 }
648
649 protected void openFolder(Node folderNode)
650 {
651 Graph2D graph = view.getGraph2D();
652
653 final double w = graph.getWidth(folderNode);
654 final double h = graph.getHeight(folderNode);
655
656 NodeList folderNodes = new NodeList();
657 if(folderNode == null)
658 {
659 for(NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next())
661 {
662 Node v = nc.node();
663 if(hierarchy.isFolderNode(v))
664 {
665 folderNodes.add(v);
666 }
667 }
668 }
669 else
670 {
671 folderNodes.add(folderNode);
672 }
673
674 graph.firePreEvent();
675
676 for(NodeCursor nc = folderNodes.nodes(); nc.ok(); nc.next())
677 {
678 Graph2D innerGraph = (Graph2D)hierarchy.getInnerGraph(nc.node());
680 YPoint folderP = graph.getLocation(nc.node());
681 NodeList innerNodes = new NodeList(innerGraph.nodes());
682
683 hierarchy.openFolder(nc.node());
684
685 Rectangle2D.Double gBox = graph.getRealizer(nc.node()).getBoundingBox();
687 LayoutTool.moveSubgraph(graph, innerNodes.nodes(),
689 folderP.x - gBox.x,
690 folderP.y - gBox.y);
691 }
692 graph.firePostEvent();
693
694
695 graph.unselectAll();
696 for(NodeCursor nc = folderNodes.nodes(); nc.ok(); nc.next())
697 {
698 graph.setSelected(nc.node(), true);
699 }
700
701 if (w != graph.getWidth(folderNode) || h != graph.getHeight(folderNode)) {
705 for (EdgeCursor ec = folderNode.outEdges(); ec.ok(); ec.next()) {
706 graph.setSourcePointRel(ec.edge(), YPoint.ORIGIN);
707 }
708 for (EdgeCursor ec = folderNode.inEdges(); ec.ok(); ec.next()) {
709 graph.setTargetPointRel(ec.edge(), YPoint.ORIGIN);
710 }
711 }
712
713 graph.updateViews();
714 }
715
716 void groupSelection(double x, double y)
717 {
718 Graph2D graph = view.getGraph2D();
719
720 graph.firePreEvent();
721
722 NodeList subNodes = new NodeList(graph.selectedNodes());
723 Node groupNode;
724 if(subNodes.isEmpty())
725 {
726 groupNode = hierarchy.createGroupNode(graph);
727 if(Double.isNaN(x) || Double.isNaN(y))
728 {
729 x = view.getCenter().getX();
730 y = view.getCenter().getY();
731 }
732 graph.setCenter(groupNode, x,y);
733 }
734 else
735 {
736 Node nca = hierarchy.getNearestCommonAncestor(subNodes);
737 groupNode = hierarchy.createGroupNode(nca);
738 hierarchy.groupSubgraph(new NodeList(graph.selectedNodes()), groupNode);
739 }
740 graph.setLabelText(groupNode, "Group");
741 graph.firePostEvent();
742
743 graph.unselectAll();
744 graph.setSelected(groupNode, true);
745
746 graph.updateViews();
747 }
748
749
750 void ungroupSelection()
751 {
752 Graph2D graph = view.getGraph2D();
753 graph.firePreEvent();
754
755 hierarchy.ungroupSubgraph(new NodeList(graph.selectedNodes()));
756
757 graph.firePostEvent();
758
759 graph.updateViews();
760 }
761
762 void down(Node v)
763 {
764 Graph2D graph = view.getGraph2D();
765
766 if(v == null)
767 {
768 NodeCursor nc = graph.selectedNodes();
769 if(nc.size() == 1)
770 {
771 v = nc.node();
772 }
773 }
774
775 if(hierarchy.isFolderNode(v))
776 {
777 Graph2D innerGraph = (Graph2D)hierarchy.getInnerGraph(v);
778 Rectangle box = innerGraph.getBoundingBox();
779 view.setGraph2D(innerGraph);
780 view.setCenter(box.x+box.width/2,box.y+box.height/2);
781 innerGraph.updateViews();
782 }
783 }
784
785 void up()
786 {
787 Graph2D graph = view.getGraph2D();
788 if(!hierarchy.isRootGraph(graph))
789 {
790 Graph2D parentGraph = (Graph2D)hierarchy.getParentGraph(graph);
791 view.setGraph2D(parentGraph);
792 Node anchor = hierarchy.getAnchorNode(graph);
793
794 view.setZoom(1.0);
795 view.setCenter(parentGraph.getCenterX(anchor),parentGraph.getCenterY(anchor));
796 parentGraph.unselectAll();
797 parentGraph.setSelected(anchor,true);
798 view.getGraph2D().updateViews();
799 }
800 }
801
802
806 class FoldSubtreesAction extends AbstractAction
807 {
808 FoldSubtreesAction()
809 {
810 super("Fold Subtrees");
811 }
812
813 public void actionPerformed(ActionEvent e)
814 {
815 foldSubtrees();
816 }
817 }
818
819 class FoldComponentsAction extends AbstractAction
820 {
821 FoldComponentsAction()
822 {
823 super("Fold Components");
824 }
825
826 public void actionPerformed(ActionEvent e)
827 {
828 foldComponents();
829 }
830 }
831
832 class FoldSelectionAction extends AbstractAction
833 {
834 FoldSelectionAction()
835 {
836 super("Fold Selection");
837 }
838
839 public void actionPerformed(ActionEvent e)
840 {
841 foldSelection();
842 }
843 }
844
845 class UnfoldSelectionAction extends AbstractAction
846 {
847 UnfoldSelectionAction()
848 {
849 super("Unfold Selection");
850 }
851
852 public void actionPerformed(ActionEvent e)
853 {
854 unfoldSelection();
855 }
856 }
857
858 class UnfoldAllAction extends AbstractAction
859 {
860 UnfoldAllAction()
861 {
862 super("Unfold All");
863 }
864
865 public void actionPerformed(ActionEvent e)
866 {
867 unfoldAll();
868 }
869 }
870
871 class ExtractFolderAction extends AbstractAction
872 {
873 Node folderNode;
874
875 ExtractFolderAction(Node folderNode)
876 {
877 super("Extract Folder");
878 this.folderNode = folderNode;
879 }
880
881 public void actionPerformed(ActionEvent e)
882 {
883 extractFolder(folderNode);
884 }
885 }
886
887 class ViewParentAction extends AbstractAction
888 {
889 ViewParentAction()
890 {
891 super("View Parent");
892 }
893
894 public void actionPerformed(ActionEvent e)
895 {
896 navigateToParentGraph();
897 }
898 }
899
900 class CreateFolderNodeAction extends AbstractAction
901 {
902 double x, y;
903 Graph2D graph;
904
905 CreateFolderNodeAction(Graph2D graph, double x, double y)
906 {
907 super("Create Folder");
908 this.graph = graph;
909 this.x = x;
910 this.y = y;
911 }
912
913 public void actionPerformed(ActionEvent e)
914 {
915 Node folderNode = hierarchy.createFolderNode(graph);
916 graph.setCenter(folderNode, x, y);
917 graph.setLabelText(folderNode, "Folder");
918 graph.updateViews();
919 }
920 }
921
922 class CloseGroupAction extends AbstractAction
923 {
924 Node groupNode;
925 CloseGroupAction(Node groupNode)
926 {
927 super("Close Group");
928 this.groupNode = groupNode;
929 }
930
931 public void actionPerformed(ActionEvent e)
932 {
933 closeGroup(groupNode);
934 }
935 }
936
937 class OpenFolderAction extends AbstractAction
938 {
939 Node folderNode;
940 OpenFolderAction(Node folderNode)
941 {
942 super("Open Folder");
943 this.folderNode = folderNode;
944 }
945
946 public void actionPerformed(ActionEvent e)
947 {
948 openFolder(folderNode);
949 }
950 }
951
952 class RemoveGroupAction extends AbstractAction
953 {
954 Node groupNode;
955 RemoveGroupAction(Node groupNode)
956 {
957 super("Remove Group");
958 this.groupNode = groupNode;
959 }
960
961 public void actionPerformed(ActionEvent e)
962 {
963 removeGroup(groupNode);
964 }
965 }
966
967
968 class GroupSelectionAction extends AbstractAction
969 {
970 double x;
971 double y;
972 GroupSelectionAction(double x, double y)
973 {
974 super("Group Selection");
975 this.x = x;
976 this.y = y;
977 }
978
979 public void actionPerformed(ActionEvent e)
980 {
981 groupSelection(x, y);
982 }
983 }
984
985 class UngroupSelectionAction extends AbstractAction
986 {
987 UngroupSelectionAction()
988 {
989 super("Ungroup Selection");
990 }
991
992 public void actionPerformed(ActionEvent e)
993 {
994 ungroupSelection();
995 }
996 }
997
998 class UpAction extends AbstractAction
999 {
1000 UpAction()
1001 {
1002 super("View Parent");
1003 }
1004
1005 public void actionPerformed(ActionEvent e)
1006 {
1007 up();
1008 }
1009 }
1010
1011 class DownAction extends AbstractAction
1012 {
1013 Node v;
1014 DownAction(Node v)
1015 {
1016 super("View Folder");
1017 this.v = v;
1018 }
1019
1020 public void actionPerformed(ActionEvent e)
1021 {
1022 down(v);
1023 }
1024 }
1025
1026 class LoadInitialGraphAction extends AbstractAction
1027 {
1028 LoadInitialGraphAction() { super("Load Initial Graph"); }
1029
1030 public void actionPerformed(ActionEvent ae)
1031 {
1032 view.getGraph2D().clear();
1033 loadInitialGraph();
1034 view.getGraph2D().updateViews();
1035 }
1036 }
1037}
1038