// This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.util.*;
/**
* A Java applet that simulates a client-side imagemap.
* Plays a sound whenever the user clicks on one of the hyperlinks.
*/
public class Soundmap extends Applet {
protected Image image; // The image to display.
protected Vector rects; // A list of rectangles in it.
protected AudioClip sound; // A sound to play on user clicks in a rectangle.
/** Initialize the applet */
public void init() {
// Look up the name of the image, relative to a base URL, and load it.
// Note the use of three Applet methods in this one line.
image = this.getImage(this.getDocumentBase(), this.getParameter("image"));
// Lookup and parse a list of rectangular areas and the URLs they map to.
// The convenience routine getRectangleParameter() is defined below.
rects = new Vector();
ImagemapRectangle r;
for(int i = 0; (r = getRectangleParameter("rect" + i)) != null; i++)
rects.addElement(r);
// Look up a sound to play when the user clicks one of those areas.
sound = this.getAudioClip(this.getDocumentBase(),
this.getParameter("sound"));
// Specify an "event listener" object to respond to mouse button
// presses and releases. Note that this is the Java 1.1 event model.
// Note that it also uses a Java 1.1 inner class, defined below.
this.addMouseListener(new Listener());
}
/** Called when the applet is being unloaded from the system.
* We use it here to "flush" the image we no longer need. This may
* result in memory and other resources being freed more quickly. */
public void destroy() { image.flush(); }
/** To display the applet, we simply draw the image. */
public void paint(Graphics g) { g.drawImage(image, 0, 0, this); }
/** We override this method so that it doesn't clear the background
* before calling paint(). No clear is necessary, since paint() overwrites
* everything with an image. Causes less flickering this way. */
public void update(Graphics g) { paint(g); }
/** Parse a comma-separated list of rectangle coordinates and a URL.
* Used to read the imagemap rectangle definitions from applet parameters */
protected ImagemapRectangle getRectangleParameter(String name) {
int x, y, w, h;
URL url;
String value = this.getParameter(name);
if (value == null) return null;
try {
StringTokenizer st = new StringTokenizer(value, ",");
x = Integer.parseInt(st.nextToken());
y = Integer.parseInt(st.nextToken());
w = Integer.parseInt(st.nextToken());
h = Integer.parseInt(st.nextToken());
url = new URL(this.getDocumentBase(), st.nextToken());
}
catch (NoSuchElementException e) { return null; }
catch (NumberFormatException e) { return null; }
catch (MalformedURLException e) { return null; }
return new ImagemapRectangle(x, y, w, h, url);
}
/**
* An instance of this inner class is used to respond to mouse events
*/
class Listener extends MouseAdapter {
/** The rectangle that the mouse was pressed in. */
private ImagemapRectangle lastrect;
/** Called when a mouse button is pressed. */
public void mousePressed(MouseEvent e) {
// On button down, check if we're inside one of the specified rectangles.
// If so, highlight the rectangle, display a message, and play a sound.
// The utility routine findrect() is defined below.
ImagemapRectangle r = findrect(e);
if (r == null) return;
Graphics g = Applet.this.getGraphics();
g.setXORMode(Color.red);
g.drawRect(r.x, r.y, r.width, r.height); // highlight rectangle
Applet.this.showStatus("To: " + r.url); // display URL
sound.play(); // play the sound
lastrect = r; // Remember the rectangle so it can be un-highlighted.
}
/** Called when a mouse button is released. */
public void mouseReleased(MouseEvent e) {
// When the button is released, unhighlight the rectangle. If the
// mouse is still inside it, ask the browser to go to the URL.
if (lastrect != null) {
Graphics g = Applet.this.getGraphics();
g.setXORMode(Color.red);
g.drawRect(lastrect.x, lastrect.y, lastrect.width, lastrect.height);
Applet.this.showStatus(""); // Clear the message.
ImagemapRectangle r = findrect(e);
if ((r != null) && (r == lastrect)) // If still in the same rectangle
Applet.this.getAppletContext().showDocument(r.url); // Go to the URL
lastrect = null;
}
}
/** Find the rectangle we're inside. */
protected ImagemapRectangle findrect(MouseEvent e) {
int i, x = e.getX(), y = e.getY();
for(i = 0; i < rects.size(); i++) {
ImagemapRectangle r = (ImagemapRectangle) rects.elementAt(i);
if (r.contains(x, y)) return r;
}
return null;
}
}
/**
* A helper class. Just like java.awt.Rectangle, but with a URL field.
* Note the use of a nested toplevel class for neatness.
*/
static class ImagemapRectangle extends Rectangle {
URL url;
public ImagemapRectangle(int x, int y, int w, int h, URL url) {
super(x, y, w, h);
this.url = url;
}
}
}
|