KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > apps > svgbrowser > ThumbnailDialog


1 /*
2
3    Copyright 2001,2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.apps.svgbrowser;
19
20 import java.awt.BasicStroke JavaDoc;
21 import java.awt.BorderLayout JavaDoc;
22 import java.awt.Color JavaDoc;
23 import java.awt.Dimension JavaDoc;
24 import java.awt.Frame JavaDoc;
25 import java.awt.Graphics JavaDoc;
26 import java.awt.Graphics2D JavaDoc;
27 import java.awt.Shape JavaDoc;
28 import java.awt.event.ComponentAdapter JavaDoc;
29 import java.awt.event.ComponentEvent JavaDoc;
30 import java.awt.event.MouseEvent JavaDoc;
31 import java.awt.event.WindowAdapter JavaDoc;
32 import java.awt.event.WindowEvent JavaDoc;
33 import java.awt.geom.AffineTransform JavaDoc;
34 import java.awt.geom.Dimension2D JavaDoc;
35 import java.awt.geom.NoninvertibleTransformException JavaDoc;
36 import java.awt.geom.Point2D JavaDoc;
37 import java.awt.geom.Rectangle2D JavaDoc;
38 import java.util.List JavaDoc;
39 import java.util.Locale JavaDoc;
40 import java.util.ResourceBundle JavaDoc;
41
42 import javax.swing.JDialog JavaDoc;
43 import javax.swing.event.MouseInputAdapter JavaDoc;
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 /**
62  * This class represents a Dialog that displays a Thumbnail of the current SVG
63  * document.
64  *
65  * @author <a HREF="mailto:tkormann@apache.org">Thierry Kormann</a>
66  * @version $Id: ThumbnailDialog.java,v 1.15 2005/03/27 08:58:30 cam Exp $
67  */

68 public class ThumbnailDialog extends JDialog JavaDoc {
69
70     /**
71      * The resource file name
72      */

73     protected final static String JavaDoc RESOURCES =
74         "org.apache.batik.apps.svgbrowser.resources.ThumbnailDialog";
75
76     /**
77      * The resource bundle
78      */

79     protected static ResourceBundle JavaDoc bundle;
80
81     /**
82      * The resource manager
83      */

84     protected static ResourceManager resources;
85
86     static {
87         bundle = ResourceBundle.getBundle(RESOURCES, Locale.getDefault());
88         resources = new ResourceManager(bundle);
89     }
90
91     /** The canvas that owns the SVG document to display. */
92     protected JSVGCanvas svgCanvas;
93
94     /** The canvas that displays the thumbnail. */
95     protected JGVTComponent svgThumbnailCanvas;
96
97     /** A flag bit that indicates a document has been loaded. */
98     protected boolean documentChanged;
99
100     /** The overlay used to display the area of interest. */
101     protected AreaOfInterestOverlay overlay;
102
103     /** The overlay used to display the area of interest. */
104     protected AreaOfInterestListener aoiListener;
105
106     protected boolean interactionEnabled = true;
107
108     /**
109      * Constructs a new <tt>ThumbnailDialog</tt> for the specified canvas.
110      *
111      * @param owner the owner frame
112      * @param svgCanvas the canvas that owns the SVG document to display
113      */

114     public ThumbnailDialog(Frame JavaDoc owner, JSVGCanvas svgCanvas) {
115         super(owner, resources.getString("Dialog.title"));
116
117         addWindowListener(new ThumbnailListener());
118
119         // register listeners to maintain consistency
120
this.svgCanvas = svgCanvas;
121         svgCanvas.addGVTTreeRendererListener(new ThumbnailGVTListener());
122         svgCanvas.addSVGDocumentLoaderListener(new ThumbnailDocumentListener());
123         svgCanvas.addComponentListener(new ThumbnailCanvasComponentListener());
124
125         // create the thumbnail
126
svgThumbnailCanvas = new JGVTComponent();
127         overlay = new AreaOfInterestOverlay();
128         svgThumbnailCanvas.getOverlays().add(overlay);
129         svgThumbnailCanvas.setPreferredSize(new Dimension JavaDoc(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     /**
154      * Updates the thumbnail component.
155      */

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 JavaDoc 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     /**
175      * Updates the thumbnail component rendering transform.
176      */

177     protected void updateThumbnailRenderingTransform() {
178         SVGDocument svgDocument = svgCanvas.getSVGDocument();
179         if (svgDocument != null) {
180             SVGSVGElement elt = svgDocument.getRootElement();
181             Dimension JavaDoc dim = svgThumbnailCanvas.getSize();
182
183             String JavaDoc viewBox = elt.getAttributeNS
184                 (null, SVGConstants.SVG_VIEW_BOX_ATTRIBUTE);
185
186             AffineTransform JavaDoc Tx;
187             if (viewBox.length() != 0) {
188                 String JavaDoc 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                 // no viewBox has been specified, create a scale transform
194
Dimension2D JavaDoc 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 JavaDoc vTx = cgn.getViewingTransform();
205                 if ((vTx != null) && !vTx.isIdentity()) {
206                     try {
207                         AffineTransform JavaDoc invVTx = vTx.createInverse();
208                         Tx.concatenate(invVTx);
209                     } catch (NoninvertibleTransformException JavaDoc nite) {
210                         /* nothing */
211                     }
212                 }
213             }
214
215             svgThumbnailCanvas.setRenderingTransform(Tx);
216             overlay.synchronizeAreaOfInterest();
217         }
218     }
219
220     /**
221      * Used to determine whether or not the GVT tree of the thumbnail has to be
222      * updated.
223      */

224     protected class ThumbnailDocumentListener extends SVGDocumentLoaderAdapter {
225
226         public void documentLoadingStarted(SVGDocumentLoaderEvent e) {
227             documentChanged = true;
228         }
229     }
230
231     /**
232      * Used to perform a translation using the area of interest.
233      */

234     protected class AreaOfInterestListener extends MouseInputAdapter JavaDoc {
235
236         protected int sx, sy;
237         protected boolean in;
238
239         public void mousePressed(MouseEvent JavaDoc evt) {
240             sx = evt.getX();
241             sy = evt.getY();
242             in = overlay.contains(sx, sy);
243             overlay.setPaintingTransform(new AffineTransform JavaDoc());
244         }
245
246         public void mouseDragged(MouseEvent JavaDoc 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 JavaDoc evt) {
257             if (in) {
258                 in = false;
259
260                 int dx = evt.getX() - sx;
261                 int dy = evt.getY() - sy;
262                 AffineTransform JavaDoc at = overlay.getOverlayTransform();
263                 Point2D JavaDoc pt0 = new Point2D.Float JavaDoc(0, 0);
264                 Point2D JavaDoc pt = new Point2D.Float JavaDoc(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 JavaDoc ex) { }
276             }
277         }
278     }
279
280     /**
281      * Used to update the overlay and/or the GVT tree of the thumbnail.
282      */

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 JavaDoc());
299         }
300         }
301
302         public void gvtRenderingFailed(GVTTreeRendererEvent e) {
303         if (documentChanged) {
304         svgThumbnailCanvas.setGraphicsNode(null);
305         svgThumbnailCanvas.setRenderingTransform(new AffineTransform JavaDoc());
306         }
307     }
308     }
309
310     /**
311      * Used the first time the thumbnail dialog is shown to make visible the
312      * current GVT tree being displayed by the original SVG component.
313      */

314     protected class ThumbnailListener extends WindowAdapter JavaDoc {
315
316         public void windowOpened(WindowEvent JavaDoc evt) {
317             updateThumbnailGraphicsNode();
318         }
319     }
320
321     /**
322      * Used to allow the SVG document being displayed by the thumbnail to be
323      * resized properly.
324      */

325     protected class ThumbnailComponentListener extends ComponentAdapter JavaDoc {
326
327         public void componentResized(ComponentEvent JavaDoc e) {
328             updateThumbnailRenderingTransform();
329         }
330     }
331
332     /**
333      * Used to allow the SVG document being displayed by the thumbnail to be
334      * resized properly when parent resizes.
335      */

336     protected class ThumbnailCanvasComponentListener extends ComponentAdapter JavaDoc {
337
338         public void componentResized(ComponentEvent JavaDoc e) {
339             updateThumbnailRenderingTransform();
340         }
341     }
342
343     /**
344      * An overlay that represents the current area of interest.
345      */

346     protected class AreaOfInterestOverlay implements Overlay {
347
348         protected Shape JavaDoc s;
349         protected AffineTransform JavaDoc at;
350         protected AffineTransform JavaDoc paintingTransform = new AffineTransform JavaDoc();
351
352         public boolean contains(int x, int y) {
353             return (s != null) ? s.contains(x, y) : false;
354         }
355
356         public AffineTransform JavaDoc getOverlayTransform() {
357             return at;
358         }
359
360         public void setPaintingTransform(AffineTransform JavaDoc rt) {
361             this.paintingTransform = rt;
362         }
363
364         public AffineTransform JavaDoc getPaintingTransform() {
365             return paintingTransform;
366         }
367
368         public void synchronizeAreaOfInterest() {
369             paintingTransform = new AffineTransform JavaDoc();
370             Dimension JavaDoc dim = svgCanvas.getSize();
371             s = new Rectangle2D.Float JavaDoc(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 JavaDoc ex) {
377                 dim = svgThumbnailCanvas.getSize();
378                 s = new Rectangle2D.Float JavaDoc(0, 0, dim.width, dim.height);
379             }
380         }
381
382         public void paint(Graphics JavaDoc g) {
383             if (s != null) {
384                 Graphics2D JavaDoc g2d = (Graphics2D JavaDoc)g;
385                 g2d.transform(paintingTransform);
386                 g2d.setColor(new Color JavaDoc(255, 255, 255, 128));
387                 g2d.fill(s);
388                 g2d.setColor(Color.black);
389                 g2d.setStroke(new BasicStroke JavaDoc());
390                 g2d.draw(s);
391             }
392         }
393     }
394 }
395
Popular Tags