| /* |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| */ |
| package org.apache.batik.swing.gvt; |
| |
| import java.awt.Shape; |
| import java.awt.geom.AffineTransform; |
| import java.util.Collections; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import org.apache.batik.bridge.InterruptedBridgeException; |
| import org.apache.batik.gvt.renderer.ImageRenderer; |
| import org.apache.batik.util.EventDispatcher; |
| import org.apache.batik.util.EventDispatcher.Dispatcher; |
| import org.apache.batik.util.HaltingThread; |
| |
| /** |
| * This class represents an object which renders asynchronously |
| * a GVT tree. |
| * |
| * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a> |
| * @version $Id$ |
| */ |
| public class GVTTreeRenderer extends HaltingThread { |
| |
| /** |
| * The renderer used to paint. |
| */ |
| protected ImageRenderer renderer; |
| |
| /** |
| * The area of interest. |
| */ |
| protected Shape areaOfInterest; |
| |
| /** |
| * The buffer width. |
| */ |
| protected int width; |
| |
| /** |
| * The buffer height. |
| */ |
| protected int height; |
| |
| /** |
| * The user to device transform. |
| */ |
| protected AffineTransform user2DeviceTransform; |
| |
| /** |
| * Whether to enable the double buffering. |
| */ |
| protected boolean doubleBuffering; |
| |
| /** |
| * The listeners. |
| */ |
| protected List listeners = Collections.synchronizedList(new LinkedList()); |
| |
| /** |
| * Creates a new GVTTreeRenderer. |
| * @param r The renderer to use to paint. |
| * @param usr2dev The user to device transform. |
| * @param dbuffer Whether the double buffering should be enabled. |
| * @param aoi The area of interest in the renderer space units. |
| * @param width The offscreen buffer width. |
| * @param height The offscreen buffer height. |
| */ |
| public GVTTreeRenderer(ImageRenderer r, AffineTransform usr2dev, |
| boolean dbuffer, |
| Shape aoi, int width, int height) { |
| renderer = r; |
| areaOfInterest = aoi; |
| user2DeviceTransform = usr2dev; |
| doubleBuffering = dbuffer; |
| this.width = width; |
| this.height = height; |
| } |
| |
| /** |
| * Runs this renderer. |
| */ |
| public void run() { |
| GVTTreeRendererEvent ev = new GVTTreeRendererEvent(this, null); |
| try { |
| fireEvent(prepareDispatcher, ev); |
| |
| renderer.setTransform(user2DeviceTransform); |
| renderer.setDoubleBuffered(doubleBuffering); |
| renderer.updateOffScreen(width, height); |
| renderer.clearOffScreen(); |
| |
| if (isHalted()) { |
| fireEvent(cancelledDispatcher, ev); |
| return; |
| } |
| |
| ev = new GVTTreeRendererEvent(this, renderer.getOffScreen()); |
| fireEvent(startedDispatcher, ev); |
| |
| if (isHalted()) { |
| fireEvent(cancelledDispatcher, ev); |
| return; |
| } |
| |
| renderer.repaint(areaOfInterest); |
| |
| if (isHalted()) { |
| fireEvent(cancelledDispatcher, ev); |
| return; |
| } |
| |
| ev = new GVTTreeRendererEvent(this, renderer.getOffScreen()); |
| fireEvent(completedDispatcher, ev); |
| } catch (NoClassDefFoundError e) { |
| // This error was reported to happen when the rendering |
| // is interrupted with JDK1.3.0rc1 Solaris. |
| } catch (InterruptedBridgeException e) { |
| // this sometimes happens with SVG Fonts since the glyphs are |
| // not built till the rendering stage |
| fireEvent(cancelledDispatcher, ev); |
| } catch (ThreadDeath td) { |
| fireEvent(failedDispatcher, ev); |
| throw td; |
| } catch (Throwable t) { |
| t.printStackTrace(); |
| fireEvent(failedDispatcher, ev); |
| } |
| } |
| |
| public void fireEvent(Dispatcher dispatcher, Object event) { |
| EventDispatcher.fireEvent(dispatcher, listeners, event, true); |
| } |
| |
| /** |
| * Adds a GVTTreeRendererListener to this GVTTreeRenderer. |
| */ |
| public void addGVTTreeRendererListener(GVTTreeRendererListener l) { |
| listeners.add(l); |
| } |
| |
| /** |
| * Removes a GVTTreeRendererListener from this GVTTreeRenderer. |
| */ |
| public void removeGVTTreeRendererListener(GVTTreeRendererListener l) { |
| listeners.remove(l); |
| } |
| |
| static Dispatcher prepareDispatcher = new Dispatcher() { |
| public void dispatch(Object listener, |
| Object event) { |
| ((GVTTreeRendererListener)listener).gvtRenderingPrepare |
| ((GVTTreeRendererEvent)event); |
| } |
| }; |
| |
| static Dispatcher startedDispatcher = new Dispatcher() { |
| public void dispatch(Object listener, |
| Object event) { |
| ((GVTTreeRendererListener)listener).gvtRenderingStarted |
| ((GVTTreeRendererEvent)event); |
| } |
| }; |
| |
| static Dispatcher cancelledDispatcher = new Dispatcher() { |
| public void dispatch(Object listener, |
| Object event) { |
| ((GVTTreeRendererListener)listener).gvtRenderingCancelled |
| ((GVTTreeRendererEvent)event); |
| } |
| }; |
| |
| static Dispatcher completedDispatcher = new Dispatcher() { |
| public void dispatch(Object listener, |
| Object event) { |
| ((GVTTreeRendererListener)listener).gvtRenderingCompleted |
| ((GVTTreeRendererEvent)event); |
| } |
| }; |
| |
| static Dispatcher failedDispatcher = new Dispatcher() { |
| public void dispatch(Object listener, |
| Object event) { |
| ((GVTTreeRendererListener)listener).gvtRenderingFailed |
| ((GVTTreeRendererEvent)event); |
| } |
| }; |
| |
| |
| } |