/*
MazeIcon.java 3.0
Written by Kevin N. Haw and JoAnn K. Haw, www.thehaws.org. Please mail comments
via the link at our website.
All contents copyright 2000-2005 by Kevin N. Haw and JoAnn K. Haw. The authors
grant permission to freely distribute and modify this program as long as this
copyright notice and all copyright notices embedded in the program
remain intact.
This applet draws small mazes based on square, diamond, and hex shaped
tiles for use as icons or decorative borders. It requires the MazeTile class
(distributed with this class or found at our website) to create the maze.
the two are usually placed in a common .jar file to allow for ease of use.
The applet is invoked with the following parameters:
fgcolor - an RBG hex value Color of maze walls (blue is default)
bgcolor - an RBG hex value Color of maze background (white is default)
solcolor- an RBG hex value Color of maze solution (red is default)
tileShape - square|diamond|hex Shape of tiles in maze (square is default)
HREF - URL (begining "http://") URL to go to on a mouseclick (default is none)
ALT - any text Browser text when mouse crosses applet
solution - on|off|toggleOn|toggleOff on/off displays maze solution.
toggleOn/Off allows toggling solution
w/ r-click (toggleOff is default)
refresh - integer Draw a new maze after a number of seconds
(default is a new maze only when
the whole page is refreshed)
Example 1: A simple icon linked to a website
Example 2: A horizontal, hex shaped border on a tan background with
black foreground. The solution is displayed (but can be r-clicked
to toggle off) and the maze refreshes every three seconds.
See getParameterInfo() below for documentation of applet parameters.
*/
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics;
import java.util.Vector;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.PrintStream;
import java.awt.Color;
import java.awt.Polygon;
import java.applet.AppletContext;
import java.net.URL;
import java.lang.Thread;
// Define an applet to create mazes
public class MazeIcon extends java.applet.Applet implements MouseListener, Runnable
{
// Copyright and version data
public static String copyMsg = "MazeIcon: Copyright Kevin N. Haw, 2000-2001.";
public static String verMsg = "MazeIcon v 3.0";
public static int verno = 0x300000; // Byte0=revision, byte1= minor version, byte2= major version
Thread refreshThread; // The thread that redraws maze
int refreshTimer; // Time to run refreshThread
MazeTile firstTile = null;
String tileShapeParam;
URL clickURL = null; // URL to go to on a mouseclick
String linkMsg = null;
// Flags reflecting parameters passed into applet
Color fgColor = Color.blue; // Color of maze walls (default blue)
Color bgColor = Color.white; // Color for maze background (default white)
Color solColor = Color.red; // Color for solution & labels (default red)
Boolean labelParam = new Boolean(false);
boolean toggleSolutionParam = true;
Polygon tileShape; // Base shape of each tile in the maze
boolean drawSolution = false;
Rectangle r;
Vector theSolution; // Solution to the maze
MazeTile startTile; // Start of maze in solution
MazeTile endTile; // End of maze in solution
// Override the init() method to set up mouse listener and parse
// applet parameters.
public void init()
{
// Set up mouseListener to listen to mouse input commands
addMouseListener(this);
// Read the bgColor parameter - default to white
try {
bgColor = new Color(Integer.parseInt(getParameter("bgcolor"),16));
} catch (Exception e) { }
// Set the background color to parameter
setBackground(bgColor);
// Read the fgColor parameter (maze walls) - default to blue
try {
fgColor = new Color(Integer.parseInt(getParameter("fgcolor"),16));
} catch (Exception e) { }
// Read the solColor parameter (solution & labels) - default to red
try {
solColor = new Color(Integer.parseInt(getParameter("solcolor"),16));
} catch (Exception e) { }
// Read the refresh parameter - default is to refresh maze on repainting only
try {
refreshTimer = Integer.parseInt(getParameter("refresh"),10);
} catch (Exception e) { refreshTimer=0; }
// Read the label parameter - default is false
try {
labelParam = new Boolean( getParameter("label") );
} catch (Exception e) { }
// Read the ALT parameter as message to drive on browser's status line
// (like alternate text on a link). Default is none.
try {
linkMsg = new String(getParameter("alt"));
} catch (Exception e) { }
// Read the HREF parameter as a URL to go to when clicked
try {
clickURL = new URL(getParameter("href"));
} catch (Exception e) { }
// Read the solution parameter. Default is "toggleOff"
try {
String solutionParam = new String(getParameter("solution"));
solutionParam = solutionParam.toLowerCase();
if (solutionParam.compareTo("on") == 0)
{
// Parameter "Solution = On" means always show the solution, never toggle
toggleSolutionParam = false;
drawSolution = true;
}
else if (solutionParam.compareTo("off") == 0)
{
// Parameter "Solution = Off" means never show the solution, never toggle
toggleSolutionParam = false;
drawSolution = false;
}
else if (solutionParam.compareTo("toggleon") == 0)
{
// Parameter "Solution = toggleOn" means start showing the
// solution, but toggle it on when right-clicked.
toggleSolutionParam = true;
drawSolution = true;
}
else if (solutionParam.compareTo("toggleoff") == 0)
{
// Parameter "Solution = toggleOff" means start w/o showing the
// solution, but toggle it on when right-clicked. (DEFAULT)
toggleSolutionParam = false;
drawSolution = true;
}
} catch (Exception e) { }
// Read the tileShape parameter
try {
tileShapeParam = getParameter("tileShape");
} catch (Exception e) { }
// Set up polygon for maze tiles based on tileShape parameter
tileShape = new Polygon();
try {
if ( tileShapeParam.equalsIgnoreCase("hex") )
{
// Make tiny hex shaped tiles
tileShape.addPoint( 5, 3); // Northeast
tileShape.addPoint( 0, 6); // North
tileShape.addPoint( -5, 3); // Northwest
tileShape.addPoint( -5, -3); // Southwest
tileShape.addPoint( 0, -6); // South
tileShape.addPoint( 5, -3); // Southeast
}
else if ( tileShapeParam.equalsIgnoreCase("diamond") )
{
// Now, make a tiny diamond shaped tile
tileShape.addPoint( 3, 0); // North
tileShape.addPoint( 0, 3); // East
tileShape.addPoint( -3, 0); // South
tileShape.addPoint( 0, -3); // West
}
else
{
// By default, make square shaped tiles
tileShape.addPoint( 3, 3); // Northeast
tileShape.addPoint(-3, 3); // Southeast
tileShape.addPoint(-3,-3); // Southwest
tileShape.addPoint( 3,-3); // Southeast
}
} catch (Exception e) {
// By default, make square shaped tiles
tileShape.addPoint( 3, 3); // Northeast
tileShape.addPoint(-3, 3); // Southeast
tileShape.addPoint(-3,-3); // Southwest
tileShape.addPoint( 3,-3); // Southeast
}
}
// Override the destroy() method to remove mouse listener.
public void destroy()
{
removeMouseListener(this);
}
// Override the stop() method.
public void stop()
{
// Kill the refresh thread
refreshThread = null;
}
// Set up a run() method for refreshing the maze
public void run()
{
Thread me = Thread.currentThread();
// If requested, redraw the maze periodically
if(refreshTimer > 0)
{
while (refreshThread == me)
{
// Sleep for number of second in "refresh" parameter
try {
Thread.currentThread().sleep(refreshTimer*1000);
} catch (InterruptedException e) { }
// Now awake - make a new maze, get a new solution for it, and repaint
firstTile.constructMaze();
theSolution = firstTile.solve(startTile, endTile);
repaint();
}
}
}
// Override the start() method. This will be rerun whenever the
// HTML page is reloaded or a different page with the same applet
// is loaded. It creates a brand new maze each time it is run.
public void start()
{
// Get boundaries of the drawing plane
r= getBounds();
// If not yet done, allocate the tiles for the new maze
if (firstTile == null)
{
firstTile = MazeTile.AllocateMaze(tileShape, r);
}
// Now, actually create paths in the maze
firstTile.constructMaze();
// Find the maze's solution
startTile = firstTile.corner("lt"); // Left, topmost tile
endTile = firstTile.corner("rb"); // Right, bottommost tile
theSolution = firstTile.solve(startTile, endTile);
// Set up a thread for refresh requests
if(refreshTimer > 0)
{
refreshThread = new Thread(this);
refreshThread.start();
}
}
// Draw the applet
public void paint(Graphics g)
{
int i;
Point p1, p2;
// Clear the rectangle
g.setColor(bgColor);
g.fillRect(r.x, r.y, r.width, r.height);
// Draw the maze
firstTile.paint(g, fgColor);
// Draw the solution if requested
if (drawSolution)
{
g.setColor(solColor);
for (i=1; i",
"Color of maze walls (blue is default)"},
{"bgcolor", "",
"Color of maze background (white is default)"},
{"solcolor", "",
"Color of maze solution & labels (red is default)"},
{"tileShape",
"square|diamond|hex|bowtie|tiny|tinyhex|tinydiamond",
"shape of tiles in maze (square is default)"},
{"HREF", "",
"URL to go to on a mouseclick (often used w/ tileShape=tiny)"},
{"ALT", "","Alternate text for URL"},
{"solution", "on|off|toggleOn|toggleOff",
"on/off displays maze soltuion. toggleOn/Off allows toggling "
+"solution w/ r-click (toggleOff is default)"},
{"refresh", "integer",
"Draw a new maze after a number of seconds (default is not to)"}
};
}
}