An image does not magically appear, fully formed, the first time
you call getImage()
. It takes a finite amount of time
for the image to be read. The larger the image the longer it takes.
If the image is loaded from the Internet instead of a local file,
it can take even longer.
Instead of waiting for the image to finish loading
getImage()
returns immediately, possibly before it's even
connected to the remote site. It does return an Image
object, but that Image
object may not initially
contain any data. All the different methods in the AWT that use
images understand this and behave accordingly. For example, if only
the top half of an image is available when drawImage()
is called, then only the top half is drawn.
Meanwhile, in the background, in a separate thread, an
ImageProducer object, that is a instance of a class which
implements java.awt.ImageProducer
, is filling the
image with pixels as fast as it can. When more pixels become
available, at least a scanline's worth, the
ImageProducer
notifies all ImageObserver
objects that have registered an interest in this image.
How does an ImageObserver
register its interest in
an image? By being passed to a method that does something with the
image. For example recall that both drawImage()
,
getWidth()
, and getHeight()
take
ImageObserver
s as arguments.
java.awt.Component
implements the
ImageObserver
interface so all its subclasses do too. This
means buttons, TextAreas, check boxes, panels, applets, and more
can all be used as ImageObserver
s. However in general
you'll use the component that's actually trying to draw the
image.
The ImageObserver
interface declares a single
method, imageUpdate()
:
public abstract boolean imageUpdate(Image img, int infoflags,
int x, int y, int width, int height)
An ImageProducer
uses this method to tell the
ImageObserver
that more data is available for the image, so
it should be redrawn.