Sound and Image Loading
Starting an Image Download
To start the download within an applet, use the prepareImage()
method. This method is part of the Component
class from which
applets are derived. It might be called in the applet initialization code, for
example, to start file download as soon as possible.
Image myImage; // ... public void init() { try { myImage = getImage(new URL(getCodeBase(), "image.jpg")); prepareImage(myImage, this); } catch (Exception e) {} }
The argument this
defines the applet itself as the
observer.
Checking the Status of an Image Download
The checkImage()
method can be used to check the status of the
image download. It returns an integer with various bit flags set to indicate
what information or data is currently available. The ImageObserver
interface defines some constants for use in testing each flag. By performing a
bitwise AND between the value returned and these constants you can determine
whether a particular flag is set or not.
The flag defined by the constant ImageObserver.ALLBITS
is set
when all of the image data has been received, meaning the entire image can be
drawn. For example, the following can be placed in the applet
paint()
routine to display the image only after it has finished
downloading.
if ((checkImage(myImage, this) & ImageObserver.ALLBITS) != 0) g.drawImage(myImage, 0, 0, this); else g.drawString("Loading image...", 10, 15);
Again, this
refers to the applet, which is the observer while
g
is the graphics context.
These methods are sufficient if you're only concerned with knowing when an image file has been completely downloaded from the server. Unlike sound clips however, you can go a step further and actually track the progress of an image download as the data is received.
Tracking the Progress of an Image Download
As mentioned, there are several flags defined in the
ImageObserver
interface relating to information about the image.
Whenever a method that takes an ImageObserver
argument is called,
such as checkImage(),
the ImageObserver.updateImage()
method is triggered.
By overriding this method, you can test for these flags and retrieve data such as the dimensions of the image and how much of it has been received. The example applet demonstrates this, downloading a single image and showing its progress before finally displaying the full image.
In the initialization code, prepareImage()
is used to start the
download. In updateImage(),
the image's width and height, and the
amount of data received so far is saved in some global variables.
Within the applet paint()
routine, checkImage()
is used determine if the image should be displayed or not. If not fully loaded,
the applet instead uses that image information to display a text message
showing the progress as a percentage.
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { // If the image has finished loading, update the display. if ((infoflags & ImageObserver.ALLBITS) != 0) { repaint(); return false; } // Otherwise, save information and update the display. if ((infoflags & ImageObserver.WIDTH) != 0) fullWidth = width; if ((infoflags & ImageObserver.HEIGHT) != 0) fullHeight = height; if ((infoflags & ImageObserver.SOMEBITS) != 0) { loadedWidth = Math.abs(width - x); loadedHeight = Math.abs(height - y); } repaint(); return true; }
Note the calls to repaint()
which forces the display to be
updated. This creates a loop between the call to checkImage()
in
the paint()
routine and updateImage().
The method should coded return either true
or
false
depending on whether or not the observer needs more
information. In this case, if the image is still loading, true
is
returned so that further requests against the image will trigger
updateImage()
again. Once false
is returned,
updateImage()
will no longer be triggered for that particular
image.