001         package com.croftsoft.core.animation.painter;
002    
003         import java.awt.Color;
004         import java.awt.Graphics;
005         import java.awt.Graphics2D;
006         import java.awt.Image;
007         import java.awt.Rectangle;
008         import java.util.Random;
009         import javax.swing.JComponent;
010    
011         import com.croftsoft.core.lang.NullArgumentException;
012         import com.croftsoft.core.animation.ComponentPainter;
013    
014         /*********************************************************************
015         * Fills an area of the component with stars against black space.
016         *
017         * @version
018         *   2003-07-05
019         * @since
020         *   2002-03-28
021         * @author
022         *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
023         *********************************************************************/
024    
025         public final class  SpacePainter
026           implements ComponentPainter
027         //////////////////////////////////////////////////////////////////////
028         //////////////////////////////////////////////////////////////////////
029         {
030    
031         private static final double  DEFAULT_STAR_DENSITY = 0.01;
032    
033         //
034    
035         /** Probability of a star at any given pixel. */
036         private final double  starDensity;
037    
038         private final Random  random;
039    
040         private final long    seed;
041    
042         //
043    
044         private Rectangle  paintArea;
045    
046         private boolean    useComponentBounds;
047    
048         private Image      image;
049    
050         private int        width;
051    
052         private int        height;
053    
054         //////////////////////////////////////////////////////////////////////
055         //////////////////////////////////////////////////////////////////////
056    
057         /*********************************************************************
058         * Main constructor method.
059         *
060         * @param  paintArea
061         *
062         *    If null, component.getBounds() will be used.
063         *********************************************************************/
064         public  SpacePainter (
065           Rectangle  paintArea,
066           double     starDensity )
067         //////////////////////////////////////////////////////////////////////
068         {
069           setPaintArea ( paintArea );
070    
071           this.starDensity = starDensity;
072    
073           random = new Random ( );
074    
075           seed = random.nextLong ( );
076         }
077    
078         /*********************************************************************
079         * Convenience constructor method.
080         *********************************************************************/
081         public  SpacePainter ( )
082         //////////////////////////////////////////////////////////////////////
083         {
084           this ( null, DEFAULT_STAR_DENSITY );
085         }
086    
087         //////////////////////////////////////////////////////////////////////
088         // mutator methods
089         //////////////////////////////////////////////////////////////////////
090    
091         /*********************************************************************
092         * @param  paintArea
093         *
094         *    If null, component.getBounds() will be used.
095         *********************************************************************/
096         public void  setPaintArea ( Rectangle  paintArea )
097         //////////////////////////////////////////////////////////////////////
098         {
099           useComponentBounds = ( paintArea == null );
100    
101           if ( useComponentBounds )
102           {
103             this.paintArea = new Rectangle ( );
104           }
105         }
106    
107         //////////////////////////////////////////////////////////////////////
108         //////////////////////////////////////////////////////////////////////
109    
110         public void  paint (
111           JComponent  component,
112           Graphics2D  graphics )
113         //////////////////////////////////////////////////////////////////////
114         {
115           if ( useComponentBounds )
116           {
117             component.getBounds ( paintArea );
118    
119             if ( ( width  != paintArea.width  )
120               || ( height != paintArea.height ) )
121             {
122               if ( image != null )
123               {
124                 image.flush ( );
125    
126                 image = null;
127               }
128             }
129           }
130    
131           if ( image == null )
132           {
133             width  = paintArea.width;
134    
135             height = paintArea.height;
136    
137             createImage ( component );
138           }
139    
140           graphics.drawImage ( image, paintArea.x, paintArea.y, null );
141         }
142    
143         //////////////////////////////////////////////////////////////////////
144         //////////////////////////////////////////////////////////////////////
145    
146         private void  createImage ( JComponent  component )
147         //////////////////////////////////////////////////////////////////////
148         {
149           image = component.createImage ( width, height );
150    
151           Graphics  graphics = image.getGraphics ( );
152           
153           graphics.setColor ( Color.BLACK );
154    
155           graphics.fillRect ( 0, 0, width, height );
156    
157           random.setSeed ( seed );
158    
159           graphics.setColor ( Color.WHITE );
160    
161           for ( int  x = 0; x < width; x++ )
162           {
163             for ( int  y = 0; y < height; y++ )
164             {
165               if ( random.nextDouble ( ) <= starDensity )
166               {
167                 graphics.fillOval ( x, y, 1, 1 );
168               }
169             }
170           }
171         }
172    
173         //////////////////////////////////////////////////////////////////////
174         //////////////////////////////////////////////////////////////////////
175         }