131 132 private static final class AquaSingleImagePainter<T extends JRSUIState> 133 extends AquaPainter<T> { 134 135 AquaSingleImagePainter(final T state) { 136 super(new JRSUIControl(false), state); 137 } 138 139 @Override 140 void paint(final Graphics2D g, final T stateToPaint) { 141 paintFromSingleCachedImage(g, control, stateToPaint, boundsRect); 142 } 143 144 static void paintFromSingleCachedImage(final Graphics2D g, 145 final JRSUIControl control, final JRSUIState controlState, 146 final Rectangle bounds) { 147 if (bounds.width <= 0 || bounds.height <= 0) { 148 return; 149 } 150 151 int scale = 1; 152 if (g instanceof SunGraphics2D) { 153 scale = ((SunGraphics2D) g).surfaceData.getDefaultScale(); 154 } 155 final GraphicsConfiguration config = g.getDeviceConfiguration(); 156 final ImageCache cache = ImageCache.getInstance(); 157 final int imgW = bounds.width * scale; 158 final int imgH = bounds.height * scale; 159 AquaPixelsKey key = new AquaPixelsKey(config, 160 imgW, imgH, scale, controlState); 161 BufferedImage img = (BufferedImage) cache.getImage(key); 162 if (img == null) { 163 img = new BufferedImage(imgW, imgH, BufferedImage.TYPE_INT_ARGB_PRE); 164 if (!controlState.is(JRSUIConstants.Animating.YES)) { 165 cache.setImage(key, img); 166 } 167 168 final WritableRaster raster = img.getRaster(); 169 final DataBufferInt buffer = (DataBufferInt) raster.getDataBuffer(); 170 171 control.set(controlState); 172 control.paint(SunWritableRaster.stealData(buffer, 0), 173 imgW, imgH, 0, 0, bounds.width, bounds.height); 174 SunWritableRaster.markDirty(buffer); 175 } 176 177 g.drawImage(img, bounds.x, bounds.y, bounds.width, bounds.height, null); 178 } 179 } 180 181 private static class AquaPixelsKey implements ImageCache.PixelsKey { 182 183 private final int pixelCount; 184 private final int hash; 185 186 // key parts 187 private final GraphicsConfiguration config; 188 private final int w; 189 private final int h; 190 private final int scale; 191 private final JRSUIState state; 192 193 AquaPixelsKey(final GraphicsConfiguration config, 194 final int w, final int h, final int scale, 195 final JRSUIState state) { 196 this.pixelCount = w * h; 197 this.config = config; 198 this.w = w; 199 this.h = h; 200 this.scale = scale; 201 this.state = state; 202 this.hash = hash(); 203 } 204 205 public int getPixelCount() { 206 return pixelCount; 207 } 208 209 private int hash() { 210 int hash = config != null ? config.hashCode() : 0; 211 hash = 31 * hash + w; 212 hash = 31 * hash + h; 213 hash = 31 * hash + scale; 214 hash = 31 * hash + state.hashCode(); 215 return hash; 216 } 217 218 @Override 219 public int hashCode() { 220 return hash; 221 } 222 223 @Override 224 public boolean equals(Object obj) { 225 if (obj instanceof AquaPixelsKey) { 226 AquaPixelsKey key = (AquaPixelsKey) obj; 227 return config == key.config && w == key.w && h == key.h 228 && scale == key.scale && state.equals(key.state); 229 } 230 return false; 231 } 232 } 233 234 private static class RecyclableJRSUISlicedImageControl 235 extends RecyclableSlicedImageControl { 236 237 private final JRSUIControl control; 238 private final JRSUIState state; 239 240 RecyclableJRSUISlicedImageControl(final JRSUIControl control, final JRSUIState state, final NineSliceMetrics metrics) { 241 super(metrics); 242 this.control = control; 243 this.state = state; 244 } 245 246 @Override 247 protected Image createTemplateImage(int width, int height) { 248 BufferedImage image = new BufferedImage(metrics.minW, metrics.minH, BufferedImage.TYPE_INT_ARGB_PRE); | 131 132 private static final class AquaSingleImagePainter<T extends JRSUIState> 133 extends AquaPainter<T> { 134 135 AquaSingleImagePainter(final T state) { 136 super(new JRSUIControl(false), state); 137 } 138 139 @Override 140 void paint(final Graphics2D g, final T stateToPaint) { 141 paintFromSingleCachedImage(g, control, stateToPaint, boundsRect); 142 } 143 144 static void paintFromSingleCachedImage(final Graphics2D g, 145 final JRSUIControl control, final JRSUIState controlState, 146 final Rectangle bounds) { 147 if (bounds.width <= 0 || bounds.height <= 0) { 148 return; 149 } 150 151 final GraphicsConfiguration config = g.getDeviceConfiguration(); 152 final ImageCache cache = ImageCache.getInstance(); 153 final int width = bounds.width; 154 final int height = bounds.height; 155 AquaPixelsKey key = new AquaPixelsKey(config, 156 width, height, bounds, controlState); 157 Image img = (BufferedImage) cache.getImage(key); 158 if (img == null) { 159 160 Dimension[] sizes = new Dimension[]{ 161 new Dimension(width, height), new Dimension(2 * width, 2 * height) 162 }; 163 164 Image baseImage = createImage(width, height, bounds, control, 165 controlState); 166 167 img = new MultiResolutionBufferedImage(baseImage, sizes, 168 (rvWidth, rvHeight) -> createImage(rvWidth, rvHeight, 169 bounds, control, controlState)); 170 171 if (!controlState.is(JRSUIConstants.Animating.YES)) { 172 cache.setImage(key, img); 173 } 174 } 175 176 g.drawImage(img, bounds.x, bounds.y, bounds.width, bounds.height, null); 177 } 178 179 private static Image createImage(int imgW, int imgH, final Rectangle bounds, 180 final JRSUIControl control, JRSUIState controlState) { 181 BufferedImage img = new BufferedImage(imgW, imgH, 182 BufferedImage.TYPE_INT_ARGB_PRE); 183 184 final WritableRaster raster = img.getRaster(); 185 final DataBufferInt buffer = (DataBufferInt) raster.getDataBuffer(); 186 187 control.set(controlState); 188 control.paint(SunWritableRaster.stealData(buffer, 0), 189 imgW, imgH, 0, 0, bounds.width, bounds.height); 190 SunWritableRaster.markDirty(buffer); 191 return img; 192 } 193 } 194 195 private static class AquaPixelsKey implements ImageCache.PixelsKey { 196 197 private final int pixelCount; 198 private final int hash; 199 200 // key parts 201 private final GraphicsConfiguration config; 202 private final int w; 203 private final int h; 204 private final Rectangle bounds; 205 private final JRSUIState state; 206 207 AquaPixelsKey(final GraphicsConfiguration config, 208 final int w, final int h, final Rectangle bounds, 209 final JRSUIState state) { 210 this.pixelCount = w * h; 211 this.config = config; 212 this.w = w; 213 this.h = h; 214 this.bounds = bounds; 215 this.state = state; 216 this.hash = hash(); 217 } 218 219 public int getPixelCount() { 220 return pixelCount; 221 } 222 223 private int hash() { 224 int hash = config != null ? config.hashCode() : 0; 225 hash = 31 * hash + w; 226 hash = 31 * hash + h; 227 hash = 31 * hash + bounds.hashCode(); 228 hash = 31 * hash + state.hashCode(); 229 return hash; 230 } 231 232 @Override 233 public int hashCode() { 234 return hash; 235 } 236 237 @Override 238 public boolean equals(Object obj) { 239 if (obj instanceof AquaPixelsKey) { 240 AquaPixelsKey key = (AquaPixelsKey) obj; 241 return config == key.config && w == key.w && h == key.h 242 && bounds.equals(key.bounds) && state.equals(key.state); 243 } 244 return false; 245 } 246 } 247 248 private static class RecyclableJRSUISlicedImageControl 249 extends RecyclableSlicedImageControl { 250 251 private final JRSUIControl control; 252 private final JRSUIState state; 253 254 RecyclableJRSUISlicedImageControl(final JRSUIControl control, final JRSUIState state, final NineSliceMetrics metrics) { 255 super(metrics); 256 this.control = control; 257 this.state = state; 258 } 259 260 @Override 261 protected Image createTemplateImage(int width, int height) { 262 BufferedImage image = new BufferedImage(metrics.minW, metrics.minH, BufferedImage.TYPE_INT_ARGB_PRE); |