001         package com.croftsoft.core.animation.collector;
002    
003         import java.awt.Rectangle;
004         import java.awt.geom.Rectangle2D;
005    
006         import com.croftsoft.core.animation.RepaintCollector;
007         import com.croftsoft.core.util.ArrayLib;
008    
009         /*********************************************************************
010         * Coalesces repaint requests that intersect.
011         *
012         * @version
013         *   2003-09-05
014         * @since
015         *   2003-02-03
016         * @author
017         *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
018         *********************************************************************/
019    
020         public class  CoalescingRepaintCollector
021           implements RepaintCollector
022         //////////////////////////////////////////////////////////////////////
023         //////////////////////////////////////////////////////////////////////
024         {
025    
026         private static final Rectangle [ ]  ALL_REGIONS = new Rectangle [ ] {
027           new Rectangle ( Integer.MAX_VALUE, Integer.MAX_VALUE ) };
028    
029         //
030    
031         private int            count;
032    
033         private boolean        repaintAll;
034    
035         private Rectangle [ ]  repaintRegions;
036    
037         //////////////////////////////////////////////////////////////////////
038         // constructor methods
039         //////////////////////////////////////////////////////////////////////
040    
041         public  CoalescingRepaintCollector ( )
042         //////////////////////////////////////////////////////////////////////
043         {
044           repaintRegions = new Rectangle [ 0 ];
045         }
046    
047         //////////////////////////////////////////////////////////////////////
048         // accessor methods
049         //////////////////////////////////////////////////////////////////////
050    
051         public int  getCount ( )
052         //////////////////////////////////////////////////////////////////////
053         {
054           if ( repaintAll )
055           {
056             return 1;
057           }
058    
059           boolean  hasIntersections = true;
060    
061           while ( hasIntersections )
062           {
063             hasIntersections = false;
064    
065             iLoop:
066    
067             for ( int  i = 0; i < count - 1; i++ )
068             {
069               Rectangle  iRectangle = repaintRegions [ i ];
070    
071               for ( int  j = i + 1; j < count; j++ )
072               {
073                 Rectangle  jRectangle = repaintRegions [ j ];
074    
075                 if ( iRectangle.intersects ( jRectangle ) )
076                 {
077                   hasIntersections = true;
078    
079                   Rectangle2D.union ( iRectangle, jRectangle, iRectangle );
080    
081                   repaintRegions [ j ] = repaintRegions [ count - 1 ];
082    
083                   repaintRegions [ count - 1 ] = jRectangle;
084    
085                   count--;
086    
087                   break iLoop;
088                 }
089               }
090             }
091           }
092    
093           return count;
094         }
095    
096         public Rectangle [ ]  getRepaintRegions ( )
097         //////////////////////////////////////////////////////////////////////
098         {
099           return repaintAll ? ALL_REGIONS : repaintRegions;
100         }
101    
102         //////////////////////////////////////////////////////////////////////
103         // mutator methods
104         //////////////////////////////////////////////////////////////////////
105    
106         public void  repaint (
107           int  x,
108           int  y,
109           int  width,
110           int  height )
111         //////////////////////////////////////////////////////////////////////
112         {
113           if ( repaintAll )
114           {
115             return;
116           }
117    
118           if ( count == repaintRegions.length )
119           {
120             repaintRegions = ( Rectangle [ ] ) ArrayLib.append (
121               repaintRegions, new Rectangle ( x, y, width, height ) );
122           }
123           else
124           {
125             repaintRegions [ count ].setBounds ( x, y, width, height );        
126           }
127    
128           count++;       
129         }
130    
131         public void  repaint ( )
132         //////////////////////////////////////////////////////////////////////
133         {
134           repaintAll = true;
135         }
136    
137         public void  reset ( )
138         //////////////////////////////////////////////////////////////////////
139         {
140           count = 0;
141    
142           repaintAll = false;
143         }
144    
145         //////////////////////////////////////////////////////////////////////
146         //////////////////////////////////////////////////////////////////////
147         }