Source for org.jfree.util.WaitingImageObserver

   1: /* ========================================================================
   2:  * JCommon : a free general purpose class library for the Java(tm) platform
   3:  * ========================================================================
   4:  *
   5:  * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
   6:  * 
   7:  * Project Info:  http://www.jfree.org/jcommon/index.html
   8:  *
   9:  * This library is free software; you can redistribute it and/or modify it 
  10:  * under the terms of the GNU Lesser General Public License as published by 
  11:  * the Free Software Foundation; either version 2.1 of the License, or 
  12:  * (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but 
  15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  16:  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
  17:  * License for more details.
  18:  *
  19:  * You should have received a copy of the GNU Lesser General Public
  20:  * License along with this library; if not, write to the Free Software
  21:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
  22:  * USA.  
  23:  *
  24:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
  25:  * in the United States and other countries.]
  26:  * 
  27:  * -------------------------
  28:  * WaitingImageObserver.java
  29:  * -------------------------
  30:  * (C)opyright 2000-2004, by Thomas Morgner and Contributors.
  31:  *
  32:  * Original Author:  Thomas Morgner
  33:  * Contributor(s):   Stefan Prange;
  34:  *
  35:  * $Id: WaitingImageObserver.java,v 1.6 2006/06/28 17:15:14 taqua Exp $
  36:  *
  37:  * Changes (from 8-Feb-2002)
  38:  * -------------------------
  39:  * 15-Apr-2002 : first version used by ImageElement.
  40:  * 16-May-2002 : Line delimiters adjusted
  41:  * 04-Jun-2002 : Documentation and added a NullPointerCheck for the constructor.
  42:  * 14-Jul-2002 : BugFixed: WaitingImageObserver dead-locked (bugfix by Stefan 
  43:  *               Prange)
  44:  * 18-Mar-2003 : Updated header and made minor Javadoc changes (DG);
  45:  * 21-Sep-2003 : Moved from JFreeReport.
  46:  */
  47: 
  48: package org.jfree.util;
  49: 
  50: import java.awt.Graphics;
  51: import java.awt.Image;
  52: import java.awt.image.BufferedImage;
  53: import java.awt.image.ImageObserver;
  54: import java.io.Serializable;
  55: 
  56: /**
  57:  * This image observer blocks until the image is completely loaded. AWT
  58:  * defers the loading of images until they are painted on a graphic.
  59:  *
  60:  * While printing reports it is not very nice, not to know whether a image
  61:  * was completely loaded, so this observer forces the loading of the image
  62:  * until a final state (either ALLBITS, ABORT or ERROR) is reached.
  63:  *
  64:  * @author Thomas Morgner
  65:  */
  66: public class WaitingImageObserver implements ImageObserver, Serializable, 
  67:                                              Cloneable
  68: {
  69:   /** For serialization. */
  70:   static final long serialVersionUID = -807204410581383550L;
  71:     
  72:   /** The lock. */
  73:   private boolean lock;
  74: 
  75:   /** The image. */
  76:   private Image image;
  77: 
  78:   /** A flag that signals an error. */
  79:   private boolean error;
  80: 
  81:   /**
  82:    * Creates a new <code>ImageObserver<code> for the given <code>Image<code>. 
  83:    * The observer has to be started by an external thread.
  84:    *
  85:    * @param image  the image to observe (<code>null</code> not permitted).
  86:    */
  87:   public WaitingImageObserver(final Image image) {
  88:     if (image == null) {
  89:       throw new NullPointerException();
  90:     }
  91:     this.image = image;
  92:     this.lock = true;
  93:   }
  94: 
  95:   /**
  96:    * Callback function used by AWT to inform that more data is available. The 
  97:    * observer waits until either all data is loaded or AWT signals that the 
  98:    * image cannot be loaded.
  99:    *
 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:   public boolean isLoadingComplete() {
 185:     return this.lock == false;
 186:   }
 187: 
 188:   /**
 189:    * Returns true if there is an error condition, and false otherwise.
 190:    *
 191:    * @return A boolean.
 192:    */
 193:   public boolean isError() {
 194:     return this.error;
 195:   }
 196: }