]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graphviz/src/org/simantics/graphviz/drawable/JViewer.java
6f972d746d4e22620e8c7328acdb8bd54c8b14ab
[simantics/platform.git] / bundles / org.simantics.graphviz / src / org / simantics / graphviz / drawable / JViewer.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.graphviz.drawable;
13
14 import java.awt.Canvas;
15 import java.awt.Color;
16 import java.awt.Graphics;
17 import java.awt.Graphics2D;
18 import java.awt.Image;
19 import java.awt.Point;
20 import java.awt.RenderingHints;
21 import java.awt.event.ActionEvent;
22 import java.awt.event.ComponentAdapter;
23 import java.awt.event.ComponentEvent;
24 import java.awt.event.KeyAdapter;
25 import java.awt.event.KeyEvent;
26 import java.awt.event.MouseAdapter;
27 import java.awt.event.MouseEvent;
28 import java.awt.event.MouseWheelEvent;
29 import java.awt.event.MouseWheelListener;
30 import java.awt.event.WindowAdapter;
31 import java.awt.event.WindowEvent;
32 import java.awt.geom.AffineTransform;
33 import java.awt.geom.Rectangle2D;
34 import java.io.File;
35 import java.io.IOException;
36
37 import javax.swing.AbstractAction;
38 import javax.swing.JFileChooser;
39 import javax.swing.JFrame;
40 import javax.swing.JMenu;
41 import javax.swing.JMenuBar;
42 import javax.swing.JMenuItem;
43 import javax.swing.JOptionPane;
44 import javax.swing.filechooser.FileFilter;
45 import javax.swing.filechooser.FileView;
46
47 import org.simantics.graphviz.Graph;
48 import org.simantics.graphviz.Graphs;
49
50 /**
51  * A stand alone frame that shows and makes it
52  * possible to navigate a given Drawable.
53  * 
54  * @author Hannu Niemistö
55  */
56 public class JViewer extends JFrame {
57         private static final long serialVersionUID = 3022682167091092801L;
58         Drawable drawable;
59         ViewerCanvas canvas = new ViewerCanvas();
60         
61         class ViewerCanvas extends Canvas {
62                 private static final long serialVersionUID = -5330090168115281754L;
63                 AffineTransform transform;
64         Point prev;
65         Image im;
66                 
67         ViewerCanvas() {                
68                 setBackground(Color.WHITE);    
69                 addKeyListener(new KeyAdapter() {
70                         
71                         @Override
72                         public void keyPressed(KeyEvent e) {
73                                 if(e.getKeyChar()=='1') {
74                                         //System.out.println("a");
75                                         canvas.fit();
76                                         canvas.repaint();
77                                 }
78                                 else if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
79                                         JViewer.this.dispose();
80                                 }
81                         }
82                         
83                 });
84                 addMouseListener(new MouseAdapter() {
85                         
86                         @Override
87                         public void mousePressed(MouseEvent e) {
88                                 prev = e.getPoint();
89                         }                       
90                 });
91                 addMouseMotionListener(new MouseAdapter() {
92                         @Override
93                         public void mouseDragged(MouseEvent e) {
94                                 Point cur = e.getPoint();
95                                 if (prev == null)
96                                     prev = cur;
97                                 double deltaX = cur.getX()-prev.getX();
98                                 double deltaY = cur.getY()-prev.getY();
99                                 transform.preConcatenate(AffineTransform.getTranslateInstance(deltaX, deltaY));                                         
100                                 repaint();
101                                 prev = cur;
102                         }
103                 });
104                 addMouseWheelListener(new MouseWheelListener() {
105
106                                 @Override
107                                 public void mouseWheelMoved(MouseWheelEvent e) {
108                                         if(transform != null) {
109                                                 double scale = Math.exp(-0.1*e.getUnitsToScroll());
110                                                 Point p = e.getPoint();
111                                                 AffineTransform mod = new AffineTransform();
112                                                 mod.translate(p.getX(), p.getY());
113                                                 mod.scale(scale, scale);
114                                                 mod.translate(-p.getX(), -p.getY());
115                                                 transform.preConcatenate(mod);                                          
116                                                 repaint();
117                                         }
118                                 }
119                         
120                 });
121                 addComponentListener(new ComponentAdapter() {
122                         @Override
123                         public void componentResized(ComponentEvent e) {
124                                 im = createImage(getWidth(), getHeight());
125                                 repaint();
126                         }
127                 });
128         }
129                 
130         private void fit() {
131                 Rectangle2D bounds = drawable.getBounds();
132                 
133                 Rectangle2D container = getBounds();
134                 double scale = container == null ? 1 : Math.min(
135                                 container.getWidth() / bounds.getWidth(), 
136                                 container.getHeight() / bounds.getHeight());
137                 
138                 transform = new AffineTransform(
139                                 scale, 0.0,
140                                 0.0, scale,
141                                 container.getX() + container.getWidth() * 0.5 - bounds.getCenterX() * scale,
142                                 container.getY() + container.getHeight() * 0.5 - bounds.getCenterY() * scale
143                                 );
144         }
145         
146         @Override
147         public void paint(Graphics _g) {
148                 if(im == null)
149                         im = createImage(getWidth(), getHeight());
150                 Graphics2D g = (Graphics2D)im.getGraphics();
151                 
152                 g.clearRect(0, 0, im.getWidth(null), im.getHeight(null));
153                 
154                 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
155                 g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
156                 g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
157                                 
158                 if(transform == null)
159                         fit();
160                 g.setTransform(transform);
161                 
162                 drawable.draw(g, null);
163                 
164                 _g.drawImage(im, 0, 0, this);
165         }
166         
167         @Override
168         public void update(Graphics g) {
169                 paint(g);
170         }
171         
172     }
173         
174         public JViewer(Drawable _drawable) {
175                 this.drawable = _drawable;
176                 setTitle("Image viewer");
177                 setSize(1024, 768);
178             addWindowListener(new WindowAdapter(){
179                 public void windowClosing(WindowEvent we){
180                         dispose();
181                 }               
182                 @Override
183                 public void windowActivated(WindowEvent e) {
184                         repaint(0, 0, getWidth(), getHeight());             
185                 }
186                 @Override
187                 public void windowGainedFocus(WindowEvent e) {
188                     requestFocus();
189                 }
190             });
191             getContentPane().add(canvas);
192             
193             JMenuBar menuBar = new JMenuBar();
194             
195             JMenu menu = new JMenu("File");
196             menuBar.add(menu);
197             
198             JMenuItem saveItem = new JMenuItem(new SaveAsAction());
199             JMenuItem exitItem = new JMenuItem(new ExitAction());
200             menu.add(saveItem);
201             menu.addSeparator();
202             menu.add(exitItem);
203             setJMenuBar(menuBar);
204             
205             setVisible(true);
206         }
207         
208         public class ExitAction extends AbstractAction {
209
210                 private static final long serialVersionUID = 5680421985865931443L;
211
212                 public ExitAction() {
213                         super("Exit");
214                 }
215                 
216                 @Override
217                 public void actionPerformed(ActionEvent e) {
218                         JViewer.this.setVisible(false);
219                         JViewer.this.dispose();
220                 }
221         }
222         
223         public class SaveAsAction extends AbstractAction {
224                 
225                 private static final long serialVersionUID = 4627419396805081199L;
226
227                 public SaveAsAction() {
228                         super("Save as");
229                 }
230                 
231                 @Override
232                 public void actionPerformed(ActionEvent e) {
233                         if (!(drawable instanceof GraphDrawable)) {
234                                 JOptionPane.showMessageDialog(JViewer.this, "File saving not supported", "Error",JOptionPane.ERROR_MESSAGE);
235                                 return;
236                         }
237                         GraphDrawable gdraw = (GraphDrawable)drawable;
238                         Graph graph = gdraw.getGraph();
239                         String algo = gdraw.getAlgorithm();
240                         JFileChooser chooser = new JFileChooser();
241                         chooser.addChoosableFileFilter(new DotImageFilter());
242                         chooser.setAcceptAllFileFilterUsed(false);
243                         chooser.setFileView(new DotImageFileView());
244                         int returnval = chooser.showSaveDialog(JViewer.this);
245                         if (returnval == JFileChooser.APPROVE_OPTION) {
246                                 try {
247                                         File file = chooser.getSelectedFile();
248                                 
249                                         String type = getExtension(file);
250                                         if (type == null)
251                                                 return;
252                                         Graphs.createImage(graph, algo, type, file);
253                                 } catch (IOException err) {
254                                         err.printStackTrace();
255                                         JOptionPane.showMessageDialog(JViewer.this, "File saving failed: " + err.getMessage(), "Error",JOptionPane.ERROR_MESSAGE);
256                                 }
257                         }
258                 }
259         }
260         
261         public static String getExtension(File file) {
262                 String filename = file.getName();
263                 int index = filename.lastIndexOf(".");
264                 if (index < 0)
265                         return null;
266                 return filename.substring(index+1).toLowerCase();
267         }
268         
269         public class DotImageFilter extends FileFilter {
270                 @Override
271                 public boolean accept(File f) {
272                         if (f.isDirectory())
273                                 return true;
274                         String ext = getExtension(f);
275                         if (ext == null)
276                                 return false;
277                         if (ext.equals("svg"))
278                                 return true;
279                         if (ext.equals("dot"))
280                                 return true;
281                         if (ext.equals("eps"))
282                                 return true;
283                         if (ext.equals("jpg"))
284                                 return true;
285                         if (ext.equals("jpeg"))
286                                 return true;
287                         if (ext.equals("pdf"))
288                                 return true;
289                         if (ext.equals("png"))
290                                 return true;
291                         if (ext.equals("ps"))
292                                 return true;
293                         return false;
294                 }
295                 
296                 @Override
297                 public String getDescription() {
298                         return "Image files";
299                 }
300         }
301         
302         public class DotImageFileView extends FileView {
303                 @Override
304                 public String getTypeDescription(File f) {
305                         String ext = getExtension(f);
306                         if (ext == null)
307                                 return null;
308                         if (ext.equals("svg"))
309                                 return "Scalable Vector Graphics Image";
310                         if (ext.equals("dot"))
311                                 return "DOT Image";
312                         if (ext.equals("eps"))
313                                 return "Encapsulated PostScript Image";
314                         if (ext.equals("jpg"))
315                                 return "JPG Image";
316                         if (ext.equals("jpeg"))
317                                 return "JPG Image";
318                         if (ext.equals("pdf"))
319                                 return "Portable Document Format Image";
320                         if (ext.equals("png"))
321                                 return "Portable Network Graphics Image";
322                         if (ext.equals("ps"))
323                                 return "PostScript Image";
324                         return null;
325                 }
326         }
327         
328 }