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