Visual Color Imbalance Detector: Reconstructed project directories and files
[VistaCID.git] / org / tjworld / components / AnimatedButton.java
1 /*\r
2         * AnimatedButton.java\r
3  *\r
4         * Created on 06 October 2001, 19:17\r
5         * $Header: $\r
6         * \r
7         * $History: $\r
8 */\r
9 package org.tjworld.components;\r
10 \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
16 \r
17 /**\r
18         * A lightweight Swing-based animated button, that \r
19  *\r
20         * @author  TJ\r
21  * @version 1.0\r
22  */\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
30         \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
36                 suspended = true;\r
37         }\r
38         \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
44                 \r
45   if(bgColour != null)\r
46                 background = bgColour;  \r
47                 else\r
48                         background = Color.white;\r
49                 setBackground(background); // set button background to match parent (hopefully!!)\r
50                         \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
57                 }\r
58                 nextFrame = 1; // initial values for 'shutter-type' animation\r
59                 lastFrame = 0;\r
60                 \r
61                 suspended = false; // not suspended\r
62  }\r
63                         \r
64         public void addFrame(java.awt.Image image, int delay) {\r
65                 frames.add(new AnimationFrame(image, delay));   \r
66         }\r
67 \r
68         public synchronized void setSuspended(boolean pause) {\r
69                 suspended = pause;\r
70                 notify();\r
71         }\r
72         \r
73         public boolean isSuspended() {\r
74                 return suspended;\r
75         }\r
76         \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
82         }\r
83         \r
84         public void animate() {\r
85                 if(nextFrame == 0) \r
86                  nextFrame = ++lastFrame; // next frame\r
87                 else {\r
88                         lastFrame = nextFrame; // the one we just drew\r
89                         nextFrame = 0; // the 'shutter' frame\r
90                 }\r
91                 if(lastFrame >= frames.size()) { // loop back to the first frame\r
92                         nextFrame = 1;\r
93                         lastFrame = 0;\r
94                 }\r
95         }\r
96                                 \r
97         public void run() {\r
98                 int sleep;\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
101 \r
102                 try { // don't begin animating until all frames have been loaded\r
103                  tracker.waitForAll();\r
104                 } catch(InterruptedException e) { }\r
105                 \r
106                 if(tracker.isErrorAny()) System.out.println("AnimatedButton: Error loading images");\r
107                 \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
111                 setSize(w, h);\r
112                 while(true) {\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
115                         repaint();\r
116                         try {\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
121                                         }\r
122                                 }\r
123                         } catch(InterruptedException e) {}\r
124                         animate();\r
125                 } // keep looping until this Thread is stopped\r
126         }\r
127 \r
128         class AnimationFrame {\r
129                 private java.awt.Image image;\r
130                 private int delay; // milliseconds\r
131                 \r
132                 /** creates empty frame */\r
133                 public AnimationFrame() {\r
134                         image = null;\r
135                         delay = 0;\r
136                 }\r
137                 \r
138                 /** creates complete frame */\r
139                 public AnimationFrame(Image image, int delay) {\r
140                         this.delay = delay;\r
141                         this.image = image;\r
142                 }\r
143                 \r
144                 /** returns an Image */\r
145                 public java.awt.Image getImage() {\r
146                         return image;\r
147                 }\r
148                 \r
149                 public int getDelay() {\r
150                         return delay;\r
151                 }\r
152         }\r
153 }