1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.9. 
4    ** 
5    ** yWorks proprietary/confidential. Use is subject to license terms.
6    **
7    ** Redistribution of this file or of an unauthorized byte-code version
8    ** of this file is strictly forbidden.
9    **
10   ** Copyright (c) 2000-2011 by yWorks GmbH, Vor dem Kreuzberg 28, 
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  package demo.view.applet;
15  
16  import y.io.GraphMLIOHandler;
17  import y.io.IOHandler;
18  import y.option.OptionHandler;
19  import y.util.D;
20  import y.view.Arrow;
21  import y.view.EditMode;
22  import y.view.Graph2DPrinter;
23  import y.view.Graph2DView;
24  import y.view.Graph2DViewActions;
25  import y.view.Graph2DViewMouseWheelZoomListener;
26  import y.view.NodeLabel;
27  import y.view.NodeRealizer;
28  import y.view.SmartNodeLabelModel;
29  
30  import javax.swing.AbstractAction;
31  import javax.swing.Action;
32  import javax.swing.ImageIcon;
33  import javax.swing.JFrame;
34  import javax.swing.JMenu;
35  import javax.swing.JMenuBar;
36  import javax.swing.JPanel;
37  import javax.swing.JRootPane;
38  import javax.swing.JToolBar;
39  import java.awt.BorderLayout;
40  import java.awt.Color;
41  import java.awt.Rectangle;
42  import java.awt.event.ActionEvent;
43  import java.awt.print.PageFormat;
44  import java.awt.print.PrinterException;
45  import java.awt.print.PrinterJob;
46  import java.io.IOException;
47  import java.net.URL;
48  
49  /**
50   *  Demonstrates basic usage of the Graph2DView.
51   *
52   *  Demonstrates how some actions can be performed on the view.
53   *  The actions are:
54   *  <ul>
55   *    <li>Remove selected parts of the view content</li>
56   *    <li>Zoom out of the view</li>
57   *    <li>Zoom in on the view</li>
58   *    <li>Fit view content to the size of the the view</li>
59   *    <li>Print a graph</li>
60   *  </ul>
61   *
62   *  Additionally, this demo shows how to set up the default edit mode
63   *  to display tool tips over nodes.
64   *
65   */
66  public class DemoEditor extends JPanel {
67  
68    /**
69     * The view component of this demo.
70     */
71    protected Graph2DView view;
72    /**
73     * The view mode to be used with the view.
74     */
75    protected EditMode editMode;
76  
77  
78    public DemoEditor() {
79      setLayout(new BorderLayout());
80  
81      view = new Graph2DView();
82      view.setAntialiasedPainting(true);
83      view.getCanvasComponent().addMouseWheelListener(new Graph2DViewMouseWheelZoomListener());
84      
85      NodeRealizer nodeRealizer = view.getGraph2D().getDefaultNodeRealizer();
86      NodeLabel label = nodeRealizer.getLabel();
87      SmartNodeLabelModel labelModel = new SmartNodeLabelModel();
88      label.setLabelModel(labelModel);
89      label.setModelParameter(labelModel.getDefaultParameter());
90      nodeRealizer.setFillColor(new Color(0xFFCC00));
91      view.getGraph2D().getDefaultEdgeRealizer().setTargetArrow(Arrow.STANDARD);
92      
93      editMode = createEditMode();
94      if (editMode != null) {
95        view.addViewMode(editMode);
96      }
97          
98      Graph2DViewActions actions = new Graph2DViewActions(view);
99      actions.install();
100 
101     add(view, BorderLayout.CENTER);
102     add(createToolBar(), BorderLayout.NORTH);
103   }
104 
105   protected EditMode createEditMode() {
106     return new EditMode();
107   }
108 
109   /**
110    * Creates a toolbar for this demo.
111    */
112   protected JToolBar createToolBar() {
113     JToolBar bar = new JToolBar();
114     bar.add(new DemoEditor.DeleteSelection());
115     bar.add(new DemoEditor.Zoom(1.2));
116     bar.add(new DemoEditor.Zoom(0.8));
117     bar.add(new DemoEditor.FitContent());
118     return bar;
119   }
120 
121   /**
122    * Create a menu bar for this demo.
123    */
124   protected JMenuBar createMenuBar() {
125     JMenuBar bar = new JMenuBar();
126     JMenu menu = new JMenu("File");
127     menu.add(new DemoEditor.PrintAction());
128     bar.add(menu);
129     return bar;
130   }
131 
132   /**
133    * Creates an application  frame for this demo
134    * and displays it. The given string is the title of
135    * the displayed frame.
136    */
137   public void start(final String title) {
138     JFrame frame = new JFrame(title);
139     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
140     addContentTo(frame.getRootPane());
141     frame.pack();
142     frame.setLocationRelativeTo(null);
143     frame.setVisible(true);
144   }
145 
146   public final void addContentTo(final JRootPane rootPane) {
147     rootPane.setJMenuBar(createMenuBar());
148     rootPane.setContentPane(this);
149   }
150 
151   /**
152    * Action that prints the contents of the view
153    */
154   protected class PrintAction extends AbstractAction {
155     PageFormat pageFormat;
156     OptionHandler printOptions;
157 
158     public PrintAction() {
159       super("Print");
160 
161       //setup option handler
162       printOptions = new OptionHandler("Print Options");
163       printOptions.addInt("Poster Rows", 1);
164       printOptions.addInt("Poster Columns", 1);
165       printOptions.addBool("Add Poster Coords", false);
166       final String[] area = {"View", "Graph"};
167       printOptions.addEnum("Clip Area", area, 1);
168     }
169 
170     public void actionPerformed(ActionEvent e) {
171       Graph2DPrinter gprinter = new Graph2DPrinter(view);
172 
173       //show custom print dialog and adopt values
174       if (!printOptions.showEditor()) {
175         return;
176       }
177       gprinter.setPosterRows(printOptions.getInt("Poster Rows"));
178       gprinter.setPosterColumns(printOptions.getInt("Poster Columns"));
179       gprinter.setPrintPosterCoords(
180           printOptions.getBool("Add Poster Coords"));
181       if ("Graph".equals(printOptions.get("Clip Area"))) {
182         gprinter.setClipType(Graph2DPrinter.CLIP_GRAPH);
183       } else {
184         gprinter.setClipType(Graph2DPrinter.CLIP_VIEW);
185       }
186 
187       //show default print dialogs
188       PrinterJob printJob = PrinterJob.getPrinterJob();
189       if (pageFormat == null) {
190         pageFormat = printJob.defaultPage();
191       }
192       PageFormat pf = printJob.pageDialog(pageFormat);
193       if (pf == pageFormat) {
194         return;
195       } else {
196         pageFormat = pf;
197       }
198 
199       //setup printjob.
200       //Graph2DPrinter is of type Printable
201       printJob.setPrintable(gprinter, pageFormat);
202 
203       if (printJob.printDialog()) {
204         try {
205           printJob.print();
206         } catch (PrinterException ex) {
207           ex.printStackTrace();
208         }
209       }
210     }
211   }
212 
213   public void loadAndDisplayGraph(URL graphURL) {
214     IOHandler ioh = new GraphMLIOHandler();
215     try {
216       view.getGraph2D().clear();
217       ioh.read(view.getGraph2D(), graphURL);
218     } catch (IOException ioe) {
219       D.show(ioe);
220     }
221     //force redisplay of view contents
222     view.fitContent();
223     view.getGraph2D().updateViews();
224   }
225 
226   /**
227    * Action that deletes the selected parts of the graph.
228    */
229   protected class DeleteSelection extends AbstractAction {
230     public DeleteSelection() {
231       super("Delete Selection");
232       URL imageURL = getClass().getResource("resource/delete.png");
233       if (imageURL != null) {
234         this.putValue(Action.SMALL_ICON, new ImageIcon(imageURL));
235       }
236     }
237 
238     public void actionPerformed(ActionEvent e) {
239       view.getGraph2D().removeSelection();
240       view.getGraph2D().updateViews();
241     }
242   }
243 
244   /**
245    * Action that applies a specified zoom level to the view.
246    */
247   protected class Zoom extends AbstractAction {
248     double factor;
249 
250     public Zoom(double factor) {
251       super("Zoom " + (factor > 1.0 ? "In" : "Out"));
252       URL imageURL;
253       if (factor > 1.0d) {
254         imageURL = getClass().getResource("resource/zoomIn.png");
255       } else {
256         imageURL = getClass().getResource("resource/zoomOut.png");
257       }
258       if (imageURL != null) {
259         this.putValue(Action.SMALL_ICON, new ImageIcon(imageURL));
260       }
261       this.factor = factor;
262     }
263 
264     public void actionPerformed(ActionEvent e) {
265       view.setZoom(view.getZoom() * factor);
266       //optional code that adjusts the size of the
267       //view's world rectangle. The world rectangle
268       //defines the region of the canvas that is
269       //accessible by using the scrollbars of the view.
270       Rectangle box = view.getGraph2D().getBoundingBox();
271       view.setWorldRect(box.x - 20, box.y - 20, box.width + 40, box.height + 40);
272 
273       view.updateView();
274     }
275   }
276 
277   /**
278    * Action that fits the content nicely inside the view.
279    */
280   protected class FitContent extends AbstractAction {
281     public FitContent() {
282       super("Fit Content");
283       URL imageURL = getClass().getResource("resource/zoomFit.png");
284       if (imageURL != null) {
285         this.putValue(Action.SMALL_ICON, new ImageIcon(imageURL));
286       }
287     }
288 
289     public void actionPerformed(ActionEvent e) {
290       view.fitContent();
291       view.updateView();
292     }
293   }
294 }
295