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="http://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 }