Previous <-->
Next <==>
All
<applet code=StackedRects.class width=150 height=75>
<param name=stack value=false>
Cannot run the StackedRects applet.
</applet>
<applet code=StackedRects.class width=150 height=75>
<param name=center value=true>
<param name=outcolors value="random">
<param name=incolors value="random Random">
Cannot run the StackedRects applet.
</applet>
import java.applet.Applet;
import java.awt.*;
import java.net.*;
import java.util.StringTokenizer;
///////////////////////////////////////////////////////////////////////////////
// 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 17: add resets to default and miscellany\n"
+ "Steve Kinzler, kinzler@cs.indiana.edu, Nov 95/Mar 96\n" + url;
}
int nrects, pause;
boolean cover, center, grid, stack, freeze;
RectMaker outrect, inrect;
Color random;
int num = 1, prevnum = 1, prevkey = '\f';
boolean innum = false, dflt = false;
Image image;
Graphics imageG;
Thread kicker = null;
String pinfo[][] = {
{"bgcolor", "color", "background color"},
{"fgcolor", "color", "foreground color"},
{"nrects", "# rects", "starting rectangles [0]"},
{"pause", "ds", "pause between rectangles [1]"},
{"cover", "boolean", "overlap rectangles [false]"},
{"center", "boolean", "center rectangles [false]"},
{"grid", "boolean", "constrain to a grid [true]"},
{"stack", "boolean", "stack new rectangles [true]"},
{"freeze", "boolean", "start applet suspended [false]"},
{"outthick", "# pixels", "outer line thickness (5%)"},
{"inthick", "# pixels", "inner line thickness (5%)"},
{"outdimen", "int", "outer 3D height [0]"},
{"indimen", "int", "inner 3D height [0]"},
{"outcolors", "color ...", "outer cycled colors [fg]"},
{"incolors", "color ...", "inner cycled colors [bg]"}
};
public String[][] getParameterInfo() {
return pinfo;
}
// StackedRects // Initialization /////////////////////////////////////////////
public String getParameter(String s) {
return (dflt) ? null : super.getParameter(s);
}
public void init() {
Dimension d = size();
if (d.width >= 4) width = d.width;
if (d.height >= 4) height = d.height;
resize(width, height);
ColorSeq groundcolors = new ColorSeq();
String s = getParameter("BGCOLOR");
if (s != null) setBackground(groundcolors.parseColor(s));
s = getParameter("FGCOLOR");
if (s != null) setForeground(groundcolors.parseColor(s));
outrect = new RectMaker();
inrect = new RectMaker();
setColors();
setParams();
image = createImage(width, height);
imageG = image.getGraphics();
clear();
stackRect(nrects);
}
void setColors() {
random = null;
setColors(outrect);
random = outrect.colors.random;
setColors(inrect);
}
void setColors(RectMaker rect) {
boolean out = (rect == outrect);
String s = getParameter((out) ? "OUTCOLORS" : "INCOLORS");
Color fg = getForeground(), bg = getBackground();
rect.colors = new ColorSeq(s, fg, bg, (out) ? fg : bg, random);
}
void dfltColors() {
dflt = true; setColors(); dflt = false;
}
void dfltColors(RectMaker rect) {
dflt = true; setColors(rect); dflt = false;
}
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("STACK");
stack = (s != null) ? s.equals("true") : true;
s = getParameter("FREEZE");
freeze = (s != null) ? s.equals("true") : false;
setParams(outrect);
setParams(inrect);
}
void setParams(RectMaker rect) {
boolean out = (rect == outrect);
String s = getParameter((out) ? "OUTTHICK" : "INTHICK");
setThick(rect, (s != null) ? Integer.parseInt(s)
: Math.min(width, height) / 20);
s = getParameter((out) ? "OUTDIMEN" : "INDIMEN");
rect.dimen = (s != null) ? Integer.parseInt(s) : 0;
rect.colors.reset();
}
void dfltParams() {
dflt = true; setParams(); dflt = false;
}
void dfltParams(RectMaker rect) {
dflt = true; setParams(rect); dflt = false;
}
void setThick(RectMaker rect, int t) {
RectMaker other = ((rect == outrect) ? inrect : outrect);
int max = Math.min(width, height) / 2 - other.getThick();
rect.setThick((t < max) ? t : max);
}
void addThick(RectMaker rect, int n) {
setThick(rect, rect.getThick() + n);
}
// 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 = outrect.getThick();
int tt = t + inrect.getThick();
if (cover || center) {
double maxa = width / 2.0 - tt;
double maxb = height / 2.0 - tt;
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 - 2 * tt + 1;
int maxb = height - 2 * tt + 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;
}
}
if (! stack) clear();
outrect.paint(imageG, a, b, x, y);
inrect.paint( imageG, a+t, b+t, x-t, y-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 boolean mouseEnter(Event evt, int x, int y) {
showStatus(url);
return true;
}
public boolean mouseExit(Event evt, int x, int y) {
showStatus(null);
return true;
}
public boolean mouseUp(Event evt, int x, int y) {
goHome();
return true;
}
public void goHome() {
if (url != null) {
try { getAppletContext().showDocument(new URL(url)); }
catch (MalformedURLException e) {
url = null;
showStatus("Ignoring Malformed URL");
}
}
}
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 '.': num = prevnum; keyDown(evt, prevkey);
return true;
case 'h': goHome(); break;
case 'i': setParams(); break;
case 'I': setParams(outrect); break;
case '\011': setParams(inrect); break;
case 'o': dfltParams(); break;
case 'O': dfltParams(outrect); break;
case '\017': dfltParams(inrect); break;
case '!': cover = ! cover; break;
case '@': center = ! center; break;
case '#': grid = ! grid; break;
case 's': stack = ! stack; 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': addThick(inrect, num);
case 'T': addThick(outrect, num); break;
case '\024': addThick(inrect, num); break;
case 'y': addThick(inrect, -num);
case 'Y': addThick(outrect, -num); break;
case '\031': addThick(inrect, -num); break;
case 'd': inrect.dimen += num;
case 'D': outrect.dimen += num; break;
case '\004': inrect.dimen += num; break;
case 'e': inrect.dimen -= num;
case 'E': outrect.dimen -= num; break;
case '\005': inrect.dimen -= num; break;
case 'r': setColors(); break;
case 'R': setColors(outrect); break;
case '\022': setColors(inrect); break;
case 'u': dfltColors(); break;
case 'U': dfltColors(outrect); break;
case '\025': dfltColors(inrect); 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();
}
prevkey = key;
prevnum = num; num = 1;
innum = false;
return true;
}
}
///////////////////////////////////////////////////////////////////////////////
// RectMaker //////////////////////////////////////////////////////////////////
class RectMaker {
private int thick = 1;
int dimen = 0;
ColorSeq colors = null;
RectMaker() {}
RectMaker(int t, int d, ColorSeq c) {
setThick(t);
dimen = d;
colors = c;
}
int getThick() { return thick; }
void setThick(int t) { thick = Math.max(1, t); }
void paint(Graphics g, int a, int b, int x, int y) {
int t = thick, w = x - a + 1, h = y - b + 1;
if (colors != null) g.setColor(colors.nextColor());
g.fillRect(a, b, w, t);
g.fillRect(a, y-t+1, w, t);
g.fillRect(a, b, t, h);
g.fillRect(x-t+1, b, t, h);
boolean up = (dimen > 0);
int n = Math.min(Math.abs(dimen), thick / 2);
for (int i = 0, j = 0; i < n; i++, j += 2) {
g.draw3DRect(a+i, b+i, w-1-j, h-1-j, up);
g.draw3DRect(a+t-1-i, b+t-1-i, w-t-t+1+j, h-t-t+1+j, !up);
}
}
}
///////////////////////////////////////////////////////////////////////////////
// ColorSeq // Construction ///////////////////////////////////////////////////
class ColorSeq {
Color colors[], fg, bg, dflt, random;
private protected int p;
public ColorSeq() {
this(null, null, null, null, null);
}
public ColorSeq(String s) {
this( s, null, null, null, null);
}
public ColorSeq(String s, Color f, Color b) {
this( s, f, b, null, null);
}
public ColorSeq(String s, Color f, Color b, Color d, Color r) {
fg = (f == null) ? Color.black : f;
bg = (b == null) ? Color.white : b;
dflt = (d == null) ? fg : d;
random = (r == null) ? randomColor() : r;
if (s == null) {
colors = new Color[1];
colors[p = 0] = dflt;
} else {
StringTokenizer st = new StringTokenizer(s);
colors = new Color[st.countTokens()];
p = -1;
while (st.hasMoreTokens())
colors[++p] = parseColor(st.nextToken());
}
}
// ColorSeq // Use ////////////////////////////////////////////////////////////
public synchronized void reset() {
p = colors.length - 1;
}
public Color currColor() {
return((colors[p] == null) ? randomColor() : colors[p]);
}
public synchronized Color nextColor() {
p = (p + 1) % colors.length;
return currColor();
}
public synchronized Color prevColor() {
p = (p > 0) ? p - 1 : (p == 0) ? colors.length - 1 : p;
return currColor();
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("ColorSeq{");
for (int i = 0; i < colors.length; i++) {
if (i == p) buf.append("^");
buf.append((colors[i] == null) ? "null"
: colors[i].toString());
if (i < colors.length - 1) buf.append(", ");
}
buf.append("}");
return buf.toString();
}
// ColorSeq // Utilities //////////////////////////////////////////////////////
public Color parseColor(String s) {
if (s.equals("fg")) return fg;
else if (s.equals("bg")) return bg;
else if (s.equals("default")) return dflt;
else if (s.equals("random")) return random;
else if (s.equals("Random")) return randomColor();
else if (s.equals("RANDOM")) return null;
else if (s.equals("black")) return Color.black;
else if (s.equals("blue")) return Color.blue;
else if (s.equals("cyan")) return Color.cyan;
else if (s.equals("darkGray")) return Color.darkGray;
else if (s.equals("gray")) return Color.gray;
else if (s.equals("green")) return Color.green;
else if (s.equals("lightGray")) return Color.lightGray;
else if (s.equals("magenta")) return Color.magenta;
else if (s.equals("orange")) return Color.orange;
else if (s.equals("pink")) return Color.pink;
else if (s.equals("red")) return Color.red;
else if (s.equals("white")) return Color.white;
else if (s.equals("yellow")) return Color.yellow;
return new Color(parseTaggedInt(s));
}
public static Color randomColor() {
return new Color((int) (Math.random() * 256),
(int) (Math.random() * 256),
(int) (Math.random() * 256));
}
public static int parseTaggedInt(String s)
throws NumberFormatException {
if (s.startsWith("0x"))
return Integer.parseInt(s.substring(2), 16);
else if (s.startsWith("#"))
return Integer.parseInt(s.substring(1), 16);
else if (s.startsWith("0") && s.length() > 1)
return Integer.parseInt(s.substring(1), 8);
return Integer.parseInt(s);
}
}