104 * @author Animation capabilities inspired by the
105 * MemoryAnimationSource class written by Garth Dickie
106 */
107 public class MemoryImageSource implements ImageProducer {
108 int width;
109 int height;
110 ColorModel model;
111 Object pixels;
112 int pixeloffset;
113 int pixelscan;
114 Hashtable<?, ?> properties;
115 Vector<ImageConsumer> theConsumers = new Vector<>();
116 boolean animating;
117 boolean fullbuffers;
118
119 /**
120 * Constructs an ImageProducer object which uses an array of bytes
121 * to produce data for an Image object.
122 * @param w the width of the rectangle of pixels
123 * @param h the height of the rectangle of pixels
124 * @param cm the specified <code>ColorModel</code>
125 * @param pix an array of pixels
126 * @param off the offset into the array of where to store the
127 * first pixel
128 * @param scan the distance from one row of pixels to the next in
129 * the array
130 * @see java.awt.Component#createImage
131 */
132 public MemoryImageSource(int w, int h, ColorModel cm,
133 byte[] pix, int off, int scan) {
134 initialize(w, h, cm, (Object) pix, off, scan, null);
135 }
136
137 /**
138 * Constructs an ImageProducer object which uses an array of bytes
139 * to produce data for an Image object.
140 * @param w the width of the rectangle of pixels
141 * @param h the height of the rectangle of pixels
142 * @param cm the specified <code>ColorModel</code>
143 * @param pix an array of pixels
144 * @param off the offset into the array of where to store the
145 * first pixel
146 * @param scan the distance from one row of pixels to the next in
147 * the array
148 * @param props a list of properties that the <code>ImageProducer</code>
149 * uses to process an image
150 * @see java.awt.Component#createImage
151 */
152 public MemoryImageSource(int w, int h, ColorModel cm,
153 byte[] pix, int off, int scan,
154 Hashtable<?,?> props)
155 {
156 initialize(w, h, cm, (Object) pix, off, scan, props);
157 }
158
159 /**
160 * Constructs an ImageProducer object which uses an array of integers
161 * to produce data for an Image object.
162 * @param w the width of the rectangle of pixels
163 * @param h the height of the rectangle of pixels
164 * @param cm the specified <code>ColorModel</code>
165 * @param pix an array of pixels
166 * @param off the offset into the array of where to store the
167 * first pixel
168 * @param scan the distance from one row of pixels to the next in
169 * the array
170 * @see java.awt.Component#createImage
171 */
172 public MemoryImageSource(int w, int h, ColorModel cm,
173 int[] pix, int off, int scan) {
174 initialize(w, h, cm, (Object) pix, off, scan, null);
175 }
176
177 /**
178 * Constructs an ImageProducer object which uses an array of integers
179 * to produce data for an Image object.
180 * @param w the width of the rectangle of pixels
181 * @param h the height of the rectangle of pixels
182 * @param cm the specified <code>ColorModel</code>
183 * @param pix an array of pixels
184 * @param off the offset into the array of where to store the
185 * first pixel
186 * @param scan the distance from one row of pixels to the next in
187 * the array
188 * @param props a list of properties that the <code>ImageProducer</code>
189 * uses to process an image
190 * @see java.awt.Component#createImage
191 */
192 public MemoryImageSource(int w, int h, ColorModel cm,
193 int[] pix, int off, int scan,
194 Hashtable<?,?> props)
195 {
196 initialize(w, h, cm, (Object) pix, off, scan, props);
197 }
198
199 private void initialize(int w, int h, ColorModel cm,
200 Object pix, int off, int scan, Hashtable<?,?> props) {
201 width = w;
202 height = h;
203 model = cm;
204 pixels = pix;
205 pixeloffset = off;
206 pixelscan = scan;
207 if (props == null) {
208 props = new Hashtable<>();
221 * @param scan the distance from one row of pixels to the next in
222 * the array
223 * @see java.awt.Component#createImage
224 * @see ColorModel#getRGBdefault
225 */
226 public MemoryImageSource(int w, int h, int pix[], int off, int scan) {
227 initialize(w, h, ColorModel.getRGBdefault(),
228 (Object) pix, off, scan, null);
229 }
230
231 /**
232 * Constructs an ImageProducer object which uses an array of integers
233 * in the default RGB ColorModel to produce data for an Image object.
234 * @param w the width of the rectangle of pixels
235 * @param h the height of the rectangle of pixels
236 * @param pix an array of pixels
237 * @param off the offset into the array of where to store the
238 * first pixel
239 * @param scan the distance from one row of pixels to the next in
240 * the array
241 * @param props a list of properties that the <code>ImageProducer</code>
242 * uses to process an image
243 * @see java.awt.Component#createImage
244 * @see ColorModel#getRGBdefault
245 */
246 public MemoryImageSource(int w, int h, int pix[], int off, int scan,
247 Hashtable<?,?> props)
248 {
249 initialize(w, h, ColorModel.getRGBdefault(),
250 (Object) pix, off, scan, props);
251 }
252
253 /**
254 * Adds an ImageConsumer to the list of consumers interested in
255 * data for this image.
256 * @param ic the specified <code>ImageConsumer</code>
257 * @throws NullPointerException if the specified
258 * <code>ImageConsumer</code> is null
259 * @see ImageConsumer
260 */
261 public synchronized void addConsumer(ImageConsumer ic) {
262 if (theConsumers.contains(ic)) {
263 return;
264 }
265 theConsumers.addElement(ic);
266 try {
267 initConsumer(ic);
268 sendPixels(ic, 0, 0, width, height);
269 if (isConsumer(ic)) {
270 ic.imageComplete(animating
271 ? ImageConsumer.SINGLEFRAMEDONE
272 : ImageConsumer.STATICIMAGEDONE);
273 if (!animating && isConsumer(ic)) {
274 ic.imageComplete(ImageConsumer.IMAGEERROR);
275 removeConsumer(ic);
276 }
277 }
278 } catch (Exception e) {
279 if (isConsumer(ic)) {
280 ic.imageComplete(ImageConsumer.IMAGEERROR);
281 }
282 }
283 }
284
285 /**
286 * Determines if an ImageConsumer is on the list of consumers currently
287 * interested in data for this image.
288 * @param ic the specified <code>ImageConsumer</code>
289 * @return <code>true</code> if the <code>ImageConsumer</code>
290 * is on the list; <code>false</code> otherwise.
291 * @see ImageConsumer
292 */
293 public synchronized boolean isConsumer(ImageConsumer ic) {
294 return theConsumers.contains(ic);
295 }
296
297 /**
298 * Removes an ImageConsumer from the list of consumers interested in
299 * data for this image.
300 * @param ic the specified <code>ImageConsumer</code>
301 * @see ImageConsumer
302 */
303 public synchronized void removeConsumer(ImageConsumer ic) {
304 theConsumers.removeElement(ic);
305 }
306
307 /**
308 * Adds an ImageConsumer to the list of consumers interested in
309 * data for this image and immediately starts delivery of the
310 * image data through the ImageConsumer interface.
311 * @param ic the specified <code>ImageConsumer</code>
312 * image data through the ImageConsumer interface.
313 * @see ImageConsumer
314 */
315 public void startProduction(ImageConsumer ic) {
316 addConsumer(ic);
317 }
318
319 /**
320 * Requests that a given ImageConsumer have the image data delivered
321 * one more time in top-down, left-right order.
322 * @param ic the specified <code>ImageConsumer</code>
323 * @see ImageConsumer
324 */
325 public void requestTopDownLeftRightResend(ImageConsumer ic) {
326 // Ignored. The data is either single frame and already in TDLR
327 // format or it is multi-frame and TDLR resends aren't critical.
328 }
329
330 /**
331 * Changes this memory image into a multi-frame animation or a
332 * single-frame static image depending on the animated parameter.
333 * <p>This method should be called immediately after the
334 * MemoryImageSource is constructed and before an image is
335 * created with it to ensure that all ImageConsumers will
336 * receive the correct multi-frame data. If an ImageConsumer
337 * is added to this ImageProducer before this flag is set then
338 * that ImageConsumer will see only a snapshot of the pixel
339 * data that was available when it connected.
340 * @param animated <code>true</code> if the image is a
341 * multi-frame animation
342 */
343 public synchronized void setAnimated(boolean animated) {
344 this.animating = animated;
345 if (!animating) {
346 Enumeration<ImageConsumer> enum_ = theConsumers.elements();
347 while (enum_.hasMoreElements()) {
348 ImageConsumer ic = enum_.nextElement();
349 ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
350 if (isConsumer(ic)) {
351 ic.imageComplete(ImageConsumer.IMAGEERROR);
352 }
353 }
354 theConsumers.removeAllElements();
355 }
356 }
357
358 /**
359 * Specifies whether this animated memory image should always be
360 * updated by sending the complete buffer of pixels whenever
361 * there is a change.
362 * This flag is ignored if the animation flag is not turned on
363 * through the setAnimated() method.
364 * <p>This method should be called immediately after the
365 * MemoryImageSource is constructed and before an image is
366 * created with it to ensure that all ImageConsumers will
367 * receive the correct pixel delivery hints.
368 * @param fullbuffers <code>true</code> if the complete pixel
369 * buffer should always
370 * be sent
371 * @see #setAnimated
372 */
373 public synchronized void setFullBufferUpdates(boolean fullbuffers) {
374 if (this.fullbuffers == fullbuffers) {
375 return;
376 }
377 this.fullbuffers = fullbuffers;
378 if (animating) {
379 Enumeration<ImageConsumer> enum_ = theConsumers.elements();
380 while (enum_.hasMoreElements()) {
381 ImageConsumer ic = enum_.nextElement();
382 ic.setHints(fullbuffers
383 ? (ImageConsumer.TOPDOWNLEFTRIGHT |
384 ImageConsumer.COMPLETESCANLINES)
385 : ImageConsumer.RANDOMPIXELORDER);
386 }
387 }
388 }
425 newPixels(x, y, w, h, true);
426 }
427
428 /**
429 * Sends a rectangular region of the buffer of pixels to any
430 * ImageConsumers that are currently interested in the data for
431 * this image.
432 * If the framenotify parameter is true then the consumers are
433 * also notified that an animation frame is complete.
434 * This method only has effect if the animation flag has been
435 * turned on through the setAnimated() method.
436 * If the full buffer update flag was turned on with the
437 * setFullBufferUpdates() method then the rectangle parameters
438 * will be ignored and the entire buffer will always be sent.
439 * @param x the x coordinate of the upper left corner of the rectangle
440 * of pixels to be sent
441 * @param y the y coordinate of the upper left corner of the rectangle
442 * of pixels to be sent
443 * @param w the width of the rectangle of pixels to be sent
444 * @param h the height of the rectangle of pixels to be sent
445 * @param framenotify <code>true</code> if the consumers should be sent a
446 * {@link ImageConsumer#SINGLEFRAMEDONE SINGLEFRAMEDONE} notification
447 * @see ImageConsumer
448 * @see #setAnimated
449 * @see #setFullBufferUpdates
450 */
451 public synchronized void newPixels(int x, int y, int w, int h,
452 boolean framenotify) {
453 if (animating) {
454 if (fullbuffers) {
455 x = y = 0;
456 w = width;
457 h = height;
458 } else {
459 if (x < 0) {
460 w += x;
461 x = 0;
462 }
463 if (x + w > width) {
464 w = width - x;
465 }
477 Enumeration<ImageConsumer> enum_ = theConsumers.elements();
478 while (enum_.hasMoreElements()) {
479 ImageConsumer ic = enum_.nextElement();
480 if (w > 0 && h > 0) {
481 sendPixels(ic, x, y, w, h);
482 }
483 if (framenotify && isConsumer(ic)) {
484 ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
485 }
486 }
487 }
488 }
489
490 /**
491 * Changes to a new byte array to hold the pixels for this image.
492 * If the animation flag has been turned on through the setAnimated()
493 * method, then the new pixels will be immediately delivered to any
494 * ImageConsumers that are currently interested in the data for
495 * this image.
496 * @param newpix the new pixel array
497 * @param newmodel the specified <code>ColorModel</code>
498 * @param offset the offset into the array
499 * @param scansize the distance from one row of pixels to the next in
500 * the array
501 * @see #newPixels(int, int, int, int, boolean)
502 * @see #setAnimated
503 */
504 public synchronized void newPixels(byte[] newpix, ColorModel newmodel,
505 int offset, int scansize) {
506 this.pixels = newpix;
507 this.model = newmodel;
508 this.pixeloffset = offset;
509 this.pixelscan = scansize;
510 newPixels();
511 }
512
513 /**
514 * Changes to a new int array to hold the pixels for this image.
515 * If the animation flag has been turned on through the setAnimated()
516 * method, then the new pixels will be immediately delivered to any
517 * ImageConsumers that are currently interested in the data for
518 * this image.
519 * @param newpix the new pixel array
520 * @param newmodel the specified <code>ColorModel</code>
521 * @param offset the offset into the array
522 * @param scansize the distance from one row of pixels to the next in
523 * the array
524 * @see #newPixels(int, int, int, int, boolean)
525 * @see #setAnimated
526 */
527 public synchronized void newPixels(int[] newpix, ColorModel newmodel,
528 int offset, int scansize) {
529 this.pixels = newpix;
530 this.model = newmodel;
531 this.pixeloffset = offset;
532 this.pixelscan = scansize;
533 newPixels();
534 }
535
536 private void initConsumer(ImageConsumer ic) {
537 if (isConsumer(ic)) {
538 ic.setDimensions(width, height);
539 }
540 if (isConsumer(ic)) {
|
104 * @author Animation capabilities inspired by the
105 * MemoryAnimationSource class written by Garth Dickie
106 */
107 public class MemoryImageSource implements ImageProducer {
108 int width;
109 int height;
110 ColorModel model;
111 Object pixels;
112 int pixeloffset;
113 int pixelscan;
114 Hashtable<?, ?> properties;
115 Vector<ImageConsumer> theConsumers = new Vector<>();
116 boolean animating;
117 boolean fullbuffers;
118
119 /**
120 * Constructs an ImageProducer object which uses an array of bytes
121 * to produce data for an Image object.
122 * @param w the width of the rectangle of pixels
123 * @param h the height of the rectangle of pixels
124 * @param cm the specified {@code ColorModel}
125 * @param pix an array of pixels
126 * @param off the offset into the array of where to store the
127 * first pixel
128 * @param scan the distance from one row of pixels to the next in
129 * the array
130 * @see java.awt.Component#createImage
131 */
132 public MemoryImageSource(int w, int h, ColorModel cm,
133 byte[] pix, int off, int scan) {
134 initialize(w, h, cm, (Object) pix, off, scan, null);
135 }
136
137 /**
138 * Constructs an ImageProducer object which uses an array of bytes
139 * to produce data for an Image object.
140 * @param w the width of the rectangle of pixels
141 * @param h the height of the rectangle of pixels
142 * @param cm the specified {@code ColorModel}
143 * @param pix an array of pixels
144 * @param off the offset into the array of where to store the
145 * first pixel
146 * @param scan the distance from one row of pixels to the next in
147 * the array
148 * @param props a list of properties that the {@code ImageProducer}
149 * uses to process an image
150 * @see java.awt.Component#createImage
151 */
152 public MemoryImageSource(int w, int h, ColorModel cm,
153 byte[] pix, int off, int scan,
154 Hashtable<?,?> props)
155 {
156 initialize(w, h, cm, (Object) pix, off, scan, props);
157 }
158
159 /**
160 * Constructs an ImageProducer object which uses an array of integers
161 * to produce data for an Image object.
162 * @param w the width of the rectangle of pixels
163 * @param h the height of the rectangle of pixels
164 * @param cm the specified {@code ColorModel}
165 * @param pix an array of pixels
166 * @param off the offset into the array of where to store the
167 * first pixel
168 * @param scan the distance from one row of pixels to the next in
169 * the array
170 * @see java.awt.Component#createImage
171 */
172 public MemoryImageSource(int w, int h, ColorModel cm,
173 int[] pix, int off, int scan) {
174 initialize(w, h, cm, (Object) pix, off, scan, null);
175 }
176
177 /**
178 * Constructs an ImageProducer object which uses an array of integers
179 * to produce data for an Image object.
180 * @param w the width of the rectangle of pixels
181 * @param h the height of the rectangle of pixels
182 * @param cm the specified {@code ColorModel}
183 * @param pix an array of pixels
184 * @param off the offset into the array of where to store the
185 * first pixel
186 * @param scan the distance from one row of pixels to the next in
187 * the array
188 * @param props a list of properties that the {@code ImageProducer}
189 * uses to process an image
190 * @see java.awt.Component#createImage
191 */
192 public MemoryImageSource(int w, int h, ColorModel cm,
193 int[] pix, int off, int scan,
194 Hashtable<?,?> props)
195 {
196 initialize(w, h, cm, (Object) pix, off, scan, props);
197 }
198
199 private void initialize(int w, int h, ColorModel cm,
200 Object pix, int off, int scan, Hashtable<?,?> props) {
201 width = w;
202 height = h;
203 model = cm;
204 pixels = pix;
205 pixeloffset = off;
206 pixelscan = scan;
207 if (props == null) {
208 props = new Hashtable<>();
221 * @param scan the distance from one row of pixels to the next in
222 * the array
223 * @see java.awt.Component#createImage
224 * @see ColorModel#getRGBdefault
225 */
226 public MemoryImageSource(int w, int h, int pix[], int off, int scan) {
227 initialize(w, h, ColorModel.getRGBdefault(),
228 (Object) pix, off, scan, null);
229 }
230
231 /**
232 * Constructs an ImageProducer object which uses an array of integers
233 * in the default RGB ColorModel to produce data for an Image object.
234 * @param w the width of the rectangle of pixels
235 * @param h the height of the rectangle of pixels
236 * @param pix an array of pixels
237 * @param off the offset into the array of where to store the
238 * first pixel
239 * @param scan the distance from one row of pixels to the next in
240 * the array
241 * @param props a list of properties that the {@code ImageProducer}
242 * uses to process an image
243 * @see java.awt.Component#createImage
244 * @see ColorModel#getRGBdefault
245 */
246 public MemoryImageSource(int w, int h, int pix[], int off, int scan,
247 Hashtable<?,?> props)
248 {
249 initialize(w, h, ColorModel.getRGBdefault(),
250 (Object) pix, off, scan, props);
251 }
252
253 /**
254 * Adds an ImageConsumer to the list of consumers interested in
255 * data for this image.
256 * @param ic the specified {@code ImageConsumer}
257 * @throws NullPointerException if the specified
258 * {@code ImageConsumer} is null
259 * @see ImageConsumer
260 */
261 public synchronized void addConsumer(ImageConsumer ic) {
262 if (theConsumers.contains(ic)) {
263 return;
264 }
265 theConsumers.addElement(ic);
266 try {
267 initConsumer(ic);
268 sendPixels(ic, 0, 0, width, height);
269 if (isConsumer(ic)) {
270 ic.imageComplete(animating
271 ? ImageConsumer.SINGLEFRAMEDONE
272 : ImageConsumer.STATICIMAGEDONE);
273 if (!animating && isConsumer(ic)) {
274 ic.imageComplete(ImageConsumer.IMAGEERROR);
275 removeConsumer(ic);
276 }
277 }
278 } catch (Exception e) {
279 if (isConsumer(ic)) {
280 ic.imageComplete(ImageConsumer.IMAGEERROR);
281 }
282 }
283 }
284
285 /**
286 * Determines if an ImageConsumer is on the list of consumers currently
287 * interested in data for this image.
288 * @param ic the specified {@code ImageConsumer}
289 * @return {@code true} if the {@code ImageConsumer}
290 * is on the list; {@code false} otherwise.
291 * @see ImageConsumer
292 */
293 public synchronized boolean isConsumer(ImageConsumer ic) {
294 return theConsumers.contains(ic);
295 }
296
297 /**
298 * Removes an ImageConsumer from the list of consumers interested in
299 * data for this image.
300 * @param ic the specified {@code ImageConsumer}
301 * @see ImageConsumer
302 */
303 public synchronized void removeConsumer(ImageConsumer ic) {
304 theConsumers.removeElement(ic);
305 }
306
307 /**
308 * Adds an ImageConsumer to the list of consumers interested in
309 * data for this image and immediately starts delivery of the
310 * image data through the ImageConsumer interface.
311 * @param ic the specified {@code ImageConsumer}
312 * image data through the ImageConsumer interface.
313 * @see ImageConsumer
314 */
315 public void startProduction(ImageConsumer ic) {
316 addConsumer(ic);
317 }
318
319 /**
320 * Requests that a given ImageConsumer have the image data delivered
321 * one more time in top-down, left-right order.
322 * @param ic the specified {@code ImageConsumer}
323 * @see ImageConsumer
324 */
325 public void requestTopDownLeftRightResend(ImageConsumer ic) {
326 // Ignored. The data is either single frame and already in TDLR
327 // format or it is multi-frame and TDLR resends aren't critical.
328 }
329
330 /**
331 * Changes this memory image into a multi-frame animation or a
332 * single-frame static image depending on the animated parameter.
333 * <p>This method should be called immediately after the
334 * MemoryImageSource is constructed and before an image is
335 * created with it to ensure that all ImageConsumers will
336 * receive the correct multi-frame data. If an ImageConsumer
337 * is added to this ImageProducer before this flag is set then
338 * that ImageConsumer will see only a snapshot of the pixel
339 * data that was available when it connected.
340 * @param animated {@code true} if the image is a
341 * multi-frame animation
342 */
343 public synchronized void setAnimated(boolean animated) {
344 this.animating = animated;
345 if (!animating) {
346 Enumeration<ImageConsumer> enum_ = theConsumers.elements();
347 while (enum_.hasMoreElements()) {
348 ImageConsumer ic = enum_.nextElement();
349 ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
350 if (isConsumer(ic)) {
351 ic.imageComplete(ImageConsumer.IMAGEERROR);
352 }
353 }
354 theConsumers.removeAllElements();
355 }
356 }
357
358 /**
359 * Specifies whether this animated memory image should always be
360 * updated by sending the complete buffer of pixels whenever
361 * there is a change.
362 * This flag is ignored if the animation flag is not turned on
363 * through the setAnimated() method.
364 * <p>This method should be called immediately after the
365 * MemoryImageSource is constructed and before an image is
366 * created with it to ensure that all ImageConsumers will
367 * receive the correct pixel delivery hints.
368 * @param fullbuffers {@code true} if the complete pixel
369 * buffer should always
370 * be sent
371 * @see #setAnimated
372 */
373 public synchronized void setFullBufferUpdates(boolean fullbuffers) {
374 if (this.fullbuffers == fullbuffers) {
375 return;
376 }
377 this.fullbuffers = fullbuffers;
378 if (animating) {
379 Enumeration<ImageConsumer> enum_ = theConsumers.elements();
380 while (enum_.hasMoreElements()) {
381 ImageConsumer ic = enum_.nextElement();
382 ic.setHints(fullbuffers
383 ? (ImageConsumer.TOPDOWNLEFTRIGHT |
384 ImageConsumer.COMPLETESCANLINES)
385 : ImageConsumer.RANDOMPIXELORDER);
386 }
387 }
388 }
425 newPixels(x, y, w, h, true);
426 }
427
428 /**
429 * Sends a rectangular region of the buffer of pixels to any
430 * ImageConsumers that are currently interested in the data for
431 * this image.
432 * If the framenotify parameter is true then the consumers are
433 * also notified that an animation frame is complete.
434 * This method only has effect if the animation flag has been
435 * turned on through the setAnimated() method.
436 * If the full buffer update flag was turned on with the
437 * setFullBufferUpdates() method then the rectangle parameters
438 * will be ignored and the entire buffer will always be sent.
439 * @param x the x coordinate of the upper left corner of the rectangle
440 * of pixels to be sent
441 * @param y the y coordinate of the upper left corner of the rectangle
442 * of pixels to be sent
443 * @param w the width of the rectangle of pixels to be sent
444 * @param h the height of the rectangle of pixels to be sent
445 * @param framenotify {@code true} if the consumers should be sent a
446 * {@link ImageConsumer#SINGLEFRAMEDONE SINGLEFRAMEDONE} notification
447 * @see ImageConsumer
448 * @see #setAnimated
449 * @see #setFullBufferUpdates
450 */
451 public synchronized void newPixels(int x, int y, int w, int h,
452 boolean framenotify) {
453 if (animating) {
454 if (fullbuffers) {
455 x = y = 0;
456 w = width;
457 h = height;
458 } else {
459 if (x < 0) {
460 w += x;
461 x = 0;
462 }
463 if (x + w > width) {
464 w = width - x;
465 }
477 Enumeration<ImageConsumer> enum_ = theConsumers.elements();
478 while (enum_.hasMoreElements()) {
479 ImageConsumer ic = enum_.nextElement();
480 if (w > 0 && h > 0) {
481 sendPixels(ic, x, y, w, h);
482 }
483 if (framenotify && isConsumer(ic)) {
484 ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
485 }
486 }
487 }
488 }
489
490 /**
491 * Changes to a new byte array to hold the pixels for this image.
492 * If the animation flag has been turned on through the setAnimated()
493 * method, then the new pixels will be immediately delivered to any
494 * ImageConsumers that are currently interested in the data for
495 * this image.
496 * @param newpix the new pixel array
497 * @param newmodel the specified {@code ColorModel}
498 * @param offset the offset into the array
499 * @param scansize the distance from one row of pixels to the next in
500 * the array
501 * @see #newPixels(int, int, int, int, boolean)
502 * @see #setAnimated
503 */
504 public synchronized void newPixels(byte[] newpix, ColorModel newmodel,
505 int offset, int scansize) {
506 this.pixels = newpix;
507 this.model = newmodel;
508 this.pixeloffset = offset;
509 this.pixelscan = scansize;
510 newPixels();
511 }
512
513 /**
514 * Changes to a new int array to hold the pixels for this image.
515 * If the animation flag has been turned on through the setAnimated()
516 * method, then the new pixels will be immediately delivered to any
517 * ImageConsumers that are currently interested in the data for
518 * this image.
519 * @param newpix the new pixel array
520 * @param newmodel the specified {@code ColorModel}
521 * @param offset the offset into the array
522 * @param scansize the distance from one row of pixels to the next in
523 * the array
524 * @see #newPixels(int, int, int, int, boolean)
525 * @see #setAnimated
526 */
527 public synchronized void newPixels(int[] newpix, ColorModel newmodel,
528 int offset, int scansize) {
529 this.pixels = newpix;
530 this.model = newmodel;
531 this.pixeloffset = offset;
532 this.pixelscan = scansize;
533 newPixels();
534 }
535
536 private void initConsumer(ImageConsumer ic) {
537 if (isConsumer(ic)) {
538 ic.setDimensions(width, height);
539 }
540 if (isConsumer(ic)) {
|