1
28 package demo.view.hierarchy;
29
30 import demo.view.DemoBase;
31 import y.algo.GraphConnectivity;
32 import y.algo.Trees;
33 import y.base.Graph;
34 import y.base.Node;
35 import y.base.NodeCursor;
36 import y.base.NodeList;
37 import y.layout.tree.BalloonLayouter;
38 import y.layout.tree.TreeReductionStage;
39 import y.layout.LayoutTool;
40 import demo.layout.module.HierarchicLayoutModule;
41 import demo.layout.module.OrganicLayoutModule;
42 import demo.layout.module.OrthogonalLayoutModule;
43 import y.view.EditMode;
44 import y.view.Graph2D;
45 import y.view.Graph2DLayoutExecutor;
46 import y.view.NodeLabel;
47 import y.view.NodeRealizer;
48 import y.view.Overview;
49 import y.view.PopupMode;
50 import y.view.ProxyShapeNodeRealizer;
51 import y.view.ViewMode;
52 import y.view.LineType;
53 import y.view.ShapeNodeRealizer;
54 import y.view.NodeStateChangeEdgeRouter;
55 import y.view.NodeStateChangeHandler;
56 import y.view.hierarchy.DefaultHierarchyGraphFactory;
57 import y.view.hierarchy.DefaultNodeChangePropagator;
58 import y.view.hierarchy.GroupNodeRealizer;
59 import y.view.hierarchy.HierarchyJTree;
60 import y.view.hierarchy.HierarchyManager;
61 import y.view.hierarchy.HierarchyTreeModel;
62 import y.view.hierarchy.HierarchyTreeTransferHandler;
63 import y.geom.YPoint;
64
65 import javax.swing.AbstractAction;
66 import javax.swing.Action;
67 import javax.swing.JLabel;
68 import javax.swing.JMenu;
69 import javax.swing.JMenuBar;
70 import javax.swing.JMenuItem;
71 import javax.swing.JPanel;
72 import javax.swing.JPopupMenu;
73 import javax.swing.JScrollPane;
74 import javax.swing.JSplitPane;
75 import javax.swing.JToolBar;
76 import javax.swing.JTree;
77 import java.awt.BorderLayout;
78 import java.awt.Dimension;
79 import java.awt.Rectangle;
80 import java.awt.Color;
81 import java.awt.EventQueue;
82 import java.awt.geom.Rectangle2D;
83 import java.awt.event.ActionEvent;
84 import java.awt.event.MouseEvent;
85 import java.util.Locale;
86
87
139 public class HierarchyDemo extends DemoBase {
140
141
145 protected HierarchyManager hierarchy;
146 private HierarchicLayoutModule hierarchicLayoutModule;
147 private OrthogonalLayoutModule orthogonalLayoutModule;
148 private OrganicLayoutModule organicLayoutModule;
149
150
151
154 public HierarchyDemo() {
155 Graph2D rootGraph = view.getGraph2D();
156
157 hierarchy.addHierarchyListener(new GroupNodeRealizer.StateChangeListener());
160
161 rootGraph.addGraph2DListener(new DefaultNodeChangePropagator());
164
165 HierarchyTreeModel htm = new HierarchyTreeModel(hierarchy);
167
168 htm.setChildComparator(HierarchyTreeModel.createNodeStateComparator(hierarchy));
170
171 JTree tree = new HierarchyJTree(hierarchy, htm);
173
174 tree.addMouseListener(new HierarchyJTreeDoubleClickListener(view));
176
177 tree.setDragEnabled(true);
180 tree.setTransferHandler(new HierarchyTreeTransferHandler(hierarchy));
181
182
183 view.addViewMode(new HierarchicClickViewMode());
186
187 JScrollPane scrollPane = new JScrollPane(tree);
189 scrollPane.setPreferredSize(new Dimension(150, 0));
190 JPanel leftPane = new JPanel(new BorderLayout());
191
192 view.fitContent();
193
194 Overview overView = new Overview(view);
195 overView.setPreferredSize(new Dimension(150, 150));
196 leftPane.add(overView, BorderLayout.NORTH);
197 leftPane.add(scrollPane);
198 leftPane.setMinimumSize(new Dimension(150,150));
199
200 JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPane, view);
201
202 contentPane.add(splitPane, BorderLayout.CENTER);
203
204 loadInitialGraph();
205 configureDefaultGroupNodeRealizers();
207 }
208
209 protected void configureDefaultGroupNodeRealizers() {
210 DefaultHierarchyGraphFactory hgf = (DefaultHierarchyGraphFactory) hierarchy.getGraphFactory();
212
213 GroupNodeRealizer gnr = new GroupNodeRealizer();
214 gnr.setConsiderNodeLabelSize(true);
216
217 gnr.setFillColor(new Color(202, 236, 255, 84));
219 gnr.setLineColor(Color.decode("#666699"));
220 gnr.setLineType(LineType.DOTTED_1);
221 gnr.getLabel().setBackgroundColor(Color.decode("#99CCFF"));
222 gnr.getLabel().setTextColor(Color.BLACK);
223 gnr.getLabel().setFontSize(15);
224 gnr.setShapeType(ShapeNodeRealizer.ROUND_RECT);
225
226 hgf.setProxyNodeRealizerEnabled(true);
227
228 hgf.setDefaultGroupNodeRealizer(gnr.createCopy());
229
230 GroupNodeRealizer fnr = (GroupNodeRealizer) gnr.createCopy();
232
233 fnr.setFillColor(Color.decode("#F2F0D8"));
234 fnr.setLineColor(Color.decode("#000000"));
235 fnr.getLabel().setBackgroundColor(Color.decode("#B7B69E"));
236
237 hgf.setDefaultFolderNodeRealizer(fnr.createCopy());
238 }
239
240 protected void loadInitialGraph() {
241 loadGraph("resource/hierarchy.graphml");
242 }
243
244 protected void initialize() {
245 hierarchy = new HierarchyManager(view.getGraph2D());
248
249 hierarchicLayoutModule = new HierarchicLayoutModule();
250 orthogonalLayoutModule = new OrthogonalLayoutModule();
251 organicLayoutModule = new OrganicLayoutModule();
252 }
253
254
257 protected JToolBar createToolBar() {
258 final Action hierarchicalLayoutAction = new AbstractAction(
259 "Hierarchical",SHARED_LAYOUT_ICON) {
260 public void actionPerformed(ActionEvent e) {
261 OptionSupport.showDialog(hierarchicLayoutModule, view.getGraph2D(), true, view.getFrame());
262 }
263 };
264
265 final Action layoutAction = new AbstractAction(
266 "Orthogonal", SHARED_LAYOUT_ICON) {
267 public void actionPerformed(ActionEvent e) {
268 OptionSupport.showDialog(orthogonalLayoutModule, view.getGraph2D(), true, view.getFrame());
269 }
270 };
271
272 final Action propertiesAction = new AbstractAction(
273 "Organic", SHARED_LAYOUT_ICON) {
274 public void actionPerformed(ActionEvent e) {
275 OptionSupport.showDialog(organicLayoutModule, view.getGraph2D(), true, view.getFrame());
276 }
277 };
278
279 final JToolBar toolBar = super.createToolBar();
280
281 toolBar.addSeparator();
282 toolBar.add(new ViewParentAction());
283
284 toolBar.addSeparator();
285 toolBar.add(new JLabel("Layout: "));
286 toolBar.add(createActionControl(hierarchicalLayoutAction));
287 toolBar.add(createActionControl(layoutAction));
288 toolBar.add(createActionControl(propertiesAction));
289
290 return toolBar;
291 }
292
293
296 protected JMenuBar createMenuBar() {
297 JMenuBar menuBar = super.createMenuBar();
298
299 JMenu toolsMenu = new JMenu("Tools");
300 menuBar.add(toolsMenu);
301
302 toolsMenu.add(new JMenuItem(new FoldComponentsAction()));
303 toolsMenu.add(new JMenuItem(new FoldSubtreesAction()));
304 toolsMenu.add(new JMenuItem(new UnfoldAllAction()));
305 toolsMenu.addSeparator();
306 toolsMenu.add(new JMenuItem(new LoadInitialGraphAction()));
307
308 return menuBar;
309 }
310
311 protected EditMode createEditMode() {
312 EditMode mode = super.createEditMode();
313 mode.setPopupMode(new HierarchicPopupMode());
315 return mode;
316 }
317
318 protected void registerViewModes() {
319 view.addViewMode(createEditMode());
320 }
321
322
323
326 public static void main(String[] args) {
327 EventQueue.invokeLater(new Runnable() {
328 public void run() {
329 Locale.setDefault(Locale.ENGLISH);
330 initLnF();
331 (new HierarchyDemo()).start("Hierarchy Demo");
332 }
333 });
334 }
335
336
337
341
344 class HierarchicPopupMode extends PopupMode {
345 public JPopupMenu getPaperPopup(double x, double y) {
346 return addFolderPopupItems(new JPopupMenu(), x, y, null, false);
347 }
348
349 public JPopupMenu getNodePopup(Node v) {
350 Graph2D graph = getGraph2D();
351 return addFolderPopupItems(new JPopupMenu(),
352 graph.getCenterX(v),
353 graph.getCenterY(v),
354 v, true);
355 }
356
357 public JPopupMenu getSelectionPopup(double x, double y) {
358 return addFolderPopupItems(new JPopupMenu(), x, y, null, getGraph2D().selectedNodes().ok());
359 }
360
361 JPopupMenu addFolderPopupItems(JPopupMenu pm, double x, double y, Node node, boolean selected)
362 {
363 AbstractAction action;
364 action = new GroupSelectionAction(x, y);
365 pm.add(action);
366 action = new UngroupSelectionAction();
367 pm.add(action);
368 action = new CloseGroupAction(node);
369 action.setEnabled(node != null && hierarchy.isGroupNode(node));
370 pm.add(action);
371 pm.addSeparator();
372 action = new CreateFolderNodeAction(getGraph2D(), x, y);
373 action.setEnabled(node == null);
374 pm.add(action);
375 action = new FoldSelectionAction();
376 action.setEnabled(selected);
377 pm.add(action);
378 action = new UnfoldSelectionAction();
379 action.setEnabled(selected && !hierarchy.isRootGraph(getGraph2D()));
380 pm.add(action);
381 action = new ExtractFolderAction(node);
382 action.setEnabled(node != null && hierarchy.isFolderNode(node));
383 pm.add(action);
384 action = new OpenFolderAction(node);
385 action.setEnabled(node != null && hierarchy.isFolderNode(node));
386 pm.add(action);
387 action = new RemoveGroupAction(node);
388 action.setEnabled(node != null && hierarchy.isGroupNode(node));
389 pm.add(action);
390 return pm;
391 }
392 }
393
394
398 class HierarchicClickViewMode extends ViewMode {
399 public void mouseClicked(MouseEvent e) {
400 if (e.getClickCount() == 2) {
401 Node v = getHitInfo(e).getHitNode();
402 if (v != null) {
403 navigateToInnerGraph(v);
404 } else {
405 navigateToParentGraph();
406 }
407 } else {
408 Node v = getHitInfo(e).getHitNode();
409 if (v != null && !hierarchy.isNormalNode(v)) {
410 double x = translateX(e.getX());
411 double y = translateY(e.getY());
412 Graph2D graph = this.view.getGraph2D();
413 NodeRealizer r = graph.getRealizer(v);
414 GroupNodeRealizer gnr = null;
415 if (r instanceof GroupNodeRealizer) {
416 gnr = (GroupNodeRealizer) r;
417 } else if (r instanceof ProxyShapeNodeRealizer &&
418 ((ProxyShapeNodeRealizer) r).getRealizerDelegate() instanceof GroupNodeRealizer) {
419 gnr = (GroupNodeRealizer) ((ProxyShapeNodeRealizer) r).getRealizerDelegate();
420 }
421 if (gnr != null) {
422 NodeLabel handle = gnr.getStateLabel();
423 if (handle.getBox().contains(x, y)) {
424 if (hierarchy.isFolderNode(v)) {
425 openFolder(v);
426 } else {
427 closeGroup(v);
428 }
429 }
430 }
431 }
432 }
433 }
434 }
435
436
440
443 public void navigateToInnerGraph(Node folderNode) {
444 if (hierarchy.isFolderNode(folderNode)) {
445 Graph2D innerGraph = (Graph2D) hierarchy.getInnerGraph(folderNode);
446 Rectangle box = innerGraph.getBoundingBox();
447 view.setGraph2D(innerGraph);
448 view.setCenter(box.x + box.width / 2, box.y + box.height / 2);
449 innerGraph.updateViews();
450 }
451 }
452
453
457 public void navigateToParentGraph() {
458 Graph2D graph = view.getGraph2D();
459 if (!hierarchy.isRootGraph(graph)) {
460 Graph2D parentGraph = (Graph2D) hierarchy.getParentGraph(graph);
461 view.setGraph2D(parentGraph);
462 Node anchor = hierarchy.getAnchorNode(graph);
463 view.setZoom(1.0);
464 view.setCenter(parentGraph.getCenterX(anchor), parentGraph.getCenterY(anchor));
465 view.getGraph2D().updateViews();
466 }
467 }
468
469
473 void foldSelection()
474 {
475 Graph2D graph = view.getGraph2D();
476 Node folderNode = hierarchy.createFolderNode(graph);
477 graph.setLabelText(folderNode, "Folder");
478
479 hierarchy.foldSubgraph(new NodeList(graph.selectedNodes()), folderNode);
480
481 Graph2D innerGraph = (Graph2D)hierarchy.getInnerGraph(folderNode);
482 innerGraph.unselectAll();
483
484 Rectangle box = innerGraph.getBoundingBox();
485 graph.setSize(folderNode,box.width+10, box.height+10);
486 graph.setLocation(folderNode,box.x-5,box.y-5);
487 graph.updateViews();
488 }
489
490
491
496 void unfoldSelection()
497 {
498 Graph2D graph = view.getGraph2D();
499 NodeList selectedNodes = new NodeList(graph.selectedNodes());
500
501 if(!selectedNodes.isEmpty() && !hierarchy.isRootGraph(graph))
502 {
503 hierarchy.unfoldSubgraph(graph, selectedNodes );
504 }
505 graph.updateViews();
506 }
507
508
512 void extractFolder(Node folderNode) {
513 Graph2D graph = (Graph2D) folderNode.getGraph();
514 Graph innerGraph = hierarchy.getInnerGraph(folderNode);
515 NodeList subNodes = new NodeList(innerGraph.nodes());
516 hierarchy.unfoldSubgraph(innerGraph, subNodes);
517
518 graph.removeNode(folderNode);
521
522 for (NodeCursor nc = subNodes.nodes(); nc.ok(); nc.next()) {
524 graph.setSelected(nc.node(), true);
525 }
526
527 graph.updateViews();
528 }
529
530
534 void foldComponents() {
535 Graph2D graph = view.getGraph2D();
536 for (NodeCursor nodeCursor = graph.nodes(); nodeCursor.ok(); nodeCursor.next()) {
538 Node node = nodeCursor.node();
539 if (hierarchy.isGroupNode(node)) {
540 graph.removeNode(node);
541 }
542 }
543
544 NodeList[] components = GraphConnectivity.connectedComponents(graph);
545
546 if (components.length > 1) {
547 for (int i = 0; i < components.length; i++) {
548 NodeList subNodes = components[i];
549 Node folderNode = hierarchy.createFolderNode(graph);
550 graph.setCenter(folderNode, 150 * (i + 1), 0);
551 graph.setLabelText(folderNode, "Comp " + (i + 1));
552 hierarchy.setParentNode(subNodes, folderNode);
553 }
554 view.fitContent();
555 view.getGraph2D().updateViews();
556 }
557
558 }
559
560
572 void foldSubtrees() {
573 Graph2D graph = view.getGraph2D();
574
575 for (NodeCursor nodeCursor = graph.nodes(); nodeCursor.ok(); nodeCursor.next()) {
577 Node node = nodeCursor.node();
578 if (hierarchy.isGroupNode(node)) {
579 graph.removeNode(node);
580 }
581 }
582
583 NodeList[] trees = Trees.getTreeNodes(graph);
584
585 for (int i = 0; i < trees.length; i++) {
586 NodeList tree = trees[i];
587
588 Node folderNode = hierarchy.createFolderNode(graph);
589
590 hierarchy.foldSubgraph(tree, folderNode);
591
592 Graph2D innerGraph = (Graph2D) hierarchy.getInnerGraph(folderNode);
593
594 BalloonLayouter balloonLayouter = new BalloonLayouter();
595 balloonLayouter.appendStage(new TreeReductionStage());
596 new Graph2DLayoutExecutor().doLayout(innerGraph, balloonLayouter);
597
598 Node root = tree.firstNode();
600 String rootName = innerGraph.getLabelText(root);
601 graph.setLabelText(folderNode, rootName + " Tree");
602
603 Rectangle box = innerGraph.getBoundingBox();
604 if (box.height > box.width) {
605 graph.setSize(folderNode, Math.max(150 * box.width / box.height, 40), 170);
606 } else {
607 graph.setSize(folderNode, 150, Math.max(40, 150 * box.height / box.width + 20));
608 }
609 }
610
611 view.fitContent();
612 graph.updateViews();
613 }
614
615
618 void unfoldAll()
619 {
620 NodeList result = hierarchy.getFolderNodes(view.getGraph2D(),true);
621 while(!result.isEmpty())
622 {
623 Node folderNode = result.popNode();
624 extractFolder(folderNode);
625 }
626 }
627
628
629 protected void closeGroup(Node groupNode)
630 {
631 Graph2D graph = view.getGraph2D();
632
633 NodeList groupNodes = new NodeList();
634 if(groupNode == null)
635 {
636 for(NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next())
638 {
639 Node v = nc.node();
640 if(hierarchy.isGroupNode(v) && hierarchy.getLocalGroupDepth(v) == 0)
641 {
642 groupNodes.add(v);
643 }
644 }
645 }
646 else
647 {
648 groupNodes.add(groupNode);
649 }
650
651 graph.firePreEvent();
652 NodeStateChangeHandler stateChangeHandler = new NodeStateChangeEdgeRouter();
653 for(NodeCursor nc = groupNodes.nodes(); nc.ok(); nc.next())
654 {
655 stateChangeHandler.preNodeStateChange(nc.node());
656 hierarchy.closeGroup(nc.node());
657 stateChangeHandler.postNodeStateChange(nc.node());
658 }
659 graph.firePostEvent();
660
661 graph.unselectAll();
662 for(NodeCursor nc = groupNodes.nodes(); nc.ok(); nc.next())
663 {
664 graph.setSelected(nc.node(), true);
665 }
666
667 graph.updateViews();
668 }
669
670 protected void removeGroup(Node groupNode) {
671 hierarchy.removeGroupNode(groupNode);
672 }
673
674 protected void openFolder(Node folderNode)
675 {
676 Graph2D graph = view.getGraph2D();
677
678 NodeList folderNodes = new NodeList();
679 if(folderNode == null)
680 {
681 for(NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next())
683 {
684 Node v = nc.node();
685 if(hierarchy.isFolderNode(v))
686 {
687 folderNodes.add(v);
688 }
689 }
690 }
691 else
692 {
693 folderNodes.add(folderNode);
694 }
695
696 graph.firePreEvent();
697
698 NodeStateChangeHandler stateChangeHandler = new NodeStateChangeEdgeRouter();
699
700 for(NodeCursor nc = folderNodes.nodes(); nc.ok(); nc.next())
701 {
702 Graph2D innerGraph = (Graph2D)hierarchy.getInnerGraph(nc.node());
704 YPoint folderP = graph.getLocation(nc.node());
705 NodeList innerNodes = new NodeList(innerGraph.nodes());
706 stateChangeHandler.preNodeStateChange(nc.node());
707 hierarchy.openFolder(nc.node());
708
709 Rectangle2D.Double gBox = graph.getRealizer(nc.node()).getBoundingBox();
711 LayoutTool.moveSubgraph(graph, innerNodes.nodes(),
713 folderP.x - gBox.x,
714 folderP.y - gBox.y);
715 stateChangeHandler.postNodeStateChange(nc.node());
716 }
717 graph.firePostEvent();
718
719
720 graph.unselectAll();
721 for(NodeCursor nc = folderNodes.nodes(); nc.ok(); nc.next())
722 {
723 graph.setSelected(nc.node(), true);
724 }
725
726 graph.updateViews();
727 }
728
729 void groupSelection(double x, double y)
730 {
731 Graph2D graph = view.getGraph2D();
732
733 graph.firePreEvent();
734
735 NodeList subNodes = new NodeList(graph.selectedNodes());
736 Node groupNode;
737 if(subNodes.isEmpty())
738 {
739 groupNode = hierarchy.createGroupNode(graph);
740 if(Double.isNaN(x) || Double.isNaN(y))
741 {
742 x = view.getCenter().getX();
743 y = view.getCenter().getY();
744 }
745 graph.setCenter(groupNode, x,y);
746 }
747 else
748 {
749 Node nca = hierarchy.getNearestCommonAncestor(subNodes);
750 groupNode = hierarchy.createGroupNode(nca);
751 hierarchy.groupSubgraph(new NodeList(graph.selectedNodes()), groupNode);
752 }
753 graph.setLabelText(groupNode, "Group");
754 graph.firePostEvent();
755
756 graph.unselectAll();
757 graph.setSelected(groupNode, true);
758
759 graph.updateViews();
760 }
761
762
763 void ungroupSelection()
764 {
765 Graph2D graph = view.getGraph2D();
766 graph.firePreEvent();
767
768 hierarchy.ungroupSubgraph(new NodeList(graph.selectedNodes()));
769
770 graph.firePostEvent();
771
772 graph.updateViews();
773 }
774
775 void down(Node v)
776 {
777 Graph2D graph = view.getGraph2D();
778
779 if(v == null)
780 {
781 NodeCursor nc = graph.selectedNodes();
782 if (nc.size() == 1) {
783 v = nc.node();
784 }
785 }
786
787 if (hierarchy.isFolderNode(v)) {
788 Graph2D innerGraph = (Graph2D) hierarchy.getInnerGraph(v);
789 Rectangle box = innerGraph.getBoundingBox();
790 view.setGraph2D(innerGraph);
791 view.setCenter(box.x + box.width / 2, box.y + box.height / 2);
792 innerGraph.updateViews();
793 }
794 }
795
796 void up() {
797 Graph2D graph = view.getGraph2D();
798 if (!hierarchy.isRootGraph(graph)) {
799 Graph2D parentGraph = (Graph2D) hierarchy.getParentGraph(graph);
800 view.setGraph2D(parentGraph);
801 Node anchor = hierarchy.getAnchorNode(graph);
802
803 view.setZoom(1.0);
804 view.setCenter(parentGraph.getCenterX(anchor), parentGraph.getCenterY(anchor));
805 parentGraph.unselectAll();
806 parentGraph.setSelected(anchor, true);
807 view.getGraph2D().updateViews();
808 }
809 }
810
811
815 class FoldSubtreesAction extends AbstractAction {
816 FoldSubtreesAction() {
817 super("Fold Subtrees");
818 }
819
820 public void actionPerformed(ActionEvent e) {
821 foldSubtrees();
822 }
823 }
824
825 class FoldComponentsAction extends AbstractAction {
826 FoldComponentsAction() {
827 super("Fold Components");
828 }
829
830 public void actionPerformed(ActionEvent e) {
831 foldComponents();
832 }
833 }
834
835 class FoldSelectionAction extends AbstractAction
836 {
837 FoldSelectionAction()
838 {
839 super("Fold Selection");
840 }
841
842 public void actionPerformed(ActionEvent e)
843 {
844 foldSelection();
845 }
846 }
847
848 class UnfoldSelectionAction extends AbstractAction
849 {
850 UnfoldSelectionAction()
851 {
852 super("Unfold Selection");
853 }
854
855 public void actionPerformed(ActionEvent e)
856 {
857 unfoldSelection();
858 }
859 }
860
861 class UnfoldAllAction extends AbstractAction
862 {
863 UnfoldAllAction()
864 {
865 super("Unfold All");
866 }
867
868 public void actionPerformed(ActionEvent e)
869 {
870 unfoldAll();
871 }
872 }
873
874 class ExtractFolderAction extends AbstractAction
875 {
876 Node folderNode;
877
878 ExtractFolderAction(Node folderNode) {
879 super("Extract Folder");
880 this.folderNode = folderNode;
881 }
882
883 public void actionPerformed(ActionEvent e) {
884 extractFolder(folderNode);
885 }
886 }
887
888 class ViewParentAction extends AbstractAction {
889 ViewParentAction() {
890 super("View Parent");
891 }
892
893 public void actionPerformed(ActionEvent e) {
894 navigateToParentGraph();
895 }
896 }
897
898 class CreateFolderNodeAction extends AbstractAction {
899 double x, y;
900 Graph2D graph;
901
902 CreateFolderNodeAction(Graph2D graph, double x, double y) {
903 super("Create Folder");
904 this.graph = graph;
905 this.x = x;
906 this.y = y;
907 }
908
909 public void actionPerformed(ActionEvent e) {
910 Node folderNode = hierarchy.createFolderNode(graph);
911 graph.setCenter(folderNode, x, y);
912 graph.setLabelText(folderNode, "Folder");
913 graph.updateViews();
914 }
915 }
916
917 class CloseGroupAction extends AbstractAction
918 {
919 Node groupNode;
920 CloseGroupAction(Node groupNode)
921 {
922 super("Close Group");
923 this.groupNode = groupNode;
924 }
925
926 public void actionPerformed(ActionEvent e)
927 {
928 closeGroup(groupNode);
929 }
930 }
931
932 class OpenFolderAction extends AbstractAction
933 {
934 Node folderNode;
935 OpenFolderAction(Node folderNode)
936 {
937 super("Open Folder");
938 this.folderNode = folderNode;
939 }
940
941 public void actionPerformed(ActionEvent e)
942 {
943 openFolder(folderNode);
944 }
945 }
946
947 class RemoveGroupAction extends AbstractAction
948 {
949 Node groupNode;
950 RemoveGroupAction(Node groupNode)
951 {
952 super("Remove Group");
953 this.groupNode = groupNode;
954 }
955
956 public void actionPerformed(ActionEvent e) {
957 removeGroup(groupNode);
958 }
959 }
960
961
962 class GroupSelectionAction extends AbstractAction
963 {
964 double x;
965 double y;
966 GroupSelectionAction(double x, double y)
967 {
968 super("Group Selection");
969 this.x = x;
970 this.y = y;
971 }
972
973 public void actionPerformed(ActionEvent e)
974 {
975 groupSelection(x, y);
976 }
977 }
978
979 class UngroupSelectionAction extends AbstractAction
980 {
981 UngroupSelectionAction()
982 {
983 super("Ungroup Selection");
984 }
985
986 public void actionPerformed(ActionEvent e)
987 {
988 ungroupSelection();
989 }
990 }
991
992 class UpAction extends AbstractAction
993 {
994 UpAction()
995 {
996 super("View Parent");
997 }
998
999 public void actionPerformed(ActionEvent e) {
1000 up();
1001 }
1002 }
1003
1004 class DownAction extends AbstractAction {
1005 Node v;
1006
1007 DownAction(Node v) {
1008 super("View Folder");
1009 this.v = v;
1010 }
1011
1012 public void actionPerformed(ActionEvent e) {
1013 down(v);
1014 }
1015 }
1016
1017 class LoadInitialGraphAction extends AbstractAction {
1018 LoadInitialGraphAction() {
1019 super("Load Initial Graph");
1020 }
1021
1022 public void actionPerformed(ActionEvent ae) {
1023 view.getGraph2D().clear();
1024 loadInitialGraph();
1025 view.getGraph2D().updateViews();
1026 }
1027 }
1028}
1029