Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API

Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

Stepping through an image map applet

Spice up any Web site with this reusable Java code

Many a Web site has considered employing Java within its home page. The image map, a mainstay of home pages consisting of a GIF or JPEG image mapped to link to various documents depending upon where a user clicks within the image, lends itself nicely to Java enhancement. In this inaugural Step by Step column, we'll walk you through the creation of a reusable image map applet.

Overview of the problem

The basic idea: Allow for regions to be defined on an image. When the user moves the mouse into the region, another image is displayed. When the user clicks in the region, the browser is driven to a URL associated with that area. This applet allows for two styles of image placement, either over the region or at the bottom of the background image. The difference is a matter of style. Both work well, and the choice will depend on the desired effect.

One suggestion is to use below-background image placement to provide textual information relating to the link; interesting graphical effects can be achieved with Image overlays. If this applet is designed to be as generic as possible, then it can be written and compiled once, and reused many times with differing effects.

Global elements

The basic elements are a background image, a boolean value specifying the image placement, a Vector of Rectangles representing the defined regions, a Vector of images associated with those regions, and a Vector of URLs to which each region should point. We also must keep the index of the current active region.

import java.awt.*;
import java.applet.*;
import java.util.*;
import java.net.*;
public class ImageMap extends Applet {
  Image background;
  boolean overlay;
  Vector areas = new Vector();
  Vector images = new Vector();
  Vector urls = new Vector();
  int current = -1;


Vectors are used so that any number of regions may be defined. A Vector is a dynamically allocated array that grows as needed. This is more efficient than a large array for most cases.

Initialization and parameter collection

The init() method does all the work of collecting the parameters. This method is called automatically when the applet first loads.

  public void init() {
    // get the parameters
    background = getImage(getDocumentBase(), getParameter("main"));
    prepareImage(background, this);
    overlay = Boolean.valueOf(getParameter("overlay")).booleanValue();
    String bgcolor = getParameter("bgcolor");
    if (bgcolor != null)
      setBackground (new Color (Integer.parseInt (bgcolor.substring (1), 16)));
    boolean ok = true;
    for (int i = 1; ok; ++i) {
      String areaStr = getParameter("area"+i);
      String imageStr = getParameter("image"+i);
      String urlStr = getParameter("url"+i);
      if ((areaStr != null) && (imageStr != null) && (urlStr != null)) {
        try {
          StringTokenizer str = new StringTokenizer(areaStr);
          Rectangle area = new Rectangle(Integer.parseInt(str.nextToken()),
                                         Integer.parseInt(str.nextToken()),
                                         Integer.parseInt(str.nextToken()),
                                         Integer.parseInt(str.nextToken()));
          Image image = getImage(getDocumentBase(), imageStr);
          URL url = new URL(getDocumentBase(), urlStr);
          areas.addElement(area);
          images.addElement(image);
          urls.addElement(url);
          prepareImage (image, this);
        } catch (MalformedURLException ex) {
          System.out.println ("Invalid format for URL " + i + " : " + urlStr);
        } catch (NoSuchElementException ex) {
          System.out.println ("Invalid format for area " + i + " : " + areaStr);
        } // end try
      } else {
        ok = false;
      } // end if
    } // end for
  } // end init


There are several parameters that we need to collect from the HTML APPLET tag. A typical tag will look like this:

&ltapplet code=ImageMap width=461 height=585>
&ltparam name="main" value="jwbackcolors.gif">
&ltparam name="bgcolor" value="#000000">
&ltparam name="overlay" value="true">
&ltparam name="area1" value="1 3 460 138">
&ltparam name="image1" value="images/jw1.gif">
&ltparam name="url1" value="http://prominence.com/">
&ltparam name="area2" value="8 149 243 188">
&ltparam name="image2" value="jw2.gif">
&ltparam name="url2" value="http://prominence.com/">
&ltparam name="area3" value="256 147 196 26">
&ltparam name="image3" value="images/jw3.gif">
&ltparam name="url3" value="http://prominence.com/">
&ltparam name="area4" value="255 171 205 34">
&ltparam name="image4" value="images/jw4.gif">
&ltparam name="url4" value="http://prominence.com/">
</applet >


The first three parameters define the general features of the image map. The "main" parameter is the background image, and the "bgcolor" is the background color. The "overlay" parameter should have a value of true or false, and determines whether the images are drawn on top of the background image over their respective areas or centered below. We use the type wrapper objects, Boolean and Integer, to convert strings to the primitive types. The Boolean class has a static method, valueOf, that takes a string as a parameter and returns the corresponding Boolean whose booleanValue method we call. The Integer class has a method, parseInt, that takes a string and returns an integer. We want the integer and boolean values as primitive types, not reference types, so we use these classes to perform manipulation of the strings in order to get integer and boolean primitive types.

When we collect the background image into the variable background, we call the applet's prepareImage method with the image as the parameter. This method begins downloading the image at that time; otherwise, the image would not be downloaded until we need to paint it for the first time, causing more flicker. This is a simple optimization that can be employed when images are used.

The rest of the parameters define distinct regions of the image map with a string representing the Rectangle coordinates (x , y, width, height), and the images and URLs associated with each region. The parameter names start with area, image, and url, respectively, and numbers are added to the end, beginning with 1. Since we are using Vectors to store these values, there is no limit on the number of regions that can be defined.

Validity checking makes the applet more robust, and we require that each region have a valid image, URL, and coordinate set. We collect the parameters in logical groups of three, checking to make sure that none of the Strings are null. If any of these are null, we set the ok boolean to false to indicate that it was the last fully correct region in the sequence, and the for loop will terminate. A try .. catch statement is then used to ensure that everything is correct when the parameters are converted to their usable types.

1 | 2 | 3 | 4 |  Next >
Resources