1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.graphviz.drawable;
\r
14 import java.awt.Canvas;
\r
15 import java.awt.Color;
\r
16 import java.awt.Graphics;
\r
17 import java.awt.Graphics2D;
\r
18 import java.awt.Image;
\r
19 import java.awt.Point;
\r
20 import java.awt.RenderingHints;
\r
21 import java.awt.event.ActionEvent;
\r
22 import java.awt.event.ComponentAdapter;
\r
23 import java.awt.event.ComponentEvent;
\r
24 import java.awt.event.KeyAdapter;
\r
25 import java.awt.event.KeyEvent;
\r
26 import java.awt.event.MouseAdapter;
\r
27 import java.awt.event.MouseEvent;
\r
28 import java.awt.event.MouseWheelEvent;
\r
29 import java.awt.event.MouseWheelListener;
\r
30 import java.awt.event.WindowAdapter;
\r
31 import java.awt.event.WindowEvent;
\r
32 import java.awt.geom.AffineTransform;
\r
33 import java.awt.geom.Rectangle2D;
\r
34 import java.io.File;
\r
35 import java.io.IOException;
\r
37 import javax.swing.AbstractAction;
\r
38 import javax.swing.JFileChooser;
\r
39 import javax.swing.JFrame;
\r
40 import javax.swing.JMenu;
\r
41 import javax.swing.JMenuBar;
\r
42 import javax.swing.JMenuItem;
\r
43 import javax.swing.JOptionPane;
\r
44 import javax.swing.filechooser.FileFilter;
\r
45 import javax.swing.filechooser.FileView;
\r
47 import org.simantics.graphviz.Graph;
\r
48 import org.simantics.graphviz.Graphs;
\r
51 * A stand alone frame that shows and makes it
\r
52 * possible to navigate a given Drawable.
\r
54 * @author Hannu Niemistö
\r
56 public class JViewer extends JFrame {
\r
57 private static final long serialVersionUID = 3022682167091092801L;
\r
59 ViewerCanvas canvas = new ViewerCanvas();
\r
61 class ViewerCanvas extends Canvas {
\r
62 private static final long serialVersionUID = -5330090168115281754L;
\r
63 AffineTransform transform;
\r
68 setBackground(Color.WHITE);
\r
69 addKeyListener(new KeyAdapter() {
\r
72 public void keyPressed(KeyEvent e) {
\r
73 if(e.getKeyChar()=='1') {
\r
74 //System.out.println("a");
\r
78 else if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
\r
79 JViewer.this.dispose();
\r
84 addMouseListener(new MouseAdapter() {
\r
87 public void mousePressed(MouseEvent e) {
\r
88 prev = e.getPoint();
\r
91 addMouseMotionListener(new MouseAdapter() {
\r
93 public void mouseDragged(MouseEvent e) {
\r
94 Point cur = e.getPoint();
\r
97 double deltaX = cur.getX()-prev.getX();
\r
98 double deltaY = cur.getY()-prev.getY();
\r
99 transform.preConcatenate(AffineTransform.getTranslateInstance(deltaX, deltaY));
\r
104 addMouseWheelListener(new MouseWheelListener() {
\r
107 public void mouseWheelMoved(MouseWheelEvent e) {
\r
108 if(transform != null) {
\r
109 double scale = Math.exp(-0.1*e.getUnitsToScroll());
\r
110 Point p = e.getPoint();
\r
111 AffineTransform mod = new AffineTransform();
\r
112 mod.translate(p.getX(), p.getY());
\r
113 mod.scale(scale, scale);
\r
114 mod.translate(-p.getX(), -p.getY());
\r
115 transform.preConcatenate(mod);
\r
121 addComponentListener(new ComponentAdapter() {
\r
123 public void componentResized(ComponentEvent e) {
\r
124 im = createImage(getWidth(), getHeight());
\r
130 private void fit() {
\r
131 Rectangle2D bounds = drawable.getBounds();
\r
133 Rectangle2D container = getBounds();
\r
134 double scale = container == null ? 1 : Math.min(
\r
135 container.getWidth() / bounds.getWidth(),
\r
136 container.getHeight() / bounds.getHeight());
\r
138 transform = new AffineTransform(
\r
141 container.getX() + container.getWidth() * 0.5 - bounds.getCenterX() * scale,
\r
142 container.getY() + container.getHeight() * 0.5 - bounds.getCenterY() * scale
\r
147 public void paint(Graphics _g) {
\r
149 im = createImage(getWidth(), getHeight());
\r
150 Graphics2D g = (Graphics2D)im.getGraphics();
\r
152 g.clearRect(0, 0, im.getWidth(null), im.getHeight(null));
\r
154 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
\r
155 g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
\r
156 g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
\r
158 if(transform == null)
\r
160 g.setTransform(transform);
\r
162 drawable.draw(g, null);
\r
164 _g.drawImage(im, 0, 0, this);
\r
168 public void update(Graphics g) {
\r
174 public JViewer(Drawable _drawable) {
\r
175 this.drawable = _drawable;
\r
176 setTitle("Image viewer");
\r
177 setSize(1024, 768);
\r
178 addWindowListener(new WindowAdapter(){
\r
179 public void windowClosing(WindowEvent we){
\r
183 public void windowActivated(WindowEvent e) {
\r
184 repaint(0, 0, getWidth(), getHeight());
\r
187 public void windowGainedFocus(WindowEvent e) {
\r
191 getContentPane().add(canvas);
\r
193 JMenuBar menuBar = new JMenuBar();
\r
195 JMenu menu = new JMenu("File");
\r
198 JMenuItem saveItem = new JMenuItem(new SaveAsAction());
\r
199 JMenuItem exitItem = new JMenuItem(new ExitAction());
\r
200 menu.add(saveItem);
\r
201 menu.addSeparator();
\r
202 menu.add(exitItem);
\r
203 setJMenuBar(menuBar);
\r
208 public class ExitAction extends AbstractAction {
\r
210 private static final long serialVersionUID = 5680421985865931443L;
\r
212 public ExitAction() {
\r
217 public void actionPerformed(ActionEvent e) {
\r
218 JViewer.this.setVisible(false);
\r
219 JViewer.this.dispose();
\r
223 public class SaveAsAction extends AbstractAction {
\r
225 private static final long serialVersionUID = 4627419396805081199L;
\r
227 public SaveAsAction() {
\r
232 public void actionPerformed(ActionEvent e) {
\r
233 if (!(drawable instanceof GraphDrawable)) {
\r
234 JOptionPane.showMessageDialog(JViewer.this, "File saving not supported", "Error",JOptionPane.ERROR_MESSAGE);
\r
237 GraphDrawable gdraw = (GraphDrawable)drawable;
\r
238 Graph graph = gdraw.getGraph();
\r
239 String algo = gdraw.getAlgorithm();
\r
240 JFileChooser chooser = new JFileChooser();
\r
241 chooser.addChoosableFileFilter(new DotImageFilter());
\r
242 chooser.setAcceptAllFileFilterUsed(false);
\r
243 chooser.setFileView(new DotImageFileView());
\r
244 int returnval = chooser.showSaveDialog(JViewer.this);
\r
245 if (returnval == JFileChooser.APPROVE_OPTION) {
\r
247 File file = chooser.getSelectedFile();
\r
249 String type = getExtension(file);
\r
252 Graphs.createImage(graph, algo, type, file);
\r
253 } catch (IOException err) {
\r
254 err.printStackTrace();
\r
255 JOptionPane.showMessageDialog(JViewer.this, "File saving failed: " + err.getMessage(), "Error",JOptionPane.ERROR_MESSAGE);
\r
261 public static String getExtension(File file) {
\r
262 String filename = file.getName();
\r
263 int index = filename.lastIndexOf(".");
\r
266 return filename.substring(index+1).toLowerCase();
\r
269 public class DotImageFilter extends FileFilter {
\r
271 public boolean accept(File f) {
\r
272 if (f.isDirectory())
\r
274 String ext = getExtension(f);
\r
277 if (ext.equals("svg"))
\r
279 if (ext.equals("dot"))
\r
281 if (ext.equals("eps"))
\r
283 if (ext.equals("jpg"))
\r
285 if (ext.equals("jpeg"))
\r
287 if (ext.equals("pdf"))
\r
289 if (ext.equals("png"))
\r
291 if (ext.equals("ps"))
\r
297 public String getDescription() {
\r
298 return "Image files";
\r
302 public class DotImageFileView extends FileView {
\r
304 public String getTypeDescription(File f) {
\r
305 String ext = getExtension(f);
\r
308 if (ext.equals("svg"))
\r
309 return "Scalable Vector Graphics Image";
\r
310 if (ext.equals("dot"))
\r
311 return "DOT Image";
\r
312 if (ext.equals("eps"))
\r
313 return "Encapsulated PostScript Image";
\r
314 if (ext.equals("jpg"))
\r
315 return "JPG Image";
\r
316 if (ext.equals("jpeg"))
\r
317 return "JPG Image";
\r
318 if (ext.equals("pdf"))
\r
319 return "Portable Document Format Image";
\r
320 if (ext.equals("png"))
\r
321 return "Portable Network Graphics Image";
\r
322 if (ext.equals("ps"))
\r
323 return "PostScript Image";
\r