import java.applet.Applet;
//import java.awt.Cursor; //JDK 1.1
import java.awt.Event;
//import java.awt.event.MouseAdapter; //JDK 1.1
//import java.awt.event.MouseEvent; //JDK 1.1
//import java.awt.event.MouseMotionAdapter; //JDK 1.1
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.awt.MediaTracker;
import java.awt.Rectangle;
import java.net.MalformedURLException;
import java.net.URL;
/**
* This class allows to have a grahical menu that changes its look when the
* user moves the mouse on the menu; if the user press the button on the menu,
* a URL is look for.
* The parameters for this applet are:
* frame : [optional] the frame to use to lunch the URL (default=_SELF)
* items : [optional] number of items in the image. The default is 1
* first : [optional] first item to display (default is 1)
* last : [optional] last item to display (default is items)
* pos : [optional] can be HORIZONTAL or VERTICAL (default is VERTICAL)
* image : [mandatory] the image (jpg or gif) that represents the menu.
* If the applet has a size of (width x height), the image should have,
* although this is not checked, the size (2*width x height). The left side
* of the image contains the menu in its normal state, and the right side,
* in its highlighted state.
* If the menu is going to have 3 items, for example, and the applet size is
* 150 x 120, the developper should generate an image of 300 x 120, with
* 6 images inside, all with the same size.
* If pos=HORIZONTAL, the size should be (2*height,width), and the highlighted
* images are in the down part of the image.
* For each item, it is also needed to give a parameter called 'dst%', with the
* destin URL. This is optional, it not given, the image doesn't change when the
* the mouse moves on
* FIRST and LAST parameters are useful if two different MENUs can be displayed,
* therefore is possible to include both in the same image.
*
* The implementation of this applet is very simple, but:
* a) to speed it up, it is needed to load one image only, and not one for each
* item in the menu. But to split an image is not directly supported in the
* awt, and I have had to develop my own SplitImage class.
* b) the event model has changed in the JDK 1.1; therefore, my nice 1.1 class didn't
* work on any of the current browsers, and I have to use the deprecated API.
* That's the reason because some parts of the code are inside comments: is the
* JDK 1.1 compliant part.
*
* @author (c) LuisM Pena.
* @version 0.2, September-1997
*/
public class Menu extends Applet implements ImageObserver, Runnable
{
public void init()
{
//init some variables
error=null;
urls=null;
image=null;
bImagesReady=false;
bValidImage=false;
yPos=-1;
selectedItem=-1;
height=0;
width=0;
images=null;
// normalCursor=new Cursor(Cursor.DEFAULT_CURSOR); //JDK1.1
// selectedCursor=new Cursor(Cursor.HAND_CURSOR); //JDK1.1
//get the parameters
frame=getParameter("frame");
if (frame==null)
frame=new String("_self");
nItemsTotal=getIntParameter("items",1,1,Integer.MAX_VALUE);
firstItem=getIntParameter("first",1,1,nItemsTotal);
lastItem=getIntParameter("last",nItemsTotal,firstItem,nItemsTotal);
bVertical=isVertical();
nItems=lastItem-firstItem+1;
urls=getURLs();
image=getImage();
if (error==null)
new Thread(this).start();
else
{
showStatus(error);
System.out.println(error);
}
// else
// {
// addMouseListener(new MenuMouseListener()); //JDK 1.1
// addMouseMotionListener(new MenuMouseMotionListener()); //JDK 1.1
// }
}
/**
* Gets the Pos parameter. If not given or it is VERTICAL, it returns true
* If it is HORIZONTAL, it returns false. If the parameter is given, but
* is not a valid value, it sets the error variable
* If error is not null, it returns directly the defaultValue (true).
*/
boolean isVertical()
{
boolean ret=true;
if (error==null)
{
String pos=getParameter("pos");
if (pos!=null)
if (pos.equalsIgnoreCase("horizontal"))
ret=false;
else if (!pos.equalsIgnoreCase("vertical"))
error=new String("Error on parameter 'pos'");
}
return ret;
}
/**
* Gets the parameter associated to an string.
* If the parameter has not been given, it returns the default value.
* It is also checked that the value be between a min and a max value.
* If any error is produced, the error variable is changed
* If error is not null, it returns directly the defaultValue.
*/
int getIntParameter(String item, int defaultValue, int minValue, int maxValue)
{
int ret=defaultValue;
if (error==null)
{
String retItem=getParameter(item);
if (retItem!=null)
try
{
ret=Integer.valueOf(retItem).intValue();
if (ret="+minValue);
else if (ret>maxValue)
error=new String("Par. '"+item+"' must be >="+maxValue);
}
catch(NumberFormatException nfe)
{
error=new String("Error on parameter '"+item+"'");
}
}
return ret;
}
/**
* Get the URLs. If an error is produced, sets the error variable
* If error != null, it doesn't nothing
*/
URL[] getURLs()
{
URL [] urls=null;
if (error==null)
{
urls=new URL[nItems];
String szBaseURL=getCodeBase().toString();
for (int i=0;error==null && i=0 && relative =0 && selectedItem0 && width>0;
bImagesReady=true;
repaint();
}
// Rest is only valid for JDK 1.1
//
// class MenuMouseListener extends MouseAdapter
// {
// public void mouseExited(MouseEvent ev)
// {
// if (bImagesReady)
// noItemsSelected();
// return true;
// }
// public void mousePressed(MouseEvent ev)
// {
// if (selectedItem>=0 && selectedItem