KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > snow > lookandfeel > CustomOceanImagePanel


1 package snow.lookandfeel;
2
3   /**
4    * A panel used as background for panels.
5    * Has some gradient and other drawing stuff on it.
6    *
7    * Note: You have to call setOpaque(false) for all
8    * swing objects, which you add to this panel,
9    * otherwise you wont see the panel color gradient.
10    */

11
12
13 import javax.swing.*;
14 import javax.swing.border.*;
15 import javax.swing.event.*;
16 import java.awt.*;
17 import java.io.*;
18 import java.util.*;
19 import java.awt.event.*;
20 import java.beans.*;
21 import javax.swing.plaf.metal.*;
22
23
24
25 public final class CustomOceanImagePanel extends JPanel
26 {
27
28   // The gradient types :
29
public static final int ApplyUpperLeftCornerHighLight = 0;
30   public static final int ApplyVerticalHighLight = 1;
31
32   // Some predefined color keystrings :
33
public static final String JavaDoc ActiveTitleBackground = "InternalFrame.activeTitleBackground";
34   public static final String JavaDoc PanelBackground = "Panel.background";
35
36
37   // The gradient strength :
38
public static final int LightGradientStrength = 0;
39   public static final int MediumGradientStrength = 1;
40   public static final int StrongGradientStrength = 2;
41
42   private static final int AlfaColorStrength = 224;
43   // The lower this value, the more the backgroundpicture comes visible.
44

45
46   private Color lightColor = new Color(190,190,250);
47   private Color mediumColor = new Color(120,120,180);
48   private Color darkColor = new Color(80,80,120);
49   float xGradient;
50
51   private Color basisColor; // around this the gradient will be
52

53   // gradient look : (defaults)
54
private int gradientType = ApplyUpperLeftCornerHighLight;
55   private int gradientStrength = MediumGradientStrength;
56   private String JavaDoc colorKey = ActiveTitleBackground;
57
58   float gradientLength;
59
60
61   private int finalColorOffset;
62   private int colorOffset;
63
64
65   private boolean useParentBackGround = false; // when a background color has been assigned
66

67   private ImageIcon backgroundImage = null;
68   // This is set according to the current theme, and changes,
69
// when the theme changes.
70

71   private ImageIcon customBackgroundImage = null;
72   // This can be set by using one of the constructors.
73
// If this is set, this backgroundimage is used always,
74
// and not the one associated to the current theme.
75

76
77   private boolean introThreadHasBeenStarted = false;
78
79
80   private boolean allIsReadyForSpecialUpdates = false;
81   // This flag is needed, because the updateUI() method sometimes
82
// is initially called, when some referenced UIManager
83
// functionality is not available yet. DO NOT REMOVE THIS.
84

85
86  /**
87   * Creates a panel where you can pass
88   * theGradientType = ApplyUpperLeftCornerHighLight
89   * or ApplyVerticalHighLight
90   *
91   * and
92   * theGradientStrength = LightGradientStrength
93   * or MediumGradientStrength
94   * or StrongGradientStrength
95   *
96   * and
97   * theColorKey = null
98   * or ActiveTitleBackground
99   * or PanelBackground
100   * or any valid theme colorkey.
101   *
102   */

103   public CustomOceanImagePanel( final int theGradientType,
104                                 final int theGradientStrength,
105                                 final String JavaDoc theColorKey )
106   {
107     this( new BorderLayout(),true,theGradientType,theGradientStrength,theColorKey );
108   }
109
110
111   public CustomOceanImagePanel( )
112   {
113     this( new BorderLayout(), true, ApplyUpperLeftCornerHighLight, LightGradientStrength, PanelBackground );
114   }
115
116
117  /**
118   * Creates a panel where you can pass
119   * theGradientType = ApplyUpperLeftCornerHighLight
120   * or ApplyVerticalHighLight
121   *
122   * and
123   * theGradientStrength = LightGradientStrength
124   * or MediumGradientStrength
125   * or StrongGradientStrength
126   *
127   * and
128   * theColorKey = null
129   * or ActiveTitleBackground
130   * or PanelBackground
131   * or any valid theme colorkey.
132   *
133   */

134   public CustomOceanImagePanel( LayoutManager layout,
135                             int theGradientType,
136                             int theGradientStrength,
137                             String JavaDoc theColorKey )
138   {
139     this(layout, true, theGradientType, theGradientStrength, theColorKey);
140   }
141
142
143
144
145  /**
146   * Creates a panel where you can pass
147   * theGradientType = ApplyUpperLeftCornerHighLight
148   * or ApplyVerticalHighLight
149   *
150   * and
151   * theGradientStrength = LightGradientStrength
152   * or MediumGradientStrength
153   * or StrongGradientStrength
154   *
155   * and
156   * theColorKey = null
157   * or ActiveTitleBackground
158   * or PanelBackground
159   * or any valid theme colorkey.
160   *
161   */

162   public CustomOceanImagePanel( LayoutManager layout,
163                             boolean isDoubleBuffered,
164                             int theGradientType,
165                             int theGradientStrength,
166                             String JavaDoc theColorKey )
167   {
168     super(layout,isDoubleBuffered);
169     this.gradientType = theGradientType;
170     this.gradientStrength = theGradientStrength;
171     this.updateSpecialUI(); // sets basisColor, startColor and endColor
172
if( colorKey != null )
173      {
174        this.colorKey = theColorKey;
175      } // else use the default
176
// scale the gradient along with the current font size :
177
float unitSize1 = UIManager.getFont("TextField.font").getSize2D();
178     this.xGradient = unitSize1;
179
180     this.colorOffset = this.getFinalColorOffset()/16;
181                        // This will increased to the value of
182
// finalColorOffset in a few steps by the
183
// startupThread.
184

185     this.finalColorOffset = 70; // medium gradient strength
186
if( this.gradientStrength == LightGradientStrength )
187      {
188        this.finalColorOffset = 40;
189      }
190     if( this.gradientStrength == StrongGradientStrength )
191      {
192        this.finalColorOffset = 90;
193      }
194
195
196
197     EventQueue.invokeLater(new Runnable JavaDoc()
198      {
199        public void run()
200        {
201          allIsReadyForSpecialUpdates = true;
202        }
203      });
204
205   } // Constructor
206

207
208
209
210
211  /**
212   * This last constructor additionally defines a custom background
213   * picture. If this constructor is used, the passed backround
214   * picture will be used for ever, instead of getting or changing
215   * the background picture with the theme.
216   */

217   public CustomOceanImagePanel( LayoutManager layout,
218                             int theGradientType,
219                             int theGradientStrength,
220                             String JavaDoc theColorKey,
221                             ImageIcon customBackgroundImage )
222   {
223     this( layout,theGradientType,theGradientStrength,theColorKey);
224     this.customBackgroundImage = customBackgroundImage;
225   }
226
227
228
229  /**
230   * Process additional update-work, after having called
231   * the parent method.
232   */

233   public void updateUI()
234   {
235     super.updateUI();
236     if( this.allIsReadyForSpecialUpdates )
237      {
238       // additional update work :
239
updateSpecialUI();
240       // rescale the gradient along with the current font size :
241
float unitSize2 = UIManager.getFont("TextField.font").getSize2D();
242       xGradient = unitSize2;
243      }
244   }
245
246
247
248
249  /**
250   * Seta a fixed background color, and with that : turns out the
251   * UIManager update mechanism.
252   */

253   public void setBackground( Color bgColor )
254   {
255     super.setBackground(bgColor);
256     this.useParentBackGround = true; // turns off UIManager special update
257
this.basisColor = super.getBackground();
258     this.calculateColors();
259   }
260
261
262
263  /**
264   * Calculate the start and endcolor of the gradient
265   * taking the basisColor as center color :
266   */

267   private void calculateColors()
268   {
269     int rBase = this.basisColor.getRed();
270     int gBase = this.basisColor.getGreen();
271     int bBase = this.basisColor.getBlue();
272     // start color is lighter :
273
int rStart = rBase + colorOffset;
274     int gStart = gBase + colorOffset;
275     int bStart = bBase + colorOffset;
276     if( (rStart <= 255) && (gStart <= 255) && (bStart <= 255) )
277      {
278        this.lightColor = new Color( rStart,gStart,bStart );
279      } else
280      {
281        if( rStart > 255 ) rStart = 255;
282        if( gStart > 255 ) gStart = 255;
283        if( bStart > 255 ) bStart = 255;
284        this.lightColor = new Color( rStart,gStart,bStart );
285      }
286
287     this.mediumColor = this.basisColor;
288
289     rStart = rBase - colorOffset;
290     gStart = gBase - colorOffset;
291     bStart = bBase - colorOffset;
292     if( (rStart >= 0) && (gStart >= 0) && (bStart >= 0) )
293      {
294        this.darkColor = new Color( rStart,gStart,bStart );
295      } else
296      {
297        if( rStart < 0 ) rStart = 0;
298        if( gStart < 0 ) gStart = 0;
299        if( bStart < 0 ) bStart = 0;
300        this.darkColor = new Color( rStart,gStart,bStart );
301      }
302
303     // If the current panel has a background image, we use this one and
304
// set the medium color slightly transparent :
305
// The background image is valid, when there is a theme with background
306
// image OR when a custom backgroundimage was set :
307
if( this.customBackgroundImage != null )
308      {
309         // A custom image was set, so set the color a bit transparent :
310
this.mediumColor = new Color( mediumColor.getRed(),
311                                        mediumColor.getGreen(),
312                                        mediumColor.getBlue(),
313                                        AlfaColorStrength );
314         // and use this one :
315
this.backgroundImage = this.customBackgroundImage;
316      }
317     else
318     {
319       CustomOceanTheme cot = ThemesManager.getInstance().getSelectedTheme();
320       if( cot != null )
321       {
322             this.backgroundImage = cot.getBackgroundImage();
323             if( this.backgroundImage != null )
324             {
325               this.mediumColor = new Color( mediumColor.getRed(),
326                                              mediumColor.getGreen(),
327                                              mediumColor.getBlue(),
328                                              AlfaColorStrength );
329             }
330
331       }
332     }
333   } // calculateColors
334

335
336
337
338
339
340  /**
341   * Must be called, when the lf theme changes.
342   * Called by the propertychange listener above.
343   */

344   public void updateSpecialUI()
345   {
346     // set it as basis :
347
this.basisColor = UIManager.getColor(this.colorKey);
348     // Calculate the start and endColors from that :
349
this.calculateColors();
350   }
351
352
353  /**
354   * Overwritten paint method to have a slight color gradient.
355   */

356   public void paint( Graphics g )
357   {
358     Graphics2D graphics2D = (Graphics2D)g;
359     final Paint savePaint = graphics2D.getPaint();
360
361     // draw the background image, if we have one :
362
if( this.backgroundImage != null )
363     {
364       int xMax = this.getWidth();
365       int yMax = this.getHeight();
366       int imageWidth = this.backgroundImage.getIconWidth();
367       int imageHeight = this.backgroundImage.getIconHeight();
368
369       // Security [prevents endless loop, case an attribute is zero]
370
if( (xMax > 0) &&
371           (yMax > 0) &&
372           (imageWidth > 0) &&
373           (imageHeight > 0) )
374       {
375           int x = 0;
376           int y = 0;
377           while( x < xMax )
378           {
379              while( y < yMax )
380              {
381                 //Icon ic = this.backgroundImage;
382
//ic.paintIcon(this, graphics2D,x,y);
383
graphics2D.drawImage( backgroundImage.getImage(),x,y,imageWidth,imageHeight,
384                               backgroundImage.getImageObserver() );
385 // System.out.println("Paint at "+x+", "+y);
386
y += imageHeight;
387              } // while y
388
y = 0;
389              x += imageWidth;
390           } // while x
391
} // if
392
} // if
393

394     if( this.gradientType == ApplyUpperLeftCornerHighLight )
395     {
396       GradientPaint upperLeftGradientPaint =
397                     new GradientPaint( 0f,0f,
398                                        lightColor,
399                                        xGradient,xGradient*5.0f,
400                                        mediumColor );
401
402       graphics2D.setPaint( upperLeftGradientPaint );
403       graphics2D.fill( graphics2D.getClip() );
404     }
405     else if( this.gradientType == ApplyVerticalHighLight )
406     {
407
408       this.gradientLength = xGradient;
409       if( gradientLength > this.getHeight()/2.5f )
410       {
411          gradientLength = this.getHeight()/2.5f;
412       }
413       GradientPaint upperVerticalGradientPaint =
414                     new GradientPaint( 0f,0f,
415                                        this.lightColor,
416                                        0f, gradientLength,
417                                        this.mediumColor );
418
419       GradientPaint lowerVerticalGradientPaint =
420                     new GradientPaint( 0f,getHeight(),
421                                        this.darkColor,
422                                        0f,getHeight() - gradientLength,
423                                        this.mediumColor );
424
425       Shape saveClip = graphics2D.getClip();
426
427       Rectangle rLower = new Rectangle( 0,getHeight()/2,getWidth(),1+getHeight()/2 );
428       graphics2D.setPaint( lowerVerticalGradientPaint );
429       graphics2D.fill( rLower );
430
431       Rectangle rUpper = new Rectangle( 0,0,getWidth(),1+getHeight()/2 );
432       graphics2D.setPaint( upperVerticalGradientPaint );
433       graphics2D.fill( rUpper );
434
435       graphics2D.setClip(saveClip);
436     }
437     graphics2D.setPaint( savePaint );
438     super.paintChildren(graphics2D);
439
440     if( !introThreadHasBeenStarted )
441     {
442        introThreadHasBeenStarted = true;
443        this.startIntroThread();
444     }
445   } // paint
446

447
448
449
450  /**
451   * Overwitten, so it doesnt clear all, but
452   * one has to call super, so children are properly rendered.
453   */

454   public void update( Graphics g )
455   {
456     //super.update(g);
457
paint(g);
458   }
459
460
461   public float getGradientLength()
462   {
463     return this.gradientLength;
464   }
465
466
467
468
469
470  /**
471   * Changes the color offset. Must be called inside
472   * the event dispatch thread.
473   */

474   public void setColorOffset( int newValue )
475   {
476     this.colorOffset = newValue;
477     this.calculateColors();
478     if( this.isShowing() && this.isVisible() )
479      {
480        this.updateUI();
481      } else
482      {
483        this.revalidate();
484      }
485   }
486
487
488   private void startIntroThread()
489   {
490     // Launch the startupthread, which will increase the coloroffset :
491
final StartupThread startupThread = new StartupThread(this);
492     // but launch him after all swing work has been done -
493
// so set it into the swing queue :
494
SwingUtilities.invokeLater( new Runnable JavaDoc()
495      {
496        public void run()
497        {
498          startupThread.start();
499        }
500      });
501   }
502
503
504
505   public int getFinalColorOffset()
506   {
507     return this.finalColorOffset;
508   }
509
510
511
512
513
514  /**
515   * The startup thread, which makes this panel shape itself
516   * in the first 3 seconds of its lifetime
517   */

518   private class StartupThread extends Thread JavaDoc
519   {
520      private CustomOceanImagePanel bgPanel;
521
522      public StartupThread( CustomOceanImagePanel bgPanel )
523      {
524        this.bgPanel = bgPanel;
525        this.setDaemon(true);
526      }
527
528      public void run()
529      {
530        // wait half a second initially - increses the effect :
531
try
532         {
533           Thread.sleep(200);
534         }
535        catch( Exception JavaDoc sdfkjh )
536         {
537         }
538        int loops = 16;
539        int offsetStep = bgPanel.getFinalColorOffset()/loops;
540        for( int i=1; i <= loops; i++ )
541         {
542            try{ Thread.sleep(90); } catch(Exception JavaDoc wurscht ){}
543            final int colorOffset = i*offsetStep;
544            SwingUtilities.invokeLater( new Runnable JavaDoc()
545             {
546               public void run()
547               {
548                 bgPanel.setColorOffset(colorOffset);
549               }
550             });
551            try{ Thread.yield(); } catch(Exception JavaDoc wurscht ){}
552         }
553      }
554
555   } // class StartupThread
556

557
558
559
560
561 } // CustomOceanImagePanel
Popular Tags