KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > snow > utils > gui > AnimatedColorPanel


1 package snow.utils.gui;
2 import java.awt.*;
3 import java.awt.event.*;
4 import java.awt.image.*;
5 import java.beans.*;
6
7 import javax.swing.*;
8 import javax.swing.plaf.*;
9 import javax.swing.border.*;
10 import javax.swing.plaf.metal.*;
11
12 /**
13 * A panel, which [slowly] animates its background colors, but with only consuming neglectable cpu time.
14 *
15 * It has a constant height of labelfont/2 and can be displayed somewhere on the bottom of another panel.
16 *
17 * Note, that one must start/end the animation manually by by a call to activateAnimation().
18 * One can use a ComponentListener attached to a toplevel container for this purpose.
19 *
20 * One can use it for busy info messages. The animation
21 * attracts the users attention, so one knows what's going on.
22 */

23 public class AnimatedColorPanel extends JPanel
24 {
25
26   private ActivatedColorThread activatedColorThread = null;
27   // The thread, which runs in the selected state.
28

29   //public AnimatedColorPanel thisPanel;
30
private boolean allIsReadyForSpecialUpdates;
31   private Paint paint; // used in activated state
32
private float gradientLength = 40;
33
34   private long delayTime = 100;
35
36  /**
37   * This one creates a panel with BoxLayout consisting
38   * of a vertical strut, which keeps the height on the
39   * label font size.
40   *
41   * delayTime in millisec is the time between animation updates.
42   * It should be bigger than 99 millisecs and controls the cpu load.
43   */

44   public AnimatedColorPanel( long delayTime )
45   {
46     super();
47     this.delayTime = delayTime;
48     if( this.delayTime < 44 ) this.delayTime = 44; // be nice to other threads
49
int panelHeight = 2+UIManager.getFont("Label.font").getSize()/2;
50     BoxLayout boxLayout = new BoxLayout( this,BoxLayout.Y_AXIS );
51     this.setLayout( boxLayout );
52     this.add( Box.createVerticalStrut(panelHeight) );
53     //this.setOpaque(false); // enables us to see the background paint
54
//this.thisPanel = this;
55
this.paint = this.getBackground(); // initially
56
EventQueue.invokeLater(new Runnable JavaDoc()
57      {
58        public void run()
59        {
60          allIsReadyForSpecialUpdates = true;
61        }
62      });
63     this.updateSpecialUI(); // one time for initializing
64
} // Constructor
65

66
67
68
69  /**
70   * This one requires a LayoutManager and doesn't and
71   * the geometry must be handles by the caller.
72   *
73   * delayTime in millisec is the time between animation updates.
74   * It should be bigger than 99 millisecs and controls the cpu load.
75   *
76   */

77   public AnimatedColorPanel( LayoutManager layoutManager,
78                              long delayTime )
79   {
80     super();
81     this.delayTime = delayTime;
82     if( this.delayTime < 44 ) this.delayTime = 44; // be nice to other threads
83
this.setLayout( layoutManager );
84     //this.setOpaque(false); // enables us to see the background paint
85
// this.thisPanel = this;
86
EventQueue.invokeLater(new Runnable JavaDoc()
87      {
88        public void run()
89        {
90          allIsReadyForSpecialUpdates = true;
91        }
92      });
93     this.updateSpecialUI(); // one time for initializing
94
} // Constructor
95

96
97
98
99
100
101
102  /**
103   * This must be called manually for starting/ending
104   * the animation.
105   * One can use a component listener (on a toplevel container)
106   * for this purpose.
107   */

108   public synchronized void activateAnimation( boolean doActivate )
109   {
110     if( doActivate )
111      {
112        if( this.activatedColorThread == null )
113         {
114           this.paint = this.getBackground(); // initially
115
this.gradientLength = this.getWidth()/2f;
116           this.activatedColorThread = new ActivatedColorThread( this );
117           activatedColorThread.setDaemon(true);
118           this.activatedColorThread.start();
119         }
120      }
121     else
122      {
123        if( this.activatedColorThread != null )
124         {
125           this.activatedColorThread.doTerminate();
126           this.activatedColorThread = null;
127           this.paint = this.getBackground(); // initially
128
this.repaint();
129         }
130      }
131   }
132
133
134  /**
135   * Just calls <code>paint(g)</code>. This method was overridden to
136   * prevent an unnecessary call to clear the background.
137   *
138   * @param g the Graphics context in which to paint
139   */

140   public void update(Graphics g)
141   {
142     this.paint(g);
143   }
144
145
146  /**
147   * Process additional update-work, after having called
148   * the parent method.
149   */

150   public void updateUI()
151   {
152     super.updateUI();
153     // additional updates :
154
if( this.allIsReadyForSpecialUpdates )
155      {
156        updateSpecialUI();
157      }
158   }
159
160
161
162   public void updateSpecialUI()
163   {
164     // Check if we have an efcn theme :
165
//this.setForeground( UIManager.getColor("Label.foreground") );
166
//this.setBackground( UIManager.getColor("Label.background") );
167
} // updateSpecialUI
168

169
170
171
172
173   public void paintComponent( final Graphics g )
174   {
175     super.paintComponent(g);
176     if(!this.isOpaque())
177     {
178        return;
179     }
180
181     final Graphics2D graphics2D = (Graphics2D)g;
182     if( this.paint != null )
183     {
184        Rectangle rec = this.getVisibleRect();
185        graphics2D.setPaint(this.paint);
186        graphics2D.fill( rec );
187     }
188     else
189     {
190        this.paint = this.getBackground(); // initially
191
}
192
193   }
194
195
196   public Color slightlyBrighter( final Color color )
197   {
198     int r = color.getRed() + 32; if( r > 255 ) r = 255;
199     int g = color.getGreen() + 32; if( g > 255 ) g = 255;
200     int b = color.getBlue() + 32; if( b > 255 ) b = 255;
201     return new Color( r,g,b );
202   } // slightlyBrighter
203

204
205
206   public Color slightlyDarker( final Color color )
207   {
208     int r = color.getRed() - 32; if( r < 0 ) r = 0;
209     int g = color.getGreen() - 32; if( g < 0 ) g = 0;
210     int b = color.getBlue() - 32; if( b < 0 ) b = 0;
211     return new Color( r,g,b );
212   } // slightlyBrighter
213

214
215
216   private void setPaint( final Paint newPaint )
217   {
218      if( newPaint != null )
219      {
220         this.paint = newPaint;
221         //this.setBackground(Color.red);
222
}
223      this.repaint();
224   }
225
226
227
228
229
230
231  /**
232   * This thread performs the animated color change while the
233   * button is activated.
234   */

235   private class ActivatedColorThread extends Thread JavaDoc
236   {
237 // private Color brightColor;
238
private Color darkColor;
239      private boolean terminateThread = false;
240      private JPanel parentPanel;
241
242
243      public ActivatedColorThread( JPanel thePanel )
244      {
245        this.parentPanel = thePanel;
246        this.setDaemon(true); // let it terminate, when the JVM shuts down
247

248        this.setPriority( Thread.NORM_PRIORITY-1 );
249        // This f.ex. has an effect on the compiling times, where it
250
// is used for the compile info label : It can make the
251
// compile times shorter.
252

253        // Give other threads more attention:
254
this.setPriority( Thread.MIN_PRIORITY );
255 // this.brightColor = this.parentPanel.getBackground().brighter().brighter();
256
this.darkColor = this.parentPanel.getBackground().darker().darker();
257      } // Constructor
258

259
260      public void run()
261      {
262        int maximumLocation = 0;
263        int maximumLocationStep = 5;
264
265        int colorOffset = 0;
266        int colorOffsetStep = 2;
267
268        // Take the 2:1 average of background and foreground color :
269
Color bg = getBackground();
270        Color fg = getForeground();
271        final int rBasis = ( 2*bg.getRed() + fg.getRed() ) / 3;
272        final int gBasis = ( 2*bg.getGreen() + fg.getGreen() ) / 3;
273        final int bBasis = ( 2*bg.getBlue() + fg.getBlue() ) / 3;
274        final Color basisColor = new Color( rBasis, gBasis, bBasis );
275
276        while( !this.terminateThread )
277         {
278            int shiftLength = 2*this.parentPanel.getWidth();
279            // turn direction at borders :
280
if( maximumLocation > shiftLength )
281             {
282               maximumLocationStep = -6;
283             }
284            if( maximumLocation < 6 )
285             {
286               maximumLocationStep = +6;
287             }
288            maximumLocation += maximumLocationStep;
289            // make the color change effect medium ( +- 60 ) :
290
if( colorOffset > 150 )
291             {
292               colorOffsetStep = -4;
293             }
294            if( colorOffset < -150 )
295             {
296               colorOffsetStep = +4;
297             }
298            colorOffset += colorOffsetStep;
299
300            int c_Red = basisColor.getRed() + colorOffset; if( c_Red > 255 ) c_Red = 255; if( c_Red < 0 ) c_Red = 0;
301            int c_Green = basisColor.getGreen() - colorOffset; if( c_Green > 255 ) c_Green = 255; if( c_Green < 0 ) c_Green = 0;
302            int c_Blue = basisColor.getBlue() + colorOffset; if( c_Blue > 255 ) c_Blue = 255; if( c_Blue < 0 ) c_Blue = 0;
303
304            final int cRed = c_Red;
305            final int cGreen = c_Green;
306            final int cBlue = c_Blue;
307            final int currentLocation = maximumLocation;
308
309            // Don't paint, if the parentPanel is not showing or not visible :
310
if( this.parentPanel.isShowing() && this.parentPanel.isVisible() )
311             {
312               EventQueue.invokeLater( new Runnable JavaDoc()
313                {
314                  public void run()
315                  {
316                     if( !terminateThread )
317                     {
318                       synchronized(AnimatedColorPanel.this)
319                       {
320                        Color secondColor = new Color(cRed,cGreen,cBlue);
321                        Color firstColor = encreaseContrast( getBackground(),secondColor );
322                        final GradientPaint gradientPaint =
323                              new GradientPaint( 2f*currentLocation,0f,
324                                                 firstColor,
325                                                 2f*currentLocation + gradientLength,0f,
326                                                 secondColor,
327                                                 true /* cyclic */ );
328                        if( gradientPaint != null)
329                        {
330                           setPaint( gradientPaint );
331                        }
332                       }
333                     }
334                  }
335                });
336             }
337            try{ Thread.sleep(delayTime); } catch(Exception JavaDoc wurscht ){ wurscht.printStackTrace(); }
338         } // thread while loop
339
} // run
340

341
342
343
344
345      public void doTerminate()
346      {
347        this.terminateThread = true;
348      }
349
350
351      public Color encreaseContrast( Color basisColor, Color checkColor )
352      {
353        int basisValue = basisColor.getRed() + basisColor.getGreen() + basisColor.getBlue();
354        int checkValue = checkColor.getRed() + checkColor.getGreen() + checkColor.getBlue();
355        int r = 0;
356        int g = 0;
357        int b = 0;
358        int offset = 64;
359        if( basisValue > checkValue )
360         {
361           r = basisColor.getRed() + offset; if( r > 255 ) r = 255;
362           g = basisColor.getGreen() + offset; if( g > 255 ) g = 255;
363           b = basisColor.getBlue() + offset; if( b > 255 ) b = 255;
364         }
365        else
366         {
367           r = basisColor.getRed() - offset; if( r < 0 ) r = 0;
368           g = basisColor.getGreen() - offset; if( g < 0 ) g = 0;
369           b = basisColor.getBlue() - offset; if( b < 0 ) b = 0;
370         }
371        return new Color(r,g,b);
372      } // encreaseContrast
373

374
375   } // class ActivatedColorThread
376

377
378
379
380
381
382 } // AnimatedColorPanel
Popular Tags