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