1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.graphviz.drawable;
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;
35 import java.io.IOException;
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;
47 import org.simantics.graphviz.Graph;
48 import org.simantics.graphviz.Graphs;
51 * A stand alone frame that shows and makes it
52 * possible to navigate a given Drawable.
54 * @author Hannu Niemistö
56 public class JViewer extends JFrame {
57 private static final long serialVersionUID = 3022682167091092801L;
59 ViewerCanvas canvas = new ViewerCanvas();
61 class ViewerCanvas extends Canvas {
62 private static final long serialVersionUID = -5330090168115281754L;
63 AffineTransform transform;
68 setBackground(Color.WHITE);
69 addKeyListener(new KeyAdapter() {
72 public void keyPressed(KeyEvent e) {
73 if(e.getKeyChar()=='1') {
74 //System.out.println("a");
78 else if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
79 JViewer.this.dispose();
84 addMouseListener(new MouseAdapter() {
87 public void mousePressed(MouseEvent e) {
91 addMouseMotionListener(new MouseAdapter() {
93 public void mouseDragged(MouseEvent e) {
94 Point cur = e.getPoint();
97 double deltaX = cur.getX()-prev.getX();
98 double deltaY = cur.getY()-prev.getY();
99 transform.preConcatenate(AffineTransform.getTranslateInstance(deltaX, deltaY));
104 addMouseWheelListener(new MouseWheelListener() {
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);
121 addComponentListener(new ComponentAdapter() {
123 public void componentResized(ComponentEvent e) {
124 im = createImage(getWidth(), getHeight());
131 Rectangle2D bounds = drawable.getBounds();
133 Rectangle2D container = getBounds();
134 double scale = container == null ? 1 : Math.min(
135 container.getWidth() / bounds.getWidth(),
136 container.getHeight() / bounds.getHeight());
138 transform = new AffineTransform(
141 container.getX() + container.getWidth() * 0.5 - bounds.getCenterX() * scale,
142 container.getY() + container.getHeight() * 0.5 - bounds.getCenterY() * scale
147 public void paint(Graphics _g) {
149 im = createImage(getWidth(), getHeight());
150 Graphics2D g = (Graphics2D)im.getGraphics();
152 g.clearRect(0, 0, im.getWidth(null), im.getHeight(null));
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);
158 if(transform == null)
160 g.setTransform(transform);
162 drawable.draw(g, null);
164 _g.drawImage(im, 0, 0, this);
168 public void update(Graphics g) {
174 public JViewer(Drawable _drawable) {
175 this.drawable = _drawable;
176 setTitle("Image viewer");
178 addWindowListener(new WindowAdapter(){
179 public void windowClosing(WindowEvent we){
183 public void windowActivated(WindowEvent e) {
184 repaint(0, 0, getWidth(), getHeight());
187 public void windowGainedFocus(WindowEvent e) {
191 getContentPane().add(canvas);
193 JMenuBar menuBar = new JMenuBar();
195 JMenu menu = new JMenu("File");
198 JMenuItem saveItem = new JMenuItem(new SaveAsAction());
199 JMenuItem exitItem = new JMenuItem(new ExitAction());
203 setJMenuBar(menuBar);
208 public class ExitAction extends AbstractAction {
210 private static final long serialVersionUID = 5680421985865931443L;
212 public ExitAction() {
217 public void actionPerformed(ActionEvent e) {
218 JViewer.this.setVisible(false);
219 JViewer.this.dispose();
223 public class SaveAsAction extends AbstractAction {
225 private static final long serialVersionUID = 4627419396805081199L;
227 public SaveAsAction() {
232 public void actionPerformed(ActionEvent e) {
233 if (!(drawable instanceof GraphDrawable)) {
234 JOptionPane.showMessageDialog(JViewer.this, "File saving not supported", "Error",JOptionPane.ERROR_MESSAGE);
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) {
247 File file = chooser.getSelectedFile();
249 String type = getExtension(file);
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);
261 public static String getExtension(File file) {
262 String filename = file.getName();
263 int index = filename.lastIndexOf(".");
266 return filename.substring(index+1).toLowerCase();
269 public class DotImageFilter extends FileFilter {
271 public boolean accept(File f) {
274 String ext = getExtension(f);
277 if (ext.equals("svg"))
279 if (ext.equals("dot"))
281 if (ext.equals("eps"))
283 if (ext.equals("jpg"))
285 if (ext.equals("jpeg"))
287 if (ext.equals("pdf"))
289 if (ext.equals("png"))
291 if (ext.equals("ps"))
297 public String getDescription() {
298 return "Image files";
302 public class DotImageFileView extends FileView {
304 public String getTypeDescription(File f) {
305 String ext = getExtension(f);
308 if (ext.equals("svg"))
309 return "Scalable Vector Graphics Image";
310 if (ext.equals("dot"))
312 if (ext.equals("eps"))
313 return "Encapsulated PostScript Image";
314 if (ext.equals("jpg"))
316 if (ext.equals("jpeg"))
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";