1 18 package org.apache.batik.apps.svgbrowser; 19 20 import java.awt.BasicStroke ; 21 import java.awt.BorderLayout ; 22 import java.awt.Color ; 23 import java.awt.Dimension ; 24 import java.awt.Frame ; 25 import java.awt.Graphics ; 26 import java.awt.Graphics2D ; 27 import java.awt.Shape ; 28 import java.awt.event.ComponentAdapter ; 29 import java.awt.event.ComponentEvent ; 30 import java.awt.event.MouseEvent ; 31 import java.awt.event.WindowAdapter ; 32 import java.awt.event.WindowEvent ; 33 import java.awt.geom.AffineTransform ; 34 import java.awt.geom.Dimension2D ; 35 import java.awt.geom.NoninvertibleTransformException ; 36 import java.awt.geom.Point2D ; 37 import java.awt.geom.Rectangle2D ; 38 import java.util.List ; 39 import java.util.Locale ; 40 import java.util.ResourceBundle ; 41 42 import javax.swing.JDialog ; 43 import javax.swing.event.MouseInputAdapter ; 44 45 import org.apache.batik.bridge.ViewBox; 46 import org.apache.batik.gvt.CanvasGraphicsNode; 47 import org.apache.batik.gvt.CompositeGraphicsNode; 48 import org.apache.batik.gvt.GraphicsNode; 49 import org.apache.batik.swing.JSVGCanvas; 50 import org.apache.batik.swing.gvt.GVTTreeRendererAdapter; 51 import org.apache.batik.swing.gvt.GVTTreeRendererEvent; 52 import org.apache.batik.swing.gvt.JGVTComponent; 53 import org.apache.batik.swing.gvt.Overlay; 54 import org.apache.batik.swing.svg.SVGDocumentLoaderAdapter; 55 import org.apache.batik.swing.svg.SVGDocumentLoaderEvent; 56 import org.apache.batik.util.gui.resource.ResourceManager; 57 import org.apache.batik.util.SVGConstants; 58 import org.w3c.dom.svg.SVGDocument; 59 import org.w3c.dom.svg.SVGSVGElement; 60 61 68 public class ThumbnailDialog extends JDialog { 69 70 73 protected final static String RESOURCES = 74 "org.apache.batik.apps.svgbrowser.resources.ThumbnailDialog"; 75 76 79 protected static ResourceBundle bundle; 80 81 84 protected static ResourceManager resources; 85 86 static { 87 bundle = ResourceBundle.getBundle(RESOURCES, Locale.getDefault()); 88 resources = new ResourceManager(bundle); 89 } 90 91 92 protected JSVGCanvas svgCanvas; 93 94 95 protected JGVTComponent svgThumbnailCanvas; 96 97 98 protected boolean documentChanged; 99 100 101 protected AreaOfInterestOverlay overlay; 102 103 104 protected AreaOfInterestListener aoiListener; 105 106 protected boolean interactionEnabled = true; 107 108 114 public ThumbnailDialog(Frame owner, JSVGCanvas svgCanvas) { 115 super(owner, resources.getString("Dialog.title")); 116 117 addWindowListener(new ThumbnailListener()); 118 119 this.svgCanvas = svgCanvas; 121 svgCanvas.addGVTTreeRendererListener(new ThumbnailGVTListener()); 122 svgCanvas.addSVGDocumentLoaderListener(new ThumbnailDocumentListener()); 123 svgCanvas.addComponentListener(new ThumbnailCanvasComponentListener()); 124 125 svgThumbnailCanvas = new JGVTComponent(); 127 overlay = new AreaOfInterestOverlay(); 128 svgThumbnailCanvas.getOverlays().add(overlay); 129 svgThumbnailCanvas.setPreferredSize(new Dimension (150, 150)); 130 svgThumbnailCanvas.addComponentListener(new ThumbnailComponentListener()); 131 aoiListener = new AreaOfInterestListener(); 132 svgThumbnailCanvas.addMouseListener(aoiListener); 133 svgThumbnailCanvas.addMouseMotionListener(aoiListener); 134 getContentPane().add(svgThumbnailCanvas, BorderLayout.CENTER); 135 } 136 137 public void setInteractionEnabled(boolean b) { 138 if (b == interactionEnabled) return; 139 interactionEnabled = b; 140 if (b) { 141 svgThumbnailCanvas.addMouseListener (aoiListener); 142 svgThumbnailCanvas.addMouseMotionListener(aoiListener); 143 } else { 144 svgThumbnailCanvas.removeMouseListener (aoiListener); 145 svgThumbnailCanvas.removeMouseMotionListener(aoiListener); 146 } 147 } 148 149 public boolean getInteractionEnabled() { 150 return interactionEnabled; 151 } 152 153 156 protected void updateThumbnailGraphicsNode() { 157 svgThumbnailCanvas.setGraphicsNode(svgCanvas.getGraphicsNode()); 158 updateThumbnailRenderingTransform(); 159 } 160 161 protected CanvasGraphicsNode getCanvasGraphicsNode(GraphicsNode gn) { 162 if (!(gn instanceof CompositeGraphicsNode)) 163 return null; 164 CompositeGraphicsNode cgn = (CompositeGraphicsNode)gn; 165 List children = cgn.getChildren(); 166 if (children.size() == 0) 167 return null; 168 gn = (GraphicsNode)cgn.getChildren().get(0); 169 if (!(gn instanceof CanvasGraphicsNode)) 170 return null; 171 return (CanvasGraphicsNode)gn; 172 } 173 174 177 protected void updateThumbnailRenderingTransform() { 178 SVGDocument svgDocument = svgCanvas.getSVGDocument(); 179 if (svgDocument != null) { 180 SVGSVGElement elt = svgDocument.getRootElement(); 181 Dimension dim = svgThumbnailCanvas.getSize(); 182 183 String viewBox = elt.getAttributeNS 184 (null, SVGConstants.SVG_VIEW_BOX_ATTRIBUTE); 185 186 AffineTransform Tx; 187 if (viewBox.length() != 0) { 188 String aspectRatio = elt.getAttributeNS 189 (null, SVGConstants.SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE); 190 Tx = ViewBox.getPreserveAspectRatioTransform 191 (elt, viewBox, aspectRatio, dim.width, dim.height); 192 }else { 193 Dimension2D docSize = svgCanvas.getSVGDocumentSize(); 195 double sx = dim.width / docSize.getWidth(); 196 double sy = dim.height / docSize.getHeight(); 197 double s = Math.min(sx, sy); 198 Tx = AffineTransform.getScaleInstance(s, s); 199 } 200 201 GraphicsNode gn = svgCanvas.getGraphicsNode(); 202 CanvasGraphicsNode cgn = getCanvasGraphicsNode(gn); 203 if (cgn != null) { 204 AffineTransform vTx = cgn.getViewingTransform(); 205 if ((vTx != null) && !vTx.isIdentity()) { 206 try { 207 AffineTransform invVTx = vTx.createInverse(); 208 Tx.concatenate(invVTx); 209 } catch (NoninvertibleTransformException nite) { 210 211 } 212 } 213 } 214 215 svgThumbnailCanvas.setRenderingTransform(Tx); 216 overlay.synchronizeAreaOfInterest(); 217 } 218 } 219 220 224 protected class ThumbnailDocumentListener extends SVGDocumentLoaderAdapter { 225 226 public void documentLoadingStarted(SVGDocumentLoaderEvent e) { 227 documentChanged = true; 228 } 229 } 230 231 234 protected class AreaOfInterestListener extends MouseInputAdapter { 235 236 protected int sx, sy; 237 protected boolean in; 238 239 public void mousePressed(MouseEvent evt) { 240 sx = evt.getX(); 241 sy = evt.getY(); 242 in = overlay.contains(sx, sy); 243 overlay.setPaintingTransform(new AffineTransform ()); 244 } 245 246 public void mouseDragged(MouseEvent evt) { 247 if (in) { 248 int dx = evt.getX() - sx; 249 int dy = evt.getY() - sy; 250 overlay.setPaintingTransform 251 (AffineTransform.getTranslateInstance(dx, dy)); 252 svgThumbnailCanvas.repaint(); 253 } 254 } 255 256 public void mouseReleased(MouseEvent evt) { 257 if (in) { 258 in = false; 259 260 int dx = evt.getX() - sx; 261 int dy = evt.getY() - sy; 262 AffineTransform at = overlay.getOverlayTransform(); 263 Point2D pt0 = new Point2D.Float (0, 0); 264 Point2D pt = new Point2D.Float (dx, dy); 265 266 try { 267 at.inverseTransform(pt0, pt0); 268 at.inverseTransform(pt, pt); 269 double tx = pt0.getX() - pt.getX(); 270 double ty = pt0.getY() - pt.getY(); 271 at = svgCanvas.getRenderingTransform(); 272 at.preConcatenate 273 (AffineTransform.getTranslateInstance(tx, ty)); 274 svgCanvas.setRenderingTransform(at); 275 } catch (NoninvertibleTransformException ex) { } 276 } 277 } 278 } 279 280 283 protected class ThumbnailGVTListener extends GVTTreeRendererAdapter { 284 285 public void gvtRenderingCompleted(GVTTreeRendererEvent e) { 286 if (documentChanged) { 287 updateThumbnailGraphicsNode(); 288 documentChanged = false; 289 } else { 290 overlay.synchronizeAreaOfInterest(); 291 svgThumbnailCanvas.repaint(); 292 } 293 } 294 295 public void gvtRenderingCancelled(GVTTreeRendererEvent e) { 296 if (documentChanged) { 297 svgThumbnailCanvas.setGraphicsNode(null); 298 svgThumbnailCanvas.setRenderingTransform(new AffineTransform ()); 299 } 300 } 301 302 public void gvtRenderingFailed(GVTTreeRendererEvent e) { 303 if (documentChanged) { 304 svgThumbnailCanvas.setGraphicsNode(null); 305 svgThumbnailCanvas.setRenderingTransform(new AffineTransform ()); 306 } 307 } 308 } 309 310 314 protected class ThumbnailListener extends WindowAdapter { 315 316 public void windowOpened(WindowEvent evt) { 317 updateThumbnailGraphicsNode(); 318 } 319 } 320 321 325 protected class ThumbnailComponentListener extends ComponentAdapter { 326 327 public void componentResized(ComponentEvent e) { 328 updateThumbnailRenderingTransform(); 329 } 330 } 331 332 336 protected class ThumbnailCanvasComponentListener extends ComponentAdapter { 337 338 public void componentResized(ComponentEvent e) { 339 updateThumbnailRenderingTransform(); 340 } 341 } 342 343 346 protected class AreaOfInterestOverlay implements Overlay { 347 348 protected Shape s; 349 protected AffineTransform at; 350 protected AffineTransform paintingTransform = new AffineTransform (); 351 352 public boolean contains(int x, int y) { 353 return (s != null) ? s.contains(x, y) : false; 354 } 355 356 public AffineTransform getOverlayTransform() { 357 return at; 358 } 359 360 public void setPaintingTransform(AffineTransform rt) { 361 this.paintingTransform = rt; 362 } 363 364 public AffineTransform getPaintingTransform() { 365 return paintingTransform; 366 } 367 368 public void synchronizeAreaOfInterest() { 369 paintingTransform = new AffineTransform (); 370 Dimension dim = svgCanvas.getSize(); 371 s = new Rectangle2D.Float (0, 0, dim.width, dim.height); 372 try { 373 at = svgCanvas.getRenderingTransform().createInverse(); 374 at.preConcatenate(svgThumbnailCanvas.getRenderingTransform()); 375 s = at.createTransformedShape(s); 376 } catch (NoninvertibleTransformException ex) { 377 dim = svgThumbnailCanvas.getSize(); 378 s = new Rectangle2D.Float (0, 0, dim.width, dim.height); 379 } 380 } 381 382 public void paint(Graphics g) { 383 if (s != null) { 384 Graphics2D g2d = (Graphics2D )g; 385 g2d.transform(paintingTransform); 386 g2d.setColor(new Color (255, 255, 255, 128)); 387 g2d.fill(s); 388 g2d.setColor(Color.black); 389 g2d.setStroke(new BasicStroke ()); 390 g2d.draw(s); 391 } 392 } 393 } 394 } 395 | Popular Tags |