1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.6. 
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-2008 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.view.*;
17  import y.option.OptionHandler;
18  import y.io.GMLIOHandler;
19  import y.io.YGFIOHandler;
20  import y.util.D;
21  import y.base.DataProvider;
22  
23  import javax.swing.*;
24  import java.awt.*;
25  import java.awt.print.PageFormat;
26  import java.awt.print.PrinterJob;
27  import java.awt.event.ActionEvent;
28  import java.io.IOException;
29  import java.net.URL;
30  import java.net.MalformedURLException;
31  import java.util.Iterator;
32  
33  /**
34   *  Demonstrates basic usage of the Graph2DView.
35   *
36   *  Demonstrates how some actions can be performed on the view.
37   *  The actions are:
38   *  <ul>
39   *    <li>Remove selected parts of the view content</li>
40   *    <li>Zoom out of the view</li>
41   *    <li>Zoom in on the view</li>
42   *    <li>Zoom to the selected parts of the view content</li>
43   *    <li>Fit view content to the size of the the view</li>
44   *    <li>Print a graph</li>
45   *  </ul>
46   *
47   *  Additionally, this demo shows how to set up the default edit mode
48   *  to display tool tips over nodes.
49   *
50   */
51  public class DemoEditor extends JPanel {
52  
53    /**
54     * The view component of this demo.
55     */
56    protected Graph2DView view;
57    /**
58     * The view mode to be used with the view.
59     */
60    protected EditMode editMode;
61  
62  
63    public DemoEditor() {
64      setLayout(new BorderLayout());
65  
66      view = new Graph2DView();
67      view.setAntialiasedPainting(true);
68      view.getCanvasComponent().addMouseWheelListener( new Graph2DViewMouseWheelZoomListener() );
69  
70      editMode = createEditMode();
71      if (editMode != null) {
72        view.addViewMode(editMode);
73      }
74  
75      Graph2DViewActions actions = new Graph2DViewActions(view);
76      ActionMap amap = actions.createActionMap();
77      amap.remove(Graph2DViewActions.DELETE_SELECTION);
78      InputMap imap = actions.createDefaultInputMap(amap);
79      view.getCanvasComponent().setActionMap(amap);
80      view.getCanvasComponent().setInputMap(JComponent.WHEN_FOCUSED, imap);
81  
82      add(view, BorderLayout.CENTER);
83      add(createToolBar(), BorderLayout.NORTH);
84    }
85  
86    protected EditMode createEditMode() {
87      final EditMode editMode = new EditMode();
88      editMode.showNodeTips(true);
89      return editMode;
90    }
91  
92    /**
93     * Creates a toolbar for this demo.
94     */
95    protected JToolBar createToolBar()
96    {
97      JToolBar bar = new JToolBar();
98      bar.add( new AbstractAction( "Clear",new ImageIcon( getClass().getResource( "resource/New16.gif" ) ) ) {
99        public void actionPerformed( ActionEvent e ) {
100         view.getGraph2D().clear();
101         view.updateView();
102       }
103     });
104     bar.add( new DemoEditor.DeleteSelection() );
105     bar.add(new DemoEditor.Zoom(1.2));
106     bar.add(new DemoEditor.Zoom(0.8));
107     bar.add(new DemoEditor.ZoomArea());
108     bar.add(new DemoEditor.FitContent());
109 
110     return bar;
111   }
112 
113   /**
114    * Create a menu bar for this demo.
115    */
116   protected JMenuBar createMenuBar()
117   {
118     JMenuBar bar = new JMenuBar();
119     JMenu menu = new JMenu("File");
120 //    menu.add(createLoadAction());
121 //    menu.add(createSaveAction());
122 //    menu.addSeparator();
123     menu.add(new DemoEditor.PrintAction());
124 //    menu.addSeparator();
125 //    menu.add(new DemoEditor.ExitAction());
126     bar.add(menu);
127     return bar;
128   }
129 
130   protected Action createLoadAction()
131   {
132     return new DemoEditor.LoadAction();
133   }
134 
135   protected Action createSaveAction()
136   {
137     return new DemoEditor.SaveAction();
138   }
139 
140   /**
141    * Creates an application  frame for this demo
142    * and displays it. The given string is the title of
143    * the displayed frame.
144    */
145   public void start( final String title )
146   {
147     JFrame frame = new JFrame(title);
148     frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
149     addContentTo(frame.getRootPane());
150     frame.pack();
151     frame.setLocationRelativeTo(null);
152     frame.setVisible(true);
153   }
154 
155   public final void addContentTo( final JRootPane rootPane )
156   {
157     rootPane.setJMenuBar(createMenuBar());
158     rootPane.setContentPane(this);
159   }
160 
161   /**
162    * Initializes to a "nice" look and feel.
163    */
164   public static void initLnF(){
165     try
166     {
167       if(!UIManager.getSystemLookAndFeelClassName().equals(
168         "com.sun.java.swing.plaf.motif.MotifLookAndFeel") &&
169         !UIManager.getSystemLookAndFeelClassName().equals(
170         "com.sun.java.swing.plaf.gtk.GTKLookAndFeel") &&
171          !UIManager.getSystemLookAndFeelClassName().equals(
172            UIManager.getLookAndFeel().getClass().getName()))
173       {
174         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
175       }
176     }
177     catch (Exception e)
178     {
179       e.printStackTrace();
180     }
181   }
182 
183   /**
184    * Launches this demo.
185    */
186   public static void main(String args[])
187   {
188     initLnF();
189     DemoEditor demo = new DemoEditor();
190     demo.start(demo.getClass().getName());
191   }
192 
193 
194   /**
195    * Action that prints the contents of the view
196    */
197   protected class PrintAction extends AbstractAction
198   {
199     PageFormat pageFormat;
200     OptionHandler printOptions;
201 
202     public PrintAction()
203     {
204       super("Print");
205 
206       //setup option handler
207       printOptions = new OptionHandler("Print Options");
208       printOptions.addInt("Poster Rows",1);
209       printOptions.addInt("Poster Columns",1);
210       printOptions.addBool("Add Poster Coords",false);
211       final String[] area = {"View","Graph"};
212       printOptions.addEnum("Clip Area",area,1);
213     }
214 
215     public void actionPerformed( ActionEvent e)
216     {
217       Graph2DPrinter gprinter = new Graph2DPrinter(view);
218 
219       //show custom print dialog and adopt values
220       if(!printOptions.showEditor()) return;
221       gprinter.setPosterRows(printOptions.getInt("Poster Rows"));
222       gprinter.setPosterColumns(printOptions.getInt("Poster Columns"));
223       gprinter.setPrintPosterCoords(
224         printOptions.getBool("Add Poster Coords"));
225       if(printOptions.get("Clip Area").equals("Graph"))
226         gprinter.setClipType(Graph2DPrinter.CLIP_GRAPH);
227       else
228         gprinter.setClipType(Graph2DPrinter.CLIP_VIEW);
229 
230       //show default print dialogs
231       PrinterJob printJob = PrinterJob.getPrinterJob();
232       if(pageFormat == null) pageFormat = printJob.defaultPage();
233       PageFormat pf = printJob.pageDialog( pageFormat );
234       if(pf == pageFormat) return;
235       else pageFormat = pf;
236 
237       //setup printjob.
238       //Graph2DPrinter is of type Printable
239       printJob.setPrintable(gprinter, pageFormat);
240 
241       if (printJob.printDialog()) {
242         try {
243           printJob.print();
244         } catch (Exception ex) {
245           ex.printStackTrace();
246         }
247       }
248     }
249   }
250 
251   /**
252    * Action that terminates the application
253    */
254   protected class ExitAction extends AbstractAction
255   {
256     ExitAction()
257     {
258       super("Exit");
259     }
260 
261     public void actionPerformed(ActionEvent e)
262     {
263 
264       System.exit(0);
265     }
266   }
267 
268   /**
269    * Action that saves the current graph to a file in YGF format.
270    */
271   protected class SaveAction extends AbstractAction
272   {
273     JFileChooser chooser;
274     public SaveAction()
275     {
276       super("Save...");
277       chooser = null;
278     }
279 
280     public void actionPerformed(ActionEvent e)
281     {
282       if (chooser == null)
283       {
284         chooser = new JFileChooser();
285       }
286       if(chooser.showSaveDialog(DemoEditor.this) == JFileChooser.APPROVE_OPTION)
287       {
288         String name = chooser.getSelectedFile().toString();
289         if (name.endsWith(".gml")){
290           GMLIOHandler ioh = new GMLIOHandler();
291           try
292           {
293             ioh.write(view.getGraph2D(),name);
294           } catch ( IOException ioe){
295             D.show(ioe);
296           }
297         } else {
298           if(!name.endsWith(".ygf")) name = name + ".ygf";
299           YGFIOHandler ioh = new YGFIOHandler();
300           try
301           {
302             ioh.write(view.getGraph2D(),name);
303           } catch (IOException ioe){
304             D.show(ioe);
305           }
306         }
307       }
308     }
309   }
310 
311   /**
312    * Action that saves the current subset of the graph to a file in YGF format.
313    */
314   protected class SaveSubsetAction extends AbstractAction
315   {
316     JFileChooser chooser;
317     public SaveSubsetAction()
318     {
319       super("Save selection...");
320       chooser = null;
321     }
322 
323     public void actionPerformed(ActionEvent e)
324     {
325       if (chooser == null)
326       {
327         chooser = new JFileChooser();
328       }
329       if(chooser.showSaveDialog(DemoEditor.this) == JFileChooser.APPROVE_OPTION)
330       {
331         String name = chooser.getSelectedFile().toString();
332         if(!name.endsWith(".ygf")) name = name + ".ygf";
333         YGFIOHandler ioh = new YGFIOHandler();
334         try
335         {
336           DataProvider dp = Selections.createSelectionDataProvider(view.getGraph2D());
337           ioh.writeSubset(view.getGraph2D(), dp, name);
338         } catch (IOException ioe){
339           D.show(ioe);
340         }
341       }
342     }
343   }
344 
345   /**
346    * Action that loads the current graph from a file in YGF format.
347    */
348   protected class LoadAction extends AbstractAction
349   {
350     JFileChooser chooser;
351     public LoadAction()
352     {
353       super("Load...");
354       chooser = null;
355     }
356 
357     public void actionPerformed(ActionEvent e)
358     {
359       if (chooser == null)
360       {
361         chooser = new JFileChooser();
362       }
363       if(chooser.showOpenDialog(DemoEditor.this) == JFileChooser.APPROVE_OPTION)
364       {
365         try {
366           URL graphURL = chooser.getSelectedFile().toURL();
367           loadAndDisplayGraph(graphURL);
368         } catch (MalformedURLException e1) {
369           e1.printStackTrace();
370         }
371       }
372     }
373   }
374 
375   public void loadAndDisplayGraph(URL graphURL) {
376     String name = graphURL.getFile();
377     if (name.endsWith(".gml")) {
378       GMLIOHandler ioh = new GMLIOHandler();
379       try {
380         view.getGraph2D().clear();
381         ioh.read(view.getGraph2D(), graphURL);
382       } catch (IOException ioe) {
383         D.show(ioe);
384       }
385     } else {
386       if (!name.endsWith(".ygf")) name = name + ".ygf";
387       YGFIOHandler ioh = new YGFIOHandler();
388       try {
389         view.getGraph2D().clear();
390         ioh.read(view.getGraph2D(), graphURL);
391       } catch (IOException ioe) {
392         D.show(ioe);
393       }
394     }
395     //force redisplay of view contents
396     view.fitContent();
397     view.getGraph2D().updateViews();
398   }
399 
400   /**
401    * Action that deletes the selected parts of the graph.
402    */
403   protected class DeleteSelection extends AbstractAction
404   {
405     public DeleteSelection()
406     {
407       super("Delete Selection");
408       URL imageURL = getClass().getResource("resource/Delete16.gif");
409       if (imageURL != null){
410         this.putValue( Action.SMALL_ICON, new ImageIcon(imageURL));
411       }
412     }
413 
414     public void actionPerformed(ActionEvent e)
415     {
416       view.getGraph2D().removeSelection();
417       view.getGraph2D().updateViews();
418     }
419   }
420 
421   /**
422    * Action that applies a specified zoom level to the view.
423    */
424   protected class Zoom extends AbstractAction
425   {
426     double factor;
427 
428     public Zoom(double factor)
429     {
430       super("Zoom " + (factor > 1.0 ? "In" : "Out"));
431       URL imageURL;
432       if (factor > 1.0d){
433         imageURL = getClass().getResource("resource/ZoomIn16.gif");
434       } else {
435         imageURL = getClass().getResource("resource/ZoomOut16.gif");
436       }
437       if (imageURL != null){
438         this.putValue(Action.SMALL_ICON, new ImageIcon(imageURL));
439       }
440       this.factor = factor;
441     }
442 
443     public void actionPerformed(ActionEvent e)
444     {
445       view.setZoom(view.getZoom()*factor);
446       //optional code that adjusts the size of the
447       //view's world rectangle. The world rectangle
448       //defines the region of the canvas that is
449       //accessible by using the scrollbars of the view.
450       Rectangle box = view.getGraph2D().getBoundingBox();
451       view.setWorldRect(box.x-20,box.y-20,box.width+40,box.height+40);
452 
453       view.updateView();
454     }
455   }
456 
457   /**
458    * Action that fits the content nicely inside the view.
459    */
460   protected class FitContent extends AbstractAction
461   {
462     public FitContent()
463     {
464       super("Fit Content");
465       URL imageURL = getClass().getResource("resource/FitContent16.gif");
466       if (imageURL != null){
467         this.putValue(Action.SMALL_ICON, new ImageIcon(imageURL));
468       }
469     }
470 
471     public void actionPerformed(ActionEvent e)
472     {
473       view.fitContent();
474       view.updateView();
475     }
476   }
477 
478   /**
479    * Action that zooms the view to the selected box.
480    */
481   public class ZoomArea extends AbstractAction {
482     public ZoomArea() {
483       super( "Zoom Area" );
484       URL imageURL = getClass().getResource( "resource/Zoom16.gif" );
485       if ( imageURL != null ) {
486         this.putValue( Action.SMALL_ICON, new ImageIcon( imageURL ) );
487       }
488       this.putValue( Action.SHORT_DESCRIPTION, "Zoom Area");
489     }
490 
491     public void actionPerformed( ActionEvent e ) {
492       Iterator viewModes = view.getViewModes();
493       while ( viewModes.hasNext() ) {
494         ViewMode viewMode = ( ViewMode ) viewModes.next();
495         if (viewMode instanceof EditMode) {
496           EditMode editMode = ( EditMode ) viewMode;
497           editMode.setChild( new AreaZoomMode(), null, null );
498         }
499       }
500     }
501   }
502 }
503