Listing 1: applet

// class JavaSlot, written by Paul Buchheit, ptb@po.cwru.edu
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Event;

// This is a half baked implementation of a Java Slot machine,
// problems and prospective fixes are in the accompanying 
// Linux Journal Article.
public class JavaSlot extends Applet implements Runnable
{
	Image strip, body;	// The slot machine wheel and body 

	int wheelPosX = 22, wheelPosY = 22;	// The positon of the wheel
	int wheelSize = 55;	// The size of the wheel 
	int nstripItems = 5;	// How many items are on the wheel
	int stripLen = nstripItems * wheelSize;

	int currentWheelPos;	// speaks for itself

	// about how far (in items) should the wheel spin before stopping
	int itemsToSpin;	

	int delay;		// The delay between wheel movements
	// max and min wheel movement during a single step of the wheel
	double maxSpeed = 20, minSpeed = 2;  

	Thread spinning = null;

	public void init() {
		// Grabs the images from the server
		strip = getImage(getCodeBase(), "strip.gif");
		body = getImage(getCodeBase(), "tux-body.gif");

		// Reads values from the HTML file
		delay = readIntParam("delay", 10);
		itemsToSpin = readIntParam("itemsToSpin", 20);

		// sets the inital wheel position
		currentWheelPos = getNewItem() * wheelSize;
	}


	// Reads in the integer parameter "name" from the HTML, returns 
	// defalutVal if a value is not specified
	int readIntParam(String name, int defaultVal) {
		String s = getParameter(name);
		if(s == null) {
			return(defaultVal);
		} else {
			return(Integer.valueOf(s).intValue());
		}
	}


	// Randomly chooses a new item on wheel
	int getNewItem() {
		return((int)(Math.random() * nstripItems) % nstripItems);
	}	


	// Calculates the next wheel position based on the current
	// position and the desired final position.
	// Not magic, meant to make the wheel slow down as is reaches its
	// destination.
	int findNextPos(int currentP, int finalP) {
		double speed = Math.cos(Math.PI / 2 * 
		  (double)currentP / (double)finalP);
		
		speed *= maxSpeed - minSpeed;
		speed += minSpeed;

		currentP += Math.round(speed);
		return(Math.min(currentP, finalP)); // Makes sure we don't go over
	}


	// Gets called when the spinning thread is started, spins the wheel
	public void run() {
		int nextItem = getNewItem();	// gets something to spin to
		int pos = currentWheelPos;
		int finalPos = (itemsToSpin + nextItem) * wheelSize;

		while((spinning != null) && (pos != finalPos)) {
			pos = findNextPos(pos, finalPos);
			currentWheelPos = pos % stripLen;

			repaint();

			try {
				Thread.sleep(delay);
			} catch(InterruptedException e) { }
		}

		spinning = null;
	}


	// This gets called when the mouse button is clicked inside
	// the applet, if the wheel is already spinning it will 
	// ignore the click, otherwise it will start up a thread
	// that spins the wheel
	public boolean mouseDown(Event e, int x, int y) {
		if(spinning == null) {
			spinning = new Thread(this);
			spinning.start();
		}

		return(true);
	}


	// Draws the wheel turned to position "pos" using a Graphics
	// clipped for the wheel
	void drawWheel(Graphics g, int pos) {
		g.drawImage(strip, 0, -pos, this);

		// loops back if we are running off the end of the strip.
		if(pos > stripLen - wheelSize)
			g.drawImage(strip, 0, stripLen - pos, this);
	}


	// creates a new Graphics for drawing the wheel
	Graphics createForWheel(Graphics bodyG) {
		return bodyG.create(wheelPosX, wheelPosY, wheelSize, wheelSize);
	}


	// Draws the whole slot machine
	public void paint(Graphics g) {
		g.drawImage(body, 0, 0, this);

		Graphics clipG = createForWheel(g);
		drawWheel(clipG, currentWheelPos);
		clipG.dispose();
	}
}