Merge with trank @ 137446
[official-gcc.git] / libjava / classpath / gnu / java / awt / image / AsyncImage.java
blob935601a8898da260dbe118475b0978045e9c0dea
1 /* AsyncImage.java -- Loads images asynchronously
2 Copyright (C) 2008 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu.java.awt.image;
42 import java.awt.Graphics;
43 import java.awt.Image;
44 import java.awt.image.ImageConsumer;
45 import java.awt.image.ImageObserver;
46 import java.awt.image.ImageProducer;
47 import java.util.HashSet;
48 import java.util.Iterator;
50 /**
51 * Supports asynchronous loading of images.
53 public class AsyncImage
54 extends Image
57 /**
58 * The image source for AsyncImages.
60 private class AsyncImageSource
61 implements ImageProducer
63 /**
64 * The real image source, if already present, or <code>null</code>
65 * otherwise.
67 private ImageProducer realSource;
69 public void addConsumer(ImageConsumer ic)
71 startProduction(ic);
74 public boolean isConsumer(ImageConsumer ic)
76 return false;
79 public void removeConsumer(ImageConsumer ic)
81 // Nothing to do here.
84 public void requestTopDownLeftRightResend(ImageConsumer ic)
86 startProduction(ic);
89 public void startProduction(ImageConsumer ic)
91 ImageProducer ip = getRealSource();
92 if (ip == null)
94 ic.setDimensions(1, 1);
95 ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
97 else
99 ip.startProduction(ic);
104 * Returns the real image source, if already present. Otherwise, this
105 * returns <code>null</code>.
107 * @return the real image source, or <code>null</code> if not present
109 private ImageProducer getRealSource()
111 synchronized (AsyncImage.this)
113 ImageProducer source = realSource;
114 if (source == null)
116 Image ri = realImage;
117 if (ri != null)
119 realSource = source = ri.getSource();
122 return source;
128 * The real image. This is null as long as the image is not complete.
130 private volatile Image realImage;
133 * The image observers.
135 * This is package private to avoid accessor methods.
137 HashSet<ImageObserver> observers;
139 private volatile boolean complete = false;
142 * Creates a new AsyncImage.
144 AsyncImage()
146 observers = new HashSet<ImageObserver>();
149 public void flush()
151 // Nothing to do here.
154 public Graphics getGraphics()
156 Image r = realImage;
157 Graphics g = null;
158 if (r != null)
159 g = r.getGraphics(); // Should we return some dummy graphics instead?
160 return g;
163 public boolean isComplete() {
164 return complete;
167 public int getHeight(ImageObserver observer)
169 addObserver(observer);
170 int height = -1;
171 waitForImage(observer);
172 Image r = realImage;
173 if (r != null)
174 height = r.getHeight(observer);
175 return height;
178 public Object getProperty(String name, ImageObserver observer)
180 addObserver(observer);
181 Image r = realImage;
182 Object prop = null;
183 if (r != null)
184 prop = r.getProperty(name, observer);
185 return prop;
188 public ImageProducer getSource()
190 return new AsyncImageSource();
193 public int getWidth(ImageObserver observer)
195 addObserver(observer);
196 int width = -1;
197 waitForImage(observer);
198 Image r = realImage;
199 if (r != null)
200 width = r.getWidth(observer);
201 return width;
204 public void addObserver(ImageObserver obs)
206 if (obs != null)
208 synchronized (this)
210 // This field gets null when image loading is complete and we don't
211 // need to store any more observers.
212 HashSet<ImageObserver> observs = observers;
213 if (observs != null)
215 observs.add(obs);
221 public boolean prepareImage(int w, int h, ImageObserver obs)
223 addObserver(obs);
224 return realImage != null;
227 public int checkImage(int w, int h, ImageObserver obs)
229 addObserver(obs);
230 int flags = 0;
231 if (realImage != null)
232 flags = ImageObserver.ALLBITS | ImageObserver.WIDTH
233 | ImageObserver.HEIGHT | ImageObserver.PROPERTIES;
234 return flags;
237 public Image getRealImage()
239 return realImage;
242 public void setRealImage(Image im)
244 realImage = im;
245 int status = ImageObserver.HEIGHT | ImageObserver.WIDTH;
246 notifyObservers(status, 0, 0, im.getWidth(null), im.getHeight(null));
249 public void notifyObservers(int status, int x, int y, int w, int h)
251 synchronized (this)
253 HashSet observs = observers;
254 if (observs != null)
256 Iterator i = observs.iterator();
257 while (i.hasNext())
259 ImageObserver obs = (ImageObserver) i.next();
260 boolean complete = obs.imageUpdate(this, status, x, y, realImage.getWidth(obs), realImage.getHeight(obs));
261 if (complete) // Remove completed observers.
262 i.remove();
265 if ((status & ImageObserver.ALLBITS) != 0)
267 complete = true;
268 notifyAll();
274 * Waits for the image to be loaded completely, if the image observer
275 * is <code>null</code>. Otherwise this is not necessary, because the
276 * image observer can be notified about later completion.
278 * @param observer the image observer
280 public void waitForImage(ImageObserver observer)
282 if (!complete && observer == null)
284 synchronized (this)
286 while (! complete)
290 wait();
292 catch (InterruptedException ex)
294 Thread.currentThread().interrupt();