-->
Bookmark and Share

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.

See the example sound loading applet in action in the demo or view the source code.

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.