001/* ======================================================================== 002 * JCommon : a free general purpose class library for the Java(tm) platform 003 * ======================================================================== 004 * 005 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jcommon/index.html 008 * 009 * This library is free software; you can redistribute it and/or modify it 010 * under the terms of the GNU Lesser General Public License as published by 011 * the Free Software Foundation; either version 2.1 of the License, or 012 * (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but 015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 017 * License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this library; if not, write to the Free Software 021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 022 * USA. 023 * 024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 025 * in the United States and other countries.] 026 * 027 * ------------------------- 028 * WaitingImageObserver.java 029 * ------------------------- 030 * (C)opyright 2000-2004, by Thomas Morgner and Contributors. 031 * 032 * Original Author: Thomas Morgner 033 * Contributor(s): Stefan Prange; 034 * 035 * $Id: WaitingImageObserver.java,v 1.8 2008/09/10 09:24:41 mungady Exp $ 036 * 037 * Changes (from 8-Feb-2002) 038 * ------------------------- 039 * 15-Apr-2002 : first version used by ImageElement. 040 * 16-May-2002 : Line delimiters adjusted 041 * 04-Jun-2002 : Documentation and added a NullPointerCheck for the constructor. 042 * 14-Jul-2002 : BugFixed: WaitingImageObserver dead-locked (bugfix by Stefan 043 * Prange) 044 * 18-Mar-2003 : Updated header and made minor Javadoc changes (DG); 045 * 21-Sep-2003 : Moved from JFreeReport. 046 */ 047 048package org.jfree.util; 049 050import java.awt.Graphics; 051import java.awt.Image; 052import java.awt.image.BufferedImage; 053import java.awt.image.ImageObserver; 054import java.io.Serializable; 055 056/** 057 * This image observer blocks until the image is completely loaded. AWT 058 * defers the loading of images until they are painted on a graphic. 059 * 060 * While printing reports it is not very nice, not to know whether a image 061 * was completely loaded, so this observer forces the loading of the image 062 * until a final state (either ALLBITS, ABORT or ERROR) is reached. 063 * 064 * @author Thomas Morgner 065 */ 066public class WaitingImageObserver implements ImageObserver, Serializable, 067 Cloneable 068{ 069 /** For serialization. */ 070 static final long serialVersionUID = -807204410581383550L; 071 072 /** The lock. */ 073 private boolean lock; 074 075 /** The image. */ 076 private Image image; 077 078 /** A flag that signals an error. */ 079 private boolean error; 080 081 /** 082 * Creates a new <code>ImageObserver<code> for the given <code>Image<code>. 083 * The observer has to be started by an external thread. 084 * 085 * @param image the image to observe (<code>null</code> not permitted). 086 */ 087 public WaitingImageObserver(final Image image) { 088 if (image == null) { 089 throw new NullPointerException(); 090 } 091 this.image = image; 092 this.lock = true; 093 } 094 095 /** 096 * Callback function used by AWT to inform that more data is available. The 097 * observer waits until either all data is loaded or AWT signals that the 098 * image cannot be loaded. 099 * 100 * @param img the image being observed. 101 * @param infoflags the bitwise inclusive OR of the following 102 * flags: <code>WIDTH</code>, <code>HEIGHT</code>, 103 * <code>PROPERTIES</code>, <code>SOMEBITS</code>, 104 * <code>FRAMEBITS</code>, <code>ALLBITS</code>, 105 * <code>ERROR</code>, <code>ABORT</code>. 106 * @param x the <i>x</i> coordinate. 107 * @param y the <i>y</i> coordinate. 108 * @param width the width. 109 * @param height the height. 110 * 111 * @return <code>false</code> if the infoflags indicate that the 112 * image is completely loaded; <code>true</code> otherwise. 113 */ 114 public synchronized boolean imageUpdate( 115 final Image img, 116 final int infoflags, 117 final int x, 118 final int y, 119 final int width, 120 final int height) { 121 if ((infoflags & ImageObserver.ALLBITS) == ImageObserver.ALLBITS) { 122 this.lock = false; 123 this.error = false; 124 notifyAll(); 125 return false; 126 } 127 else if ((infoflags & ImageObserver.ABORT) == ImageObserver.ABORT 128 || (infoflags & ImageObserver.ERROR) == ImageObserver.ERROR) { 129 this.lock = false; 130 this.error = true; 131 notifyAll(); 132 return false; 133 } 134 //notifyAll(); 135 return true; 136 } 137 138 /** 139 * The workerthread. Simply draws the image to a BufferedImage's 140 * Graphics-Object and waits for the AWT to load the image. 141 */ 142 public synchronized void waitImageLoaded() { 143 144 if (this.lock == false) 145 { 146 return; 147 } 148 149 final BufferedImage img = new BufferedImage( 150 1, 1, BufferedImage.TYPE_INT_RGB 151 ); 152 final Graphics g = img.getGraphics(); 153 154 while (this.lock) { 155 if (g.drawImage(this.image, 0, 0, img.getWidth(this), 156 img.getHeight(this), this)) { 157 return; 158 } 159 160 try { 161 wait(500); 162 } 163 catch (InterruptedException e) { 164 Log.info( 165 "WaitingImageObserver.waitImageLoaded(): InterruptedException thrown", 166 e 167 ); 168 } 169 } 170 } 171 172 /** 173 * Clones this WaitingImageObserver. 174 * 175 * @return a clone. 176 * 177 * @throws CloneNotSupportedException this should never happen. 178 * @deprecated cloning may lock down the observer 179 */ 180 public Object clone() throws CloneNotSupportedException { 181 return (WaitingImageObserver) super.clone(); 182 } 183 184 /** 185 * Returns <code>true</code> if loading is complete, and <code>false</code> 186 * otherwise. 187 * 188 * @return A boolean. 189 */ 190 public boolean isLoadingComplete() { 191 return this.lock == false; 192 } 193 194 /** 195 * Returns true if there is an error condition, and false otherwise. 196 * 197 * @return A boolean. 198 */ 199 public boolean isError() { 200 return this.error; 201 } 202}