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)); + } } } } }