2 * AnimatedButton.java
\r
4 * Created on 06 October 2001, 19:17
\r
9 package org.tjworld.components;
\r
11 import java.awt.Image;
\r
12 import java.util.Vector;
\r
13 import java.awt.MediaTracker;
\r
14 import java.applet.Applet;
\r
15 import java.awt.Color;
\r
18 * A lightweight Swing-based animated button, that
\r
23 public class AnimatedButton extends javax.swing.JButton implements Runnable {
\r
24 private java.util.Vector frames; // animation frames
\r
25 private int nextFrame, lastFrame;
\r
26 private java.awt.Color background;
\r
27 private java.awt.MediaTracker tracker;
\r
28 private Applet parent;
\r
29 private volatile boolean suspended;
\r
31 /** Creates new uninitialized AnimatedButton */
\r
32 public AnimatedButton() {
\r
33 frames = new Vector();
\r
34 background = java.awt.Color.white;
\r
35 nextFrame = lastFrame = -1;
\r
39 /** Creates new AnimatedButton */
\r
40 public AnimatedButton(Color bgColour, java.net.URL imagebase, String prefix, String suffix, int[] delays, int count, Applet parent) {
\r
41 String nextImageName;
\r
42 frames = new Vector(); // storage for animation frames and associated delays
\r
43 this.parent = parent; // needed for calls to Applet.getImage()
\r
45 if(bgColour != null)
\r
46 background = bgColour;
\r
48 background = Color.white;
\r
49 setBackground(background); // set button background to match parent (hopefully!!)
\r
51 // load the animation frames
\r
52 tracker = new MediaTracker(this);
\r
53 for(int i = 0; i < count; i++) {
\r
54 nextImageName = prefix + i + suffix; // build image name
\r
55 frames.add(new AnimationFrame(parent.getImage(imagebase, nextImageName), delays[i]));
\r
56 tracker.addImage(((AnimationFrame)frames.get(i)).getImage(), 0);
\r
58 nextFrame = 1; // initial values for 'shutter-type' animation
\r
61 suspended = false; // not suspended
\r
64 public void addFrame(java.awt.Image image, int delay) {
\r
65 frames.add(new AnimationFrame(image, delay));
\r
68 public synchronized void setSuspended(boolean pause) {
\r
73 public boolean isSuspended() {
\r
77 public void paint(java.awt.Graphics graphics) {
\r
78 java.awt.Dimension dim = getSize();
\r
79 graphics.setColor(background);
\r
80 graphics.fillRect(0,0,dim.width, dim.height);
\r
81 graphics.drawImage(((AnimationFrame)frames.get(nextFrame)).getImage(),0,0, this);
\r
84 public void animate() {
\r
86 nextFrame = ++lastFrame; // next frame
\r
88 lastFrame = nextFrame; // the one we just drew
\r
89 nextFrame = 0; // the 'shutter' frame
\r
91 if(lastFrame >= frames.size()) { // loop back to the first frame
\r
99 // no more frames, so ensure Vector has no empty slots, which means Vector.size() can be used to control the maximum frame index to use
\r
100 frames.trimToSize();
\r
102 try { // don't begin animating until all frames have been loaded
\r
103 tracker.waitForAll();
\r
104 } catch(InterruptedException e) { }
\r
106 if(tracker.isErrorAny()) System.out.println("AnimatedButton: Error loading images");
\r
108 // resize button to size of images
\r
109 int w = ((AnimationFrame)frames.get(nextFrame)).getImage().getWidth(this);
\r
110 int h = ((AnimationFrame)frames.get(nextFrame)).getImage().getHeight(this);
\r
113 // get this specific frame's delay now, BEFORE the frame index is updated in animate()
\r
114 sleep = ((AnimationFrame)frames.get(nextFrame)).getDelay();
\r
117 Thread.currentThread().sleep(sleep); // sleep now
\r
118 if(suspended) { // don't synchronize unless suspended - saves CPU time
\r
119 synchronized(this) {
\r
120 while(suspended) wait(); // suspended animation by external control
\r
123 } catch(InterruptedException e) {}
\r
125 } // keep looping until this Thread is stopped
\r
128 class AnimationFrame {
\r
129 private java.awt.Image image;
\r
130 private int delay; // milliseconds
\r
132 /** creates empty frame */
\r
133 public AnimationFrame() {
\r
138 /** creates complete frame */
\r
139 public AnimationFrame(Image image, int delay) {
\r
140 this.delay = delay;
\r
141 this.image = image;
\r
144 /** returns an Image */
\r
145 public java.awt.Image getImage() {
\r
149 public int getDelay() {
\r