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 }