1
14 package demo.view;
15
16 import y.io.GraphMLIOHandler;
17 import y.io.IOHandler;
18 import y.module.YModule;
19 import y.option.DefaultEditorFactory;
20 import y.option.Editor;
21 import y.option.EditorFactory;
22 import y.option.GuiFactory;
23 import y.option.OptionHandler;
24 import y.util.D;
25 import y.view.AutoDragViewMode;
26 import y.view.CreateEdgeMode;
27 import y.view.EditMode;
28 import y.view.Graph2D;
29 import y.view.Graph2DPrinter;
30 import y.view.Graph2DView;
31 import y.view.Graph2DViewActions;
32 import y.view.Graph2DViewMouseWheelZoomListener;
33 import y.view.MoveLabelMode;
34 import y.view.MovePortMode;
35 import y.view.MoveSelectionMode;
36 import y.view.MoveSnapContext;
37 import y.view.OrthogonalMoveBendsMode;
38 import y.view.HotSpotMode;
39 import y.view.TooltipMode;
40 import y.view.View2DConstants;
41 import y.view.DropSupport;
42
43 import javax.swing.AbstractAction;
44 import javax.swing.Action;
45 import javax.swing.ActionMap;
46 import javax.swing.BorderFactory;
47 import javax.swing.Icon;
48 import javax.swing.ImageIcon;
49 import javax.swing.InputMap;
50 import javax.swing.JButton;
51 import javax.swing.JComponent;
52 import javax.swing.JDialog;
53 import javax.swing.JEditorPane;
54 import javax.swing.JFileChooser;
55 import javax.swing.JFrame;
56 import javax.swing.JMenu;
57 import javax.swing.JMenuBar;
58 import javax.swing.JPanel;
59 import javax.swing.JRootPane;
60 import javax.swing.JScrollPane;
61 import javax.swing.JToolBar;
62 import javax.swing.JOptionPane;
63 import javax.swing.KeyStroke;
64 import javax.swing.filechooser.FileFilter;
65 import java.awt.BorderLayout;
66 import java.awt.Dimension;
67 import java.awt.EventQueue;
68 import java.awt.FlowLayout;
69 import java.awt.Frame;
70 import java.awt.Rectangle;
71 import java.awt.Color;
72 import java.awt.event.ActionEvent;
73 import java.awt.event.ActionListener;
74 import java.awt.print.PageFormat;
75 import java.awt.print.PrinterJob;
76 import java.io.File;
77 import java.io.IOException;
78 import java.net.MalformedURLException;
79 import java.net.URI;
80 import java.net.URISyntaxException;
81 import java.net.URL;
82 import java.util.Locale;
83 import java.util.regex.Pattern;
84
85
92 public abstract class DemoBase {
93
97 public static final Dimension TOOLBAR_SMALL_SEPARATOR = new Dimension(3, 3);
98
99 public static final Icon SHARED_LAYOUT_ICON = getIconResource("resource/layout.png");
100
101 private static final Pattern PATH_SEPARATOR_PATTERN = Pattern.compile("/");
102
103
106 public static void initLnF() {
107 DemoDefaults.initLnF();
108 }
109
110
113 protected Graph2DView view;
114
115 protected final JPanel contentPane;
116
117
122 protected DemoBase() {
123 view = createGraphView();
124 configureDefaultRealizers();
125
126 contentPane = new JPanel();
127 contentPane.setLayout(new BorderLayout());
128
129 initialize();
130
131 registerViewModes();
132 registerViewActions();
133
134 contentPane.add(view, BorderLayout.CENTER);
135 final JToolBar jtb = createToolBar();
136 if (jtb != null) {
137 contentPane.add(jtb, BorderLayout.NORTH);
138 }
139
140 registerViewListeners();
141 }
142
143
147 protected Graph2DView createGraphView() {
148 Graph2DView view = new Graph2DView();
149 view.setFitContentOnResize(true);
150 return view;
151 }
152
153
157 protected void configureDefaultRealizers() {
158 DemoDefaults.configureDefaultRealizers(view);
159 }
160
161
165 protected void initialize() {
166 }
167
168 public void dispose() {
169 }
170
171 protected void loadGraph(URL resource) {
172
173 if (resource == null) {
174 String message = "Resource \"" + resource + "\" not found in classpath";
175 D.showError(message);
176 throw new RuntimeException(message);
177 }
178
179 try {
180 IOHandler ioh = createGraphMLIOHandler();
181 view.getGraph2D().clear();
182 ioh.read(view.getGraph2D(), resource);
183 } catch (IOException e) {
184 String message = "Unexpected error while loading resource \"" + resource + "\" due to " + e.getMessage();
185 D.bug(message);
186 throw new RuntimeException(message, e);
187 }
188 view.getGraph2D().setURL(resource);
189 view.fitContent();
190 view.updateView();
191
192 }
193
194 protected GraphMLIOHandler createGraphMLIOHandler() {
195 return new GraphMLIOHandler();
196 }
197
198 protected void loadGraph(Class aClass, String resourceString) {
199 final URL resource = aClass.getResource(resourceString);
200 if (resource == null) {
201 String message = "Resource \"" + resourceString + "\" not found in classpath of " + aClass;
202 D.showError(message);
203 throw new RuntimeException(message);
204 }
205 loadGraph(resource);
206 }
207
208 protected void loadGraph(String resourceString) {
209 loadGraph(getClass(), resourceString);
210 }
211
212
216 public final void start() {
217 start(getSimpleClassName());
218 }
219
220
223 private String getSimpleClassName() {
224 final String className = getClass().getName();
225 return className.substring(className.lastIndexOf('.') + 1);
226 }
227
228
232 public final void start(String title) {
233 JFrame frame = new JFrame(title);
234 JOptionPane.setRootFrame(frame);
235 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
236 this.addContentTo(frame.getRootPane());
237 frame.pack();
238 frame.setLocationRelativeTo(null);
239 frame.setVisible(true);
240 }
241
242 public void addContentTo(final JRootPane rootPane) {
243 final JMenuBar jmb = createMenuBar();
244 if (jmb != null) {
245 rootPane.setJMenuBar(jmb);
246 }
247 rootPane.setContentPane(contentPane);
248 }
249
250 protected void addHelpPane( final String helpFilePath ) {
251 if (helpFilePath != null) {
252 final URL url = getClass().getResource(helpFilePath);
253 if (url == null) {
254 System.err.println("Could not locate help file: " + helpFilePath);
255 } else {
256 final JComponent helpPane = createHelpPane(url);
257 if (helpPane != null) {
258 contentPane.add(helpPane, BorderLayout.EAST);
259 }
260 }
261 }
262 }
263
264
268 protected JComponent createHelpPane( final URL helpURL ) {
269 try {
270 JEditorPane editorPane = new JEditorPane(helpURL);
271 editorPane.setEditable(false);
272 editorPane.setPreferredSize(new Dimension(250, 250));
273 return new JScrollPane(editorPane);
274 } catch (IOException e) {
275 e.printStackTrace();
276 }
277 return null;
278 }
279
280 protected void registerViewActions() {
281 Graph2DViewActions actions = new Graph2DViewActions(view);
283 ActionMap amap = view.getCanvasComponent().getActionMap();
284 if (amap != null) {
285 InputMap imap = actions.createDefaultInputMap(amap);
286 if (!isDeletionEnabled()) {
287 amap.remove(Graph2DViewActions.DELETE_SELECTION);
288 }
289 view.getCanvasComponent().setInputMap(JComponent.WHEN_FOCUSED, imap);
290 }
291 }
292
293
298 protected void registerViewModes() {
299 EditMode editMode = createEditMode();
300 if (editMode != null) {
301 view.addViewMode(editMode);
302 }
303
304 TooltipMode tooltipMode = createTooltipMode();
305 if(tooltipMode != null) {
306 view.addViewMode(tooltipMode);
307 }
308
309 view.addViewMode(new AutoDragViewMode());
310 }
311
312
318 protected EditMode createEditMode() {
319 EditMode editMode = new EditMode();
320 if (editMode.getCreateEdgeMode() instanceof CreateEdgeMode) {
322 ((CreateEdgeMode) editMode.getCreateEdgeMode()).setIndicatingTargetNode(true);
323 }
324 if (editMode.getMovePortMode() instanceof MovePortMode) {
325 ((MovePortMode) editMode.getMovePortMode()).setIndicatingTargetNode(true);
326 }
327
328 editMode.allowMovingWithPopup(true);
330
331 return editMode;
332 }
333
334
340 protected TooltipMode createTooltipMode() {
341 TooltipMode tooltipMode = new TooltipMode();
342 tooltipMode.setEdgeTipEnabled(false);
343 return tooltipMode;
344 }
345
346
350 protected void registerViewListeners() {
351 Graph2DViewMouseWheelZoomListener wheelZoomListener = new Graph2DViewMouseWheelZoomListener();
352 wheelZoomListener.setCenterZooming(false);
354 view.getCanvasComponent().addMouseWheelListener(wheelZoomListener);
355 }
356
357
361 protected boolean isDeletionEnabled() {
362 return true;
363 }
364
365
368 protected JToolBar createToolBar() {
369 JToolBar toolBar = new JToolBar();
370 toolBar.add(new Zoom(1.25));
371 toolBar.add(new Zoom(0.8));
372 toolBar.add(new ResetZoom());
373 toolBar.add(new FitContent(view));
374 if (isDeletionEnabled()) {
375 toolBar.add(createDeleteSelectionAction());
376 }
377 return toolBar;
378 }
379
380
383 protected JMenuBar createMenuBar() {
384 JMenuBar menuBar = new JMenuBar();
385 JMenu menu = new JMenu("File");
386 Action action;
387 action = createLoadAction();
388 if (action != null) {
389 menu.add(action);
390 }
391 action = createSaveAction();
392 if (action != null) {
393 menu.add(action);
394 }
395 menu.addSeparator();
396 menu.add(new PrintAction());
397 menu.addSeparator();
398 menu.add(new ExitAction());
399 menuBar.add(menu);
400
401 if (getExampleResources() != null && getExampleResources().length != 0) {
402 createExamplesMenu(menuBar);
403 }
404
405 return menuBar;
406 }
407
408 protected Action createLoadAction() {
409 return new LoadAction();
410 }
411
412 protected Action createSaveAction() {
413 return new SaveAction();
414 }
415
416 protected Action createDeleteSelectionAction() {
417 return new DeleteSelection(view);
418 }
419
420
425 protected void createExamplesMenu(JMenuBar menuBar) {
426 final String[] fileNames = getExampleResources();
427 if (fileNames == null) {
428 return;
429 }
430
431 final JMenu menu = new JMenu("Example Graphs");
432 menuBar.add(menu);
433
434 for (int i = 0; i < fileNames.length; i++) {
435 final String filename = fileNames[i];
436 final String[] path = PATH_SEPARATOR_PATTERN.split(filename);
437 menu.add(new AbstractAction(path[path.length - 1]) {
438 public void actionPerformed(ActionEvent e) {
439 loadGraph(filename);
440 }
441 });
442 }
443 }
444
445 public JPanel getContentPane() {
446 return contentPane;
447 }
448
449
452 protected String[] getExampleResources() {
453 return null;
454 }
455
456
459 public class PrintAction extends AbstractAction {
460 PageFormat pageFormat;
461
462 OptionHandler printOptions;
463
464 public PrintAction() {
465 super("Print");
466
467 printOptions = new OptionHandler("Print Options");
469 printOptions.addInt("Poster Rows", 1);
470 printOptions.addInt("Poster Columns", 1);
471 printOptions.addBool("Add Poster Coords", false);
472 final String[] area = {"View", "Graph"};
473 printOptions.addEnum("Clip Area", area, 1);
474 }
475
476 public void actionPerformed(ActionEvent e) {
477 Graph2DPrinter gprinter = new Graph2DPrinter(view);
478
479 if (!printOptions.showEditor(view.getFrame())) {
481 return;
482 }
483 gprinter.setPosterRows(printOptions.getInt("Poster Rows"));
484 gprinter.setPosterColumns(printOptions.getInt("Poster Columns"));
485 gprinter.setPrintPosterCoords(printOptions.getBool("Add Poster Coords"));
486 if ("Graph".equals(printOptions.get("Clip Area"))) {
487 gprinter.setClipType(Graph2DPrinter.CLIP_GRAPH);
488 } else {
489 gprinter.setClipType(Graph2DPrinter.CLIP_VIEW);
490 }
491
492 PrinterJob printJob = PrinterJob.getPrinterJob();
494 if (pageFormat == null) {
495 pageFormat = printJob.defaultPage();
496 }
497 PageFormat pf = printJob.pageDialog(pageFormat);
498 if (pf == pageFormat) {
499 return;
500 } else {
501 pageFormat = pf;
502 }
503
504 printJob.setPrintable(gprinter, pageFormat);
507
508 if (printJob.printDialog()) {
509 try {
510 printJob.print();
511 } catch (Exception ex) {
512 ex.printStackTrace();
513 }
514 }
515 }
516 }
517
518
521 public static class ExitAction extends AbstractAction {
522 public ExitAction() {
523 super("Exit");
524 }
525
526 public void actionPerformed(ActionEvent e) {
527 System.exit(0);
528 }
529 }
530
531
534 public class SaveAction extends AbstractAction {
535 JFileChooser chooser;
536
537 public SaveAction() {
538 super("Save...");
539 chooser = null;
540 }
541
542 public void actionPerformed(ActionEvent e) {
543 if (chooser == null) {
544 chooser = new JFileChooser();
545 chooser.setAcceptAllFileFilterUsed(false);
546 chooser.addChoosableFileFilter(new FileFilter() {
547 public boolean accept(File f) {
548 return f.isDirectory() || f.getName().endsWith(".graphml");
549 }
550
551 public String getDescription() {
552 return "GraphML Format (.graphml)";
553 }
554 });
555 }
556
557 URL url = view.getGraph2D().getURL();
558 if (url != null && "file".equals(url.getProtocol())) {
559 try {
560 chooser.setSelectedFile(new File(new URI(url.toString())));
561 } catch (URISyntaxException e1) {
562 }
564 }
565
566 if (chooser.showSaveDialog(contentPane) == JFileChooser.APPROVE_OPTION) {
567 String name = chooser.getSelectedFile().toString();
568 if(!name.endsWith(".graphml")) {
569 name += ".graphml";
570 }
571 IOHandler ioh = createGraphMLIOHandler();
572
573 try {
574 ioh.write(view.getGraph2D(), name);
575 } catch (IOException ioe) {
576 D.show(ioe);
577 }
578 }
579 }
580 }
581
582
585 public class LoadAction extends AbstractAction {
586 JFileChooser chooser;
587
588 public LoadAction() {
589 super("Load...");
590 chooser = null;
591 }
592
593 public void actionPerformed(ActionEvent e) {
594 if (chooser == null) {
595 chooser = new JFileChooser();
596 chooser.setAcceptAllFileFilterUsed(false);
597 chooser.addChoosableFileFilter(new FileFilter() {
598 public boolean accept(File f) {
599 return f.isDirectory() || f.getName().endsWith(".graphml");
600 }
601
602 public String getDescription() {
603 return "GraphML Format (.graphml)";
604 }
605 });
606 }
607 if (chooser.showOpenDialog(contentPane) == JFileChooser.APPROVE_OPTION) {
608 URL resource = null;
609 try {
610 resource = chooser.getSelectedFile().toURI().toURL();
611 } catch (MalformedURLException urlex) {
612 urlex.printStackTrace();
613 }
614 loadGraph(resource);
615 }
616 }
617 }
618
619
622 public static class DeleteSelection extends AbstractAction {
623 private final Graph2DView view;
624
625 public DeleteSelection(final Graph2DView view) {
626 super("Delete Selection");
627 this.view = view;
628 this.putValue(Action.SMALL_ICON, getIconResource("resource/delete.png"));
629 this.putValue(Action.SHORT_DESCRIPTION, "Delete Selection");
630 }
631
632 public void actionPerformed(ActionEvent e) {
633 view.getGraph2D().removeSelection();
634 view.getGraph2D().updateViews();
635 }
636 }
637
638
641 public class ResetZoom extends AbstractAction {
642 public ResetZoom() {
643 super("Reset Zoom");
644 this.putValue(Action.SMALL_ICON, getIconResource("resource/zoomOriginal.png"));
645 this.putValue(Action.SHORT_DESCRIPTION, "Reset Zoom");
646 }
647
648 public void actionPerformed( final ActionEvent e ) {
649 view.setZoom(1.0);
650 Rectangle box = view.getGraph2D().getBoundingBox();
655 view.setWorldRect(box.x - 20, box.y - 20, box.width + 40, box.height + 40);
656
657 view.updateView();
658 }
659 }
660
661
664 public class Zoom extends AbstractAction {
665 double factor;
666
667 public Zoom(double factor) {
668 super("Zoom " + (factor > 1.0 ? "In" : "Out"));
669 String resource = factor > 1.0d ? "resource/zoomIn.png" : "resource/zoomOut.png";
670 this.putValue(Action.SMALL_ICON, getIconResource(resource));
671 this.putValue(Action.SHORT_DESCRIPTION, "Zoom " + (factor > 1.0 ? "In" : "Out"));
672 this.factor = factor;
673 }
674
675 public void actionPerformed(ActionEvent e) {
676 view.setZoom(view.getZoom() * factor);
677 Rectangle box = view.getGraph2D().getBoundingBox();
682 view.setWorldRect(box.x - 20, box.y - 20, box.width + 40, box.height + 40);
683
684 view.updateView();
685 }
686 }
687
688
691 public static class FitContent extends AbstractAction {
692 private final Graph2DView view;
693
694 public FitContent(final Graph2DView view) {
695 super("Fit Content");
696 this.view = view;
697 this.putValue(Action.SMALL_ICON, getIconResource("resource/zoomFit.png"));
698 this.putValue(Action.SHORT_DESCRIPTION, "Fit Content");
699 }
700
701 public void actionPerformed(ActionEvent e) {
702 view.fitContent();
703 view.updateView();
704 }
705 }
706
707
715 public static class SnappingConfiguration {
716 private boolean snappingEnabled;
717 private double snapDistance;
718 private double snapLineExtension;
719 private Color snapLineColor;
720 private boolean removingInnerBends;
721
722 private double nodeToNodeDistance;
723 private double nodeToEdgeDistance;
724 private double edgeToEdgeDistance;
725
726 private boolean gridSnappingEnabled;
727 private double gridSnapDistance;
728 private double gridDistance;
729 private int gridType;
730
731
732 public double getEdgeToEdgeDistance() {
733 return edgeToEdgeDistance;
734 }
735
736 public void setEdgeToEdgeDistance(double edgeToEdgeDistance) {
737 this.edgeToEdgeDistance = edgeToEdgeDistance;
738 }
739
740 public double getGridSnapDistance() {
741 return gridSnapDistance;
742 }
743
744 public void setGridSnapDistance(double gridSnapDistance) {
745 this.gridSnapDistance = gridSnapDistance;
746 }
747
748 public boolean isGridSnappingEnabled() {
749 return gridSnappingEnabled;
750 }
751
752 public void setGridSnappingEnabled(boolean gridSnappingEnabled) {
753 this.gridSnappingEnabled = gridSnappingEnabled;
754 }
755
756 public double getNodeToEdgeDistance() {
757 return nodeToEdgeDistance;
758 }
759
760 public void setNodeToEdgeDistance(double nodeToEdgeDistance) {
761 this.nodeToEdgeDistance = nodeToEdgeDistance;
762 }
763
764 public double getNodeToNodeDistance() {
765 return nodeToNodeDistance;
766 }
767
768 public void setNodeToNodeDistance(double nodeToNodeDistance) {
769 this.nodeToNodeDistance = nodeToNodeDistance;
770 }
771
772 public boolean isRemovingInnerBends() {
773 return removingInnerBends;
774 }
775
776 public void setRemovingInnerBends(boolean removingInnerBends) {
777 this.removingInnerBends = removingInnerBends;
778 }
779
780 public double getSnapDistance() {
781 return snapDistance;
782 }
783
784 public void setSnapDistance(double snapDistance) {
785 this.snapDistance = snapDistance;
786 }
787
788 public Color getSnapLineColor() {
789 return snapLineColor;
790 }
791
792 public void setSnapLineColor(Color snapLineColor) {
793 this.snapLineColor = snapLineColor;
794 }
795
796 public double getSnapLineExtension() {
797 return snapLineExtension;
798 }
799
800 public void setSnapLineExtension(double snapLineExtension) {
801 this.snapLineExtension = snapLineExtension;
802 }
803
804 public boolean isSnappingEnabled() {
805 return snappingEnabled;
806 }
807
808 public void setSnappingEnabled(boolean snappingEnabled) {
809 this.snappingEnabled = snappingEnabled;
810 }
811
812 public double getGridDistance() {
813 return gridDistance;
814 }
815
816 public void setGridDistance(double gridDistance) {
817 this.gridDistance = gridDistance;
818 }
819
820 public int getGridType() {
821 return gridType;
822 }
823
824 public void setGridType(int gridType) {
825 this.gridType = gridType;
826 }
827
828 public void configureView(final Graph2DView view) {
829 view.setGridMode(false);
831
832 if (isGridSnappingEnabled()) {
833 view.setGridVisible(true);
835 view.setGridResolution(getGridDistance());
836 view.setGridType(getGridType());
837 view.setGridColor(getSnapLineColor());
838 } else {
839 view.setGridVisible(false);
840 }
841
842 view.updateView();
843 }
844
845 public void configureDropSupport(final DropSupport dropSupport) {
846 dropSupport.setSnappingEnabled(isSnappingEnabled());
847 configureSnapContext(dropSupport.getSnapContext());
848 }
849
850
856 public void configureEditMode(final EditMode editMode) {
857 if (editMode.getHotSpotMode() instanceof HotSpotMode) {
858 HotSpotMode hotSpotMode = (HotSpotMode) editMode.getHotSpotMode();
859 hotSpotMode.setSnappingEnabled(isSnappingEnabled());
860 hotSpotMode.getSnapContext().setSnapLineColor(getSnapLineColor());
861 }
862 {
863 MoveSelectionMode moveSelectionMode = (MoveSelectionMode) editMode.getMoveSelectionMode();
864 MoveSnapContext snapContext = moveSelectionMode.getSnapContext();
865 moveSelectionMode.setSnappingEnabled(isGridSnappingEnabled() || isSnappingEnabled());
866
867 configureSnapContext(snapContext);
868 moveSelectionMode.setRemovingInnerBends(isRemovingInnerBends());
869 }
870 {
871 OrthogonalMoveBendsMode moveBendsMode = (OrthogonalMoveBendsMode) editMode.getOrthogonalMoveBendsMode();
872 MoveSnapContext snapContext = moveBendsMode.getSnapContext();
873 moveBendsMode.setSnappingEnabled(isGridSnappingEnabled() || isSnappingEnabled());
874
875 configureSnapContext(snapContext);
876 moveBendsMode.setRemovingInnerBends(isRemovingInnerBends());
877 }
878 {
879 CreateEdgeMode createEdgeMode = (CreateEdgeMode) editMode.getCreateEdgeMode();
880 MoveSnapContext snapContext = createEdgeMode.getSnapContext();
881 if (isSnappingEnabled()) {
882 createEdgeMode.setSnapToOrthogonalSegmentsDistance(5.0);
883 createEdgeMode.setUsingNodeCenterSnapping(true);
884 createEdgeMode.setSnappingOrthogonalSegments(true);
885 } else {
886 createEdgeMode.setSnapToOrthogonalSegmentsDistance(0.0);
887 createEdgeMode.setUsingNodeCenterSnapping(false);
888 createEdgeMode.setSnappingOrthogonalSegments(false);
889 }
890
891 configureSnapContext(snapContext);
892 }
893 if (editMode.getMovePortMode() instanceof MovePortMode) {
894 MovePortMode movePortMode = (MovePortMode) editMode.getMovePortMode();
895 movePortMode.setUsingRealizerPortCandidates(!isSnappingEnabled());
896 movePortMode.setSegmentSnappingEnabled(isSnappingEnabled());
897 MoveSnapContext snapContext = movePortMode.getSnapContext();
898 configureSnapContext(snapContext);
899 }
900 if(editMode.getMoveLabelMode() instanceof MoveLabelMode) {
901 final MoveLabelMode moveLabelMode = (MoveLabelMode) editMode.getMoveLabelMode();
902 moveLabelMode.setSnappingEnabled(isSnappingEnabled());
903 }
904 }
905
906
911 public void configureSnapContext(final MoveSnapContext snapContext) {
912
913 snapContext.setSnapLineColor(getSnapLineColor());
914 snapContext.setSnapDistance(getSnapDistance());
915 snapContext.setGridSnapDistance(getGridSnapDistance());
916 snapContext.setSnapLineExtension(getSnapLineExtension());
917
918 snapContext.setUsingGridSnapping(isGridSnappingEnabled());
919 snapContext.setRenderingSnapLines(isGridSnappingEnabled() || isSnappingEnabled());
920
921 if (isGridSnappingEnabled() && !isSnappingEnabled()) {
922 snapContext.setSnappingBendsToSnapLines(false);
923 snapContext.setSnappingSegmentsToSnapLines(false);
924 snapContext.setUsingCenterSnapLines(false);
925 snapContext.setUsingEquidistantSnapLines(false);
926 snapContext.setUsingFixedNodeSnapLines(false);
927 snapContext.setUsingOrthogonalBendSnapping(false);
928 snapContext.setUsingOrthogonalMovementConstraints(false);
929 snapContext.setUsingOrthogonalPortSnapping(false);
930 snapContext.setUsingSegmentSnapLines(false);
931
932 snapContext.setEdgeToEdgeDistance(0.0);
934 snapContext.setNodeToEdgeDistance(-1.0);
935 snapContext.setNodeToNodeDistance(0.0);
936 } else {
937 snapContext.setSnappingBendsToSnapLines(false);
938 snapContext.setSnappingSegmentsToSnapLines(true);
939 snapContext.setUsingCenterSnapLines(false);
940 snapContext.setUsingEquidistantSnapLines(true);
941 snapContext.setUsingFixedNodeSnapLines(true);
942 snapContext.setUsingOrthogonalBendSnapping(true);
943 snapContext.setUsingOrthogonalMovementConstraints(true);
944 snapContext.setUsingOrthogonalPortSnapping(true);
945 snapContext.setUsingSegmentSnapLines(true);
946
947 snapContext.setEdgeToEdgeDistance(getEdgeToEdgeDistance());
948 snapContext.setNodeToEdgeDistance(getNodeToEdgeDistance());
949 snapContext.setNodeToNodeDistance(getNodeToNodeDistance());
950 }
951 }
952 }
953
954
957 public static SnappingConfiguration createDefaultSnappingConfiguration() {
958 SnappingConfiguration result = new SnappingConfiguration();
959 result.setSnappingEnabled(true);
960 result.setGridSnappingEnabled(false);
961 result.setSnapLineColor(Color.LIGHT_GRAY);
962 result.setRemovingInnerBends(true);
963 result.setNodeToNodeDistance(30.0);
964 result.setNodeToEdgeDistance(20.0);
965 result.setEdgeToEdgeDistance(20.0);
966 result.setSnapDistance(5.0);
967 result.setGridSnapDistance(10.0);
968 result.setSnapLineExtension(40.0);
969 result.setGridDistance(50.0);
970 result.setGridType(View2DConstants.GRID_CROSS);
971 return result;
972 }
973
974
981 public static JComponent createActionControl(final Action action) {
982 return createActionControl(action, true);
983 }
984
985
993 public static JComponent createActionControl(final Action action, final boolean showActionText) {
994 final JButton jb = new JButton();
995 if (action.getValue(Action.SMALL_ICON) != null) {
996 jb.putClientProperty("hideActionText", Boolean.valueOf(!showActionText));
997 }
998 jb.setAction(action);
999 return jb;
1000 }
1001
1002
1013 public static Icon getIconResource( final String resource ) {
1014 try {
1015 final URL icon = DemoBase.class.getResource(resource);
1016 if (icon == null) {
1017 return null;
1018 } else {
1019 return new ImageIcon(icon);
1020 }
1021 } catch (Exception e) {
1022 return null;
1023 }
1024 }
1025
1026
1029 public static class OptionSupport {
1030 private final EditorFactory editorFactory;
1031
1032
1041 public static void showDialog(final YModule module, final Graph2D graph, final boolean runOnOk, Frame owner) {
1042 if (module.getOptionHandler() == null) {
1043 module.start(graph);
1044 } else {
1045 final ActionListener listener = new ActionListener() {
1046 public void actionPerformed(ActionEvent e) {
1047 module.start(graph);
1048 }
1049 };
1050
1051 showDialog(module.getOptionHandler(), listener, runOnOk, owner);
1052 }
1053 }
1054
1055
1065 public static void showDialog(final OptionHandler oh, final ActionListener listener,
1066 final boolean runOnOk, Frame owner) {
1067 final ActionListener delegatingListener = new ActionListener() {
1068 public void actionPerformed(final ActionEvent e) {
1069 final String actionCommand = e.getActionCommand();
1070 if ("Apply".equals(actionCommand) || (runOnOk && "Ok".equals(actionCommand))) {
1071 EventQueue.invokeLater(new Runnable() {
1072 public void run() {
1073 listener.actionPerformed(e);
1074 }
1075 });
1076 }
1077 }
1078 };
1079
1080 final JDialog dialog = new OptionSupport().createDialog(oh, delegatingListener, owner);
1081 dialog.setVisible(true);
1082 }
1083
1084 public OptionSupport() {
1085 editorFactory = new DefaultEditorFactory();
1086 }
1087
1088
1096 public JDialog createDialog(final OptionHandler oh, ActionListener listener, Frame owner) {
1097 final JDialog dialog = new JDialog(owner, getTitle(oh), true);
1098
1099 final AbstractAction applyAction = new AbstractAction("Apply") {
1100 public void actionPerformed(ActionEvent e) {
1101 if (oh.checkValues()) {
1102 oh.commitValues();
1103 }
1104 }
1105 };
1106 final JButton applyButton = createButton(applyAction, listener);
1107 applyButton.setDefaultCapable(true);
1108 applyButton.requestFocus();
1109
1110 final AbstractAction closeAction = new AbstractAction("Cancel") {
1111 public void actionPerformed(ActionEvent e) {
1112 dialog.dispose();
1113 }
1114 };
1115
1116 final AbstractAction okAction = new AbstractAction("Ok") {
1117 public void actionPerformed(ActionEvent e) {
1118 if (oh.checkValues()) {
1119 oh.commitValues();
1120 dialog.dispose();
1121 }
1122 }
1123 };
1124
1125 final AbstractAction resetAction = new AbstractAction("Reset") {
1126 public void actionPerformed(ActionEvent e) {
1127 oh.resetValues();
1128 }
1129 };
1130
1131 final JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
1132 buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 11, 5));
1133 buttonPanel.add(createButton(okAction, listener));
1134 buttonPanel.add(createButton(closeAction, listener));
1135 buttonPanel.add(applyButton);
1136 buttonPanel.add(createButton(resetAction, listener));
1137
1138 final Editor editor = getEditorFactory().createEditor(oh);
1139 final JComponent editorComponent = editor.getComponent();
1140 if (editorComponent instanceof JPanel) {
1141 editorComponent.setBorder(BorderFactory.createEmptyBorder(11, 5, 5, 5));
1142 } else {
1143 editorComponent.setBorder(BorderFactory.createEmptyBorder(9, 9, 15, 9));
1144 }
1145
1146 final JPanel contentPanel = new JPanel(new BorderLayout(0, 0));
1147 contentPanel.add(editorComponent, BorderLayout.CENTER);
1148 contentPanel.add(buttonPanel, BorderLayout.SOUTH);
1149
1150 dialog.setContentPane(contentPanel);
1151 dialog.getRootPane().getInputMap().put(KeyStroke.getKeyStroke("ENTER"), "APPLY_ACTION");
1152 dialog.getRootPane().getActionMap().put("APPLY_ACTION", applyAction);
1153 dialog.getRootPane().getInputMap().put(KeyStroke.getKeyStroke("ESCAPE"), "CANCEL_ACTION");
1154 dialog.getRootPane().getActionMap().put("CANCEL_ACTION", closeAction);
1155 dialog.getRootPane().setDefaultButton(applyButton);
1156 dialog.pack();
1157 dialog.setSize(dialog.getPreferredSize());
1158 dialog.setResizable(false);
1159 dialog.setLocationRelativeTo(owner);
1160
1161 return dialog;
1162 }
1163
1164 protected EditorFactory getEditorFactory() {
1165 return editorFactory;
1166 }
1167
1168 String getTitle(OptionHandler oh) {
1169 final Object title = oh.getAttribute(OptionHandler.ATTRIBUTE_TITLE);
1170 if (title instanceof String) {
1171 return (String) title;
1172 }
1173
1174 final Object titleKey = oh.getAttribute(OptionHandler.ATTRIBUTE_TITLE_KEY);
1175 if (titleKey instanceof String) {
1176 return getTitle(oh, (String) titleKey);
1177 } else {
1178 return getTitle(oh, oh.getName());
1179 }
1180 }
1181
1182 static String getTitle(OptionHandler oh, String title) {
1183 final GuiFactory guiFactory = oh.getGuiFactory();
1184 return guiFactory == null ? title : guiFactory.getString(title);
1185 }
1186
1187 static JButton createButton(AbstractAction action, ActionListener listener) {
1188 final JButton button = new JButton(action);
1189 button.addActionListener(listener);
1190 return button;
1191
1192 }
1193 }
1194}
1195