X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.graphviz%2Fsrc%2Forg%2Fsimantics%2Fgraphviz%2Fdrawable%2FJViewer.java;fp=bundles%2Forg.simantics.graphviz%2Fsrc%2Forg%2Fsimantics%2Fgraphviz%2Fdrawable%2FJViewer.java;h=586ecc7a2039f9df9faac135004404bf7d8b31d2;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.graphviz/src/org/simantics/graphviz/drawable/JViewer.java b/bundles/org.simantics.graphviz/src/org/simantics/graphviz/drawable/JViewer.java new file mode 100644 index 000000000..586ecc7a2 --- /dev/null +++ b/bundles/org.simantics.graphviz/src/org/simantics/graphviz/drawable/JViewer.java @@ -0,0 +1,328 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.graphviz.drawable; + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Point; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.io.File; +import java.io.IOException; + +import javax.swing.AbstractAction; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileView; + +import org.simantics.graphviz.Graph; +import org.simantics.graphviz.Graphs; + +/** + * A stand alone frame that shows and makes it + * possible to navigate a given Drawable. + * + * @author Hannu Niemistö + */ +public class JViewer extends JFrame { + private static final long serialVersionUID = 3022682167091092801L; + Drawable drawable; + ViewerCanvas canvas = new ViewerCanvas(); + + class ViewerCanvas extends Canvas { + private static final long serialVersionUID = -5330090168115281754L; + AffineTransform transform; + Point prev; + Image im; + + ViewerCanvas() { + setBackground(Color.WHITE); + addKeyListener(new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent e) { + if(e.getKeyChar()=='1') { + //System.out.println("a"); + canvas.fit(); + canvas.repaint(); + } + else if(e.getKeyCode() == KeyEvent.VK_ESCAPE) { + JViewer.this.dispose(); + } + } + + }); + addMouseListener(new MouseAdapter() { + + @Override + public void mousePressed(MouseEvent e) { + prev = e.getPoint(); + } + }); + addMouseMotionListener(new MouseAdapter() { + @Override + public void mouseDragged(MouseEvent e) { + Point cur = e.getPoint(); + if (prev == null) + prev = cur; + double deltaX = cur.getX()-prev.getX(); + double deltaY = cur.getY()-prev.getY(); + transform.preConcatenate(AffineTransform.getTranslateInstance(deltaX, deltaY)); + repaint(); + prev = cur; + } + }); + addMouseWheelListener(new MouseWheelListener() { + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + if(transform != null) { + double scale = Math.exp(-0.1*e.getUnitsToScroll()); + Point p = e.getPoint(); + AffineTransform mod = new AffineTransform(); + mod.translate(p.getX(), p.getY()); + mod.scale(scale, scale); + mod.translate(-p.getX(), -p.getY()); + transform.preConcatenate(mod); + repaint(); + } + } + + }); + addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + im = createImage(getWidth(), getHeight()); + repaint(); + } + }); + } + + private void fit() { + Rectangle2D bounds = drawable.getBounds(); + + Rectangle2D container = getBounds(); + double scale = container == null ? 1 : Math.min( + container.getWidth() / bounds.getWidth(), + container.getHeight() / bounds.getHeight()); + + transform = new AffineTransform( + scale, 0.0, + 0.0, scale, + container.getX() + container.getWidth() * 0.5 - bounds.getCenterX() * scale, + container.getY() + container.getHeight() * 0.5 - bounds.getCenterY() * scale + ); + } + + @Override + public void paint(Graphics _g) { + if(im == null) + im = createImage(getWidth(), getHeight()); + Graphics2D g = (Graphics2D)im.getGraphics(); + + g.clearRect(0, 0, im.getWidth(null), im.getHeight(null)); + + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + + if(transform == null) + fit(); + g.setTransform(transform); + + drawable.draw(g, null); + + _g.drawImage(im, 0, 0, this); + } + + @Override + public void update(Graphics g) { + paint(g); + } + + } + + public JViewer(Drawable _drawable) { + this.drawable = _drawable; + setTitle("Image viewer"); + setSize(1024, 768); + addWindowListener(new WindowAdapter(){ + public void windowClosing(WindowEvent we){ + dispose(); + } + @Override + public void windowActivated(WindowEvent e) { + repaint(0, 0, getWidth(), getHeight()); + } + @Override + public void windowGainedFocus(WindowEvent e) { + requestFocus(); + } + }); + getContentPane().add(canvas); + + JMenuBar menuBar = new JMenuBar(); + + JMenu menu = new JMenu("File"); + menuBar.add(menu); + + JMenuItem saveItem = new JMenuItem(new SaveAsAction()); + JMenuItem exitItem = new JMenuItem(new ExitAction()); + menu.add(saveItem); + menu.addSeparator(); + menu.add(exitItem); + setJMenuBar(menuBar); + + setVisible(true); + } + + public class ExitAction extends AbstractAction { + + private static final long serialVersionUID = 5680421985865931443L; + + public ExitAction() { + super("Exit"); + } + + @Override + public void actionPerformed(ActionEvent e) { + JViewer.this.setVisible(false); + JViewer.this.dispose(); + } + } + + public class SaveAsAction extends AbstractAction { + + private static final long serialVersionUID = 4627419396805081199L; + + public SaveAsAction() { + super("Save as"); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (!(drawable instanceof GraphDrawable)) { + JOptionPane.showMessageDialog(JViewer.this, "File saving not supported", "Error",JOptionPane.ERROR_MESSAGE); + return; + } + GraphDrawable gdraw = (GraphDrawable)drawable; + Graph graph = gdraw.getGraph(); + String algo = gdraw.getAlgorithm(); + JFileChooser chooser = new JFileChooser(); + chooser.addChoosableFileFilter(new DotImageFilter()); + chooser.setAcceptAllFileFilterUsed(false); + chooser.setFileView(new DotImageFileView()); + int returnval = chooser.showSaveDialog(JViewer.this); + if (returnval == JFileChooser.APPROVE_OPTION) { + try { + File file = chooser.getSelectedFile(); + + String type = getExtension(file); + if (type == null) + return; + Graphs.createImage(graph, algo, type, file); + } catch (IOException err) { + err.printStackTrace(); + JOptionPane.showMessageDialog(JViewer.this, "File saving failed: " + err.getMessage(), "Error",JOptionPane.ERROR_MESSAGE); + } + } + } + } + + public static String getExtension(File file) { + String filename = file.getName(); + int index = filename.lastIndexOf("."); + if (index < 0) + return null; + return filename.substring(index+1).toLowerCase(); + } + + public class DotImageFilter extends FileFilter { + @Override + public boolean accept(File f) { + if (f.isDirectory()) + return true; + String ext = getExtension(f); + if (ext == null) + return false; + if (ext.equals("svg")) + return true; + if (ext.equals("dot")) + return true; + if (ext.equals("eps")) + return true; + if (ext.equals("jpg")) + return true; + if (ext.equals("jpeg")) + return true; + if (ext.equals("pdf")) + return true; + if (ext.equals("png")) + return true; + if (ext.equals("ps")) + return true; + return false; + } + + @Override + public String getDescription() { + return "Image files"; + } + } + + public class DotImageFileView extends FileView { + @Override + public String getTypeDescription(File f) { + String ext = getExtension(f); + if (ext == null) + return null; + if (ext.equals("svg")) + return "Scalable Vector Graphics Image"; + if (ext.equals("dot")) + return "DOT Image"; + if (ext.equals("eps")) + return "Encapsulated PostScript Image"; + if (ext.equals("jpg")) + return "JPG Image"; + if (ext.equals("jpeg")) + return "JPG Image"; + if (ext.equals("pdf")) + return "Portable Document Format Image"; + if (ext.equals("png")) + return "Portable Network Graphics Image"; + if (ext.equals("ps")) + return "PostScript Image"; + return null; + } + } + +}