Previous <--> Next <==> All
<applet code=StackedRects.class width=150 height=75>
Cannot run the StackedRects applet.
</applet>
Cannot run the StackedRects applet.
import java.applet.Applet;
import java.awt.*;

///////////////////////////////////////////////////////////////////////////////
// StackedRects // Declaration ////////////////////////////////////////////////

public class StackedRects extends Applet implements Runnable {

	final static int MINSLEEP = 25;
	int width  = 480, height = 280;	// 4x4 minimum
	String url = "http://www.cs.indiana.edu/hyplan/kinzler/fun/"
		   + "StackedRects/index.html";

	public String getAppletInfo() {
		return
"StackedRects - a continuous, random graphic of overlaying rectangles\n"
+ "Development version 11: add multiplier keys\n"
+ "Steve Kinzler, kinzler@cs.indiana.edu, Nov 95/Mar 96\n" + url;
	}

	int	 nrects, thick, pause;
	boolean  cover, center, grid, freeze;

	int	 num = 1;
	boolean	 innum = false;
	Image	 image;
	Graphics imageG;
	Thread	 kicker = null;

	String pinfo[][] = {
		{"nrects", "# rects",  "starting rectangles [0]"},
		{"thick",  "# pixels", "line thickness (5%)"},
		{"pause",  "ds",       "pause between rectangles [1]"},
		{"cover",  "boolean",  "overlap rectangles [false]"},
		{"center", "boolean",  "center rectangles [false]"},
		{"grid",   "boolean",  "constrain to a grid [true]"},
		{"freeze", "boolean",  "start applet suspended [false]"}
	};

	public String[][] getParameterInfo() {
		return pinfo;
	}

// StackedRects // Initialization /////////////////////////////////////////////

	public void init() {
		Dimension d = size();
		if (d.width  >= 4) width  = d.width;
		if (d.height >= 4) height = d.height;
		resize(width, height);

		setParams();

		image  = createImage(width, height);
		imageG = image.getGraphics();
		clear();
		stackRect(nrects);
	}

	void setParams() {
		String s = getParameter("NRECTS");
		nrects = (s != null) ? Math.abs(Integer.parseInt(s)) : 0;
		s = getParameter("PAUSE");
		pause  = (s != null) ? Math.abs(Integer.parseInt(s)) : 1;
		s = getParameter("COVER");
		cover  = (s != null) ? s.equals("true") : false;
		s = getParameter("CENTER");
		center = (s != null) ? s.equals("true") : false;
		s = getParameter("GRID");
		grid   = (s != null) ? s.equals("true") : true;
		s = getParameter("FREEZE");
		freeze = (s != null) ? s.equals("true") : false;
		s = getParameter("THICK");
		if (s != null) {
			int p = Math.max(1, Math.abs(Integer.parseInt(s)));
			thick = (p <= Math.min(width, height) / 4) ? p :
				Math.max(1, Math.min(width, height) / 20);
		} else
			thick = Math.max(1, Math.min(width, height) / 20);
	}

// StackedRects // Graphics ///////////////////////////////////////////////////

	public void update(Graphics g) {
		paint(g);
	}

	public synchronized void paint(Graphics g) {
		g.drawImage(image, 0, 0, this);
	}

	synchronized void clear() {
		imageG.setColor(getBackground());
		imageG.fillRect(0, 0, width, height);
	}

	void stackRect(int n) {
		for (int i = 0; i < n; i++) stackRect();
	}

	synchronized void stackRect() {
		int a, b, x, y;
		int t = thick;

		if (cover || center) {
			double maxa = width  / 2.0 - 2.0 * t;
			double maxb = height / 2.0 - 2.0 * t;
			a =		 (int) (Math.random() * maxa);
			b =		 (int) (Math.random() * maxb);
			x = width  - 1 - (int) (Math.random() * maxa);
			y = height - 1 - (int) (Math.random() * maxb);
			if (center) {
				x = width  - 1 - a;
				y = height - 1 - b;
			}
			if (grid) {
				a -= a % t; x += (width  - 1 - x) % t;
				b -= b % t; y += (height - 1 - y) % t;
			}
		} else {
			int maxa = width  - 4 * t + 1;
			int maxb = height - 4 * t + 1;
			a =		 (int) (Math.random() * maxa);
			b =		 (int) (Math.random() * maxb);
			x = width  - 1 - (int) (Math.random() * (maxa - a));
			y = height - 1 - (int) (Math.random() * (maxb - b));
			if (Math.random() >= 0.5) {
				int c = a, d = b;
				a = width - 1 - x; b = height - 1 - y;
				x = width - 1 - c; y = height - 1 - d;
			}
			if (grid) {
				a -= a % t; x -= (x + 1) % t;
				b -= b % t; y -= (y + 1) % t;
			}
		}

		int w = x - a + 1;
		int h = y - b + 1;

		imageG.setColor(getForeground());
		imageG.fillRect(a,       b,       w,     t);
		imageG.fillRect(a,       y-t+1,   w,     t);
		imageG.fillRect(a,       b,       t,     h);
		imageG.fillRect(x-t+1,   b,       t,     h);

		imageG.setColor(getBackground());
		imageG.fillRect(a+t,     b+t,     w-t-t, t);
		imageG.fillRect(a+t,     y-t-t+1, w-t-t, t);
		imageG.fillRect(a+t,     b+t,     t,     h-t-t);
		imageG.fillRect(x-t-t+1, b+t,     t,     h-t-t);
	}

// StackedRects // Execution //////////////////////////////////////////////////

	public void start() {
		start(! freeze);
	}

	synchronized void start(boolean b) {
		if (kicker == null && b) {
			kicker = new Thread(this, this.getClass().getName());
			kicker.setPriority(Thread.MIN_PRIORITY);
			kicker.start();
		}
	}

	public void run() {
		while (kicker != null) {
			stackRect();
			repaint();
			try { kicker.sleep(MINSLEEP + pause * 100); }
			catch (InterruptedException e) { break; }
		}
	}

	void toggle() {
		if (kicker == null) { start(true); } else { stop(); }
	}

	public synchronized void stop() {
		if (kicker != null) kicker.stop();
		kicker = null;
	}

// StackedRects // Events /////////////////////////////////////////////////////

	public synchronized boolean keyDown(Event evt, int key) {
		if ('0' <= key && key <= '9') {
			num   = (innum) ? 10 * num + key - '0' : key - '0';
			innum = true;
			return true;
		}

		switch (key) {
		case 'i':	setParams();	   break;
		case '!':	cover  = ! cover;  break;
		case '@':	center = ! center; break;
		case '#':	grid   = ! grid;   break;
		case 'f':	freeze = ! freeze; break;
		case 'n':	nrects = Math.max(0, nrects - num);    break;
		case 'N':	nrects = nrects + num;		       break;
		case 'p':
		case '+':	pause  = Math.max(0, pause - num);     break;
		case 'P':
		case '-':	pause  = pause + num;		       break;
		case 't':	thick  = Math.max(1, thick - num);     break;
		case 'T':	thick  = Math.min(thick + num,
					 Math.min(width, height) / 4); break;
		case 'c':	clear(); stackRect(nrects); repaint(); break;
		case 'C':	clear();		    repaint(); break;
		case '\f':				    repaint(); break;
		case ' ':		 stackRect(num);    repaint(); break;
		case '\r':
		default:	toggle();
		}

		num   = 1;
		innum = false;
		return true;
	}
}