This discards all observers after the image loading is finished. They
are not needed anymore and new observers get pinged directly.
2006-12-05 Roman Kennke <[EMAIL PROTECTED]>
* gnu/java/awt/peer/gtk/AsyncImage.java
(Loader.run): Nullify observers after loading.
(observers): Made package private.
(addObserver): Check for null observers field. Create local
variable for thread safety.
(getHeight): Use addObserver() for checking state of field
and notifying observer when necessary.
(getWidth): Use addObserver() for checking state of field
and notifying observer when necessary.
(getProperty): Use addObserver() for checking state of field
and notifying observer when necessary.
(notifyObservers): Check for null observers field. Create local
variable for thread safety.
/Roman
Index: gnu/java/awt/peer/gtk/AsyncImage.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/AsyncImage.java,v
retrieving revision 1.2
diff -u -1 -5 -r1.2 AsyncImage.java
--- gnu/java/awt/peer/gtk/AsyncImage.java 5 Dec 2006 21:38:33 -0000 1.2
+++ gnu/java/awt/peer/gtk/AsyncImage.java 5 Dec 2006 22:23:26 -0000
@@ -116,154 +116,155 @@
public void run()
{
Image image;
try
{
GtkImage gtkImage = new GtkImage(url);
image = CairoSurface.getBufferedImage(gtkImage);
}
catch (IllegalArgumentException iae)
{
image = null;
}
realImage = GtkToolkit.imageOrError(image);
notifyObservers(ImageObserver.ALLBITS | ImageObserver.HEIGHT
| ImageObserver.WIDTH | ImageObserver.PROPERTIES);
+ observers = null; // Not needed anymore.
}
}
/**
* The real image. This is null as long as the image is not complete.
*/
Image realImage;
- private HashSet observers;
+ /**
+ * The image observers.
+ *
+ * This is package private to avoid accessor methods.
+ */
+ HashSet observers;
/**
* Creates a new AsyncImage that loads from the specified URL.
*/
AsyncImage(URL url)
{
observers = new HashSet();
Loader l = new Loader(url);
Thread t = new Thread(l);
t.start();
}
public void flush()
{
// Nothing to do here.
}
public Graphics getGraphics()
{
Image r = realImage;
Graphics g = null;
if (r != null)
g = r.getGraphics(); // Should we return some dummy graphics instead?
return g;
}
public int getHeight(ImageObserver observer)
{
- if (observer != null)
- {
- synchronized (observers)
- {
- observers.add(observer);
- }
- }
+ addObserver(observer);
int height = 0;
Image r = realImage;
if (r != null)
height = r.getHeight(observer);
return height;
}
public Object getProperty(String name, ImageObserver observer)
{
- if (observer != null)
- {
- synchronized (observers)
- {
- observers.add(observer);
- }
- }
+ addObserver(observer);
Image r = realImage;
Object prop = null;
if (r != null)
prop = r.getProperty(name, observer);
return prop;
}
public ImageProducer getSource()
{
Image r = realImage;
ImageProducer source;
if (r == null)
source = new NullImageSource();
else
source = r.getSource();
return source;
}
public int getWidth(ImageObserver observer)
{
- if (observer != null)
- {
- synchronized (observers)
- {
- observers.add(observer);
- }
- }
+ addObserver(observer);
int width = 0;
Image r = realImage;
if (r != null)
width = r.getWidth(observer);
return width;
}
void addObserver(ImageObserver obs)
{
- if (obs != null)
+ // This field gets null when image loading is complete and we don't
+ // need to store any more observers.
+ HashSet observs = observers;
+ if (observs != null)
{
- if (realImage != null && ! observers.contains(obs))
+ if (obs != null)
{
- obs.imageUpdate(this, ImageObserver.WIDTH | ImageObserver.HEIGHT
- |ImageObserver.ALLBITS | ImageObserver.PROPERTIES,
- 0, 0, realImage.getWidth(null),
- realImage.getHeight(null));
+ synchronized (observs)
+ {
+ observs.add(obs);
+ }
}
- synchronized (observers)
- {
- observers.add(obs);
- }
+ }
+ else
+ {
+ // When the image is complete, notify the observer. Dunno if that's
+ // really needed, but to be sure.
+ obs.imageUpdate(this, ImageObserver.WIDTH | ImageObserver.HEIGHT
+ |ImageObserver.ALLBITS | ImageObserver.PROPERTIES,
+ 0, 0, realImage.getWidth(null),
+ realImage.getHeight(null));
}
}
static Image realImage(Image img, ImageObserver obs)
{
if (img instanceof AsyncImage)
{
((AsyncImage) img).addObserver(obs);
Image r = ((AsyncImage) img).realImage;
if (r != null)
img = r;
}
return img;
}
void notifyObservers(int status)
{
- synchronized (observers)
+ // This field gets null when image loading is complete.
+ HashSet observs = observers;
+ if (observs != null)
{
- Image r = realImage;
- Iterator i = observers.iterator();
- while (i.hasNext())
+ synchronized (observs)
{
- ImageObserver obs = (ImageObserver) i.next();
- obs.imageUpdate(this, status, 0, 0, r.getWidth(null),
- r.getHeight(null));
+ Image r = realImage;
+ Iterator i = observs.iterator();
+ while (i.hasNext())
+ {
+ ImageObserver obs = (ImageObserver) i.next();
+ obs.imageUpdate(this, status, 0, 0, r.getWidth(null),
+ r.getHeight(null));
+ }
}
}
}
}