001         package com.croftsoft.core.animation.updater;
002    
003         import java.awt.*;
004         import java.awt.event.*;
005         import javax.swing.*;
006    
007         import com.croftsoft.core.animation.ComponentUpdater;
008    
009         /*********************************************************************
010         * Scrolls the view when the mouse is on the edges.
011         *
012         * @version
013         *   2003-07-05
014         * @since
015         *   2003-03-08
016         * @author
017         *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
018         *********************************************************************/
019    
020         public final class  EdgeScrollUpdater
021           implements ComponentUpdater
022         //////////////////////////////////////////////////////////////////////
023         //////////////////////////////////////////////////////////////////////
024         {
025    
026         private final static int  DEFAULT_SCROLL_RATE = 1;
027    
028         private final static int  EDGE_SIZE_DIVIDER   = 10;
029    
030         //
031    
032         private final int        width;
033    
034         private final int        height;
035    
036         private final Dimension  edgeSize;
037    
038         private final Rectangle  bounds;
039    
040         private final int        scrollRate;
041    
042         private final boolean    wrapAround;
043    
044         //
045    
046         private Point  mousePoint;
047    
048         private int    translateX;
049    
050         private int    translateY;
051    
052         //////////////////////////////////////////////////////////////////////
053         //////////////////////////////////////////////////////////////////////
054    
055         public  EdgeScrollUpdater (
056           JComponent  component,
057           int         width,
058           int         height,
059           Dimension   edgeSize,
060           int         scrollRate,
061           boolean     wrapAround )
062         //////////////////////////////////////////////////////////////////////
063         {
064           this.width    = width;
065    
066           this.height   = height;
067    
068           this.edgeSize = edgeSize;
069    
070           if ( scrollRate < 1 )
071           {
072             throw new IllegalArgumentException ( "scrollRate < 1" );
073           }
074    
075           this.scrollRate = scrollRate;
076    
077           this.wrapAround = wrapAround;
078    
079           bounds = new Rectangle ( );
080    
081           component.addMouseMotionListener (
082             new MouseMotionAdapter ( )
083             {
084               public void  mouseMoved ( MouseEvent  mouseEvent )
085               {
086                 mousePoint = mouseEvent.getPoint ( );
087               }
088             } );
089         }
090    
091         public  EdgeScrollUpdater (
092           JComponent  component,
093           int         width,
094           int         height )
095         //////////////////////////////////////////////////////////////////////
096         {
097           this ( component, width, height, null, DEFAULT_SCROLL_RATE, false );
098         }
099    
100         //////////////////////////////////////////////////////////////////////
101         //////////////////////////////////////////////////////////////////////
102    
103         public int  getTranslateX ( ) { return translateX; }
104    
105         public int  getTranslateY ( ) { return translateY; }
106    
107         //////////////////////////////////////////////////////////////////////
108         //////////////////////////////////////////////////////////////////////
109    
110         public void  update ( JComponent  component )
111         //////////////////////////////////////////////////////////////////////
112         {
113           if ( mousePoint == null )
114           {
115             return;
116           }
117    
118           component.getBounds ( bounds );
119    
120           int  x = mousePoint.x;
121    
122           int  y = mousePoint.y;
123    
124           boolean  onEdge = false;
125    
126           int  edgeWidth;
127    
128           int  edgeHeight;
129    
130           if ( edgeSize == null )
131           {
132             edgeWidth  = bounds.width  / EDGE_SIZE_DIVIDER;
133    
134             edgeHeight = bounds.height / EDGE_SIZE_DIVIDER;
135           }
136           else
137           {
138             edgeWidth  = edgeSize.width;
139    
140             edgeHeight = edgeSize.height;
141           }
142    
143           if ( x < edgeWidth )
144           {
145             if ( wrapAround || ( translateX < 0 ) )
146             {
147               onEdge = true;
148    
149               translateX += scrollRate;
150    
151               if ( translateX > 0 )
152               {
153                 if ( wrapAround )
154                 {
155                   translateX -= width;
156                 }
157                 else
158                 {
159                   translateX = 0;
160                 }
161               }
162             }
163           }
164           else if ( x > bounds.width - edgeWidth )
165           {
166             if ( wrapAround || ( translateX > -( width - bounds.width ) ) )
167             {
168               onEdge = true;
169    
170               translateX -= scrollRate;
171             }
172           }
173             
174           if ( translateX < -( width - bounds.width ) )
175           {
176             if ( wrapAround )
177             {
178               translateX += width;
179             }
180             else
181             {
182               translateX = -( width - bounds.width );
183             }
184           }
185    
186           if ( y < edgeHeight )
187           {
188             if ( wrapAround || ( translateY < 0 ) )
189             {
190               onEdge = true;
191    
192               translateY += scrollRate;
193    
194               if ( translateY > 0 )
195               {
196                 if ( wrapAround )
197                 {
198                   translateY -= height;
199                 }
200                 else
201                 {
202                   translateY = 0;
203                 }
204               }
205             }
206           }
207           else if ( y > bounds.height - edgeHeight )
208           {
209             if ( wrapAround || ( translateY > -( height - bounds.height ) ) )
210             {
211               onEdge = true;
212    
213               translateY -= scrollRate;
214             }
215           }
216    
217           if ( translateY < -( height - bounds.height ) )
218           {
219             if ( wrapAround )
220             {
221               translateY += height;
222             }
223             else
224             {
225               translateY = -( height - bounds.height );
226             }
227           }
228    
229           if ( !onEdge )
230           {
231             mousePoint = null;
232           }
233           else
234           {
235             component.repaint ( );
236           }
237         }
238    
239         public void  translate ( Graphics  graphics )
240         //////////////////////////////////////////////////////////////////////
241         {
242           graphics.translate ( translateX, translateY );
243         }
244    
245         public void  translate ( Point  point )
246         //////////////////////////////////////////////////////////////////////
247         {
248           point.x += translateX;
249    
250           point.y += translateY;
251         }
252    
253         public void  translateReverse ( Graphics  graphics )
254         //////////////////////////////////////////////////////////////////////
255         {
256           graphics.translate ( -translateX, -translateY );
257         }
258    
259         public void  translateReverse ( Point  point )
260         //////////////////////////////////////////////////////////////////////
261         {
262           point.x -= translateX;
263    
264           point.y -= translateY;
265         }
266    
267         //////////////////////////////////////////////////////////////////////
268         //////////////////////////////////////////////////////////////////////
269         }