001         package com.croftsoft.core.animation.animator;
002    
003         import java.awt.*;
004         import java.awt.geom.*;
005         import javax.swing.JComponent;
006    
007         import com.croftsoft.core.animation.ComponentAnimator;
008         import com.croftsoft.core.awt.font.FontLib;
009         import com.croftsoft.core.lang.NullArgumentException;
010         import com.croftsoft.core.math.MathConstants;
011    
012         /*********************************************************************
013         * Samples and displays the frame rate.
014         *
015         * @version
016         *   2003-07-07
017         * @since
018         *   2003-02-07
019         * @author
020         *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
021         *********************************************************************/
022    
023         public final class  FrameRateAnimator
024           implements ComponentAnimator
025         //////////////////////////////////////////////////////////////////////
026         //////////////////////////////////////////////////////////////////////
027         {
028    
029         private static final long  SAMPLE_PERIOD_IN_MILLIS
030           = 10 * MathConstants.MILLISECONDS_PER_SECOND;
031    
032         private static final int   MAX_FRAME_RATE = 99999;
033    
034         //
035    
036         private final Color      color;
037    
038         private final Font       font;
039    
040         private final Rectangle  repaintBounds;
041    
042         private final float      x;
043    
044         private final float      y;
045    
046         //
047    
048         private boolean  disabled;
049    
050         private boolean  oldDisabled;
051    
052         private long     frameCount;
053    
054         private long     lastUpdateTime;
055    
056         private double   frameRate;
057    
058         private String   frameRateString;
059    
060         //////////////////////////////////////////////////////////////////////
061         //////////////////////////////////////////////////////////////////////
062    
063         public  FrameRateAnimator (
064           Color        color,
065           Font         font,
066           Rectangle2D  textLayoutBounds )
067         //////////////////////////////////////////////////////////////////////
068         {
069           NullArgumentException.check ( this.color = color );
070    
071           NullArgumentException.check ( this.font  = font  );
072    
073           NullArgumentException.check ( textLayoutBounds );
074    
075           x = ( float ) textLayoutBounds.getX ( );
076    
077           y = ( float ) -textLayoutBounds.getY ( );
078    
079           repaintBounds = textLayoutBounds.getBounds ( );
080    
081           repaintBounds.y = 0;
082    
083           frameRateString = "?????";
084         }
085    
086         public  FrameRateAnimator (
087           Component  component,
088           Color      color )
089         //////////////////////////////////////////////////////////////////////
090         {
091           this (
092             color,
093             component.getFont ( ),
094             FontLib.getTextLayoutBounds (
095               component, Integer.toString ( MAX_FRAME_RATE ) ) );
096         }
097    
098         public  FrameRateAnimator ( Component  component )
099         //////////////////////////////////////////////////////////////////////
100         {
101           this ( component, component.getForeground ( ) );
102         }
103    
104         //////////////////////////////////////////////////////////////////////
105         //////////////////////////////////////////////////////////////////////
106    
107         public void  update ( JComponent  component )
108         //////////////////////////////////////////////////////////////////////
109         {
110           if ( oldDisabled != disabled )
111           {
112             component.repaint ( );
113    
114             oldDisabled = disabled;
115           }
116    
117           if ( disabled )
118           {
119             return;
120           }
121    
122           long  updateTime = System.currentTimeMillis ( );
123    
124           frameCount++;
125    
126           long  timeDelta = updateTime - lastUpdateTime;
127    
128           if ( timeDelta < SAMPLE_PERIOD_IN_MILLIS )
129           {
130             return;
131           }
132    
133           frameRate = frameCount * MathConstants.MILLISECONDS_PER_SECOND
134             / ( double ) timeDelta;
135    
136           if ( frameRate > MAX_FRAME_RATE )
137           {
138             frameRateString = ">>>>>";
139           }
140           else
141           {
142             frameRateString = Long.toString ( Math.round ( frameRate ) );
143           }
144    
145           frameCount = 0;
146    
147           lastUpdateTime = updateTime;
148    
149           component.repaint ( repaintBounds );
150         }
151    
152         public void  paint (
153           JComponent  component,
154           Graphics2D  graphics )
155         //////////////////////////////////////////////////////////////////////
156         {
157           if ( disabled )
158           {
159             return;
160           }
161    
162           graphics.setColor ( color );
163    
164           graphics.setFont ( font );
165    
166           graphics.drawString ( frameRateString, x, y );
167         }
168    
169         //////////////////////////////////////////////////////////////////////
170         //////////////////////////////////////////////////////////////////////
171    
172         public double  getFrameRate ( )
173         //////////////////////////////////////////////////////////////////////
174         {
175           return frameRate;
176         }
177    
178         public void  toggle ( )
179         //////////////////////////////////////////////////////////////////////
180         {
181           disabled = !disabled;
182         }
183    
184         //////////////////////////////////////////////////////////////////////
185         //////////////////////////////////////////////////////////////////////
186         }