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)
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
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
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
;
51 * Supports asynchronous loading of images.
53 public class AsyncImage
58 * The image source for AsyncImages.
60 private class AsyncImageSource
61 implements ImageProducer
64 * The real image source, if already present, or <code>null</code>
67 private ImageProducer realSource
;
69 public void addConsumer(ImageConsumer ic
)
74 public boolean isConsumer(ImageConsumer ic
)
79 public void removeConsumer(ImageConsumer ic
)
81 // Nothing to do here.
84 public void requestTopDownLeftRightResend(ImageConsumer ic
)
89 public void startProduction(ImageConsumer ic
)
91 ImageProducer ip
= getRealSource();
94 ic
.setDimensions(1, 1);
95 ic
.imageComplete(ImageConsumer
.SINGLEFRAMEDONE
);
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
;
116 Image ri
= realImage
;
119 realSource
= source
= ri
.getSource();
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.
146 observers
= new HashSet
<ImageObserver
>();
151 // Nothing to do here.
154 public Graphics
getGraphics()
159 g
= r
.getGraphics(); // Should we return some dummy graphics instead?
163 public boolean isComplete() {
167 public int getHeight(ImageObserver observer
)
169 addObserver(observer
);
171 waitForImage(observer
);
174 height
= r
.getHeight(observer
);
178 public Object
getProperty(String name
, ImageObserver observer
)
180 addObserver(observer
);
184 prop
= r
.getProperty(name
, observer
);
188 public ImageProducer
getSource()
190 return new AsyncImageSource();
193 public int getWidth(ImageObserver observer
)
195 addObserver(observer
);
197 waitForImage(observer
);
200 width
= r
.getWidth(observer
);
204 public void addObserver(ImageObserver obs
)
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
;
221 public boolean prepareImage(int w
, int h
, ImageObserver obs
)
224 return realImage
!= null;
227 public int checkImage(int w
, int h
, ImageObserver obs
)
231 if (realImage
!= null)
232 flags
= ImageObserver
.ALLBITS
| ImageObserver
.WIDTH
233 | ImageObserver
.HEIGHT
| ImageObserver
.PROPERTIES
;
237 public Image
getRealImage()
242 public void setRealImage(Image 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
)
253 HashSet observs
= observers
;
256 Iterator i
= observs
.iterator();
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.
265 if ((status
& ImageObserver
.ALLBITS
) != 0)
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)
292 catch (InterruptedException ex
)
294 Thread
.currentThread().interrupt();