Skip to main content

Question on RenderableImageProducer and thread safety

No replies
peterhull90
Offline
Joined: 2008-04-17
Points: 0

I've been having a problem with RenderableImageProducer which I think is due to multi-threading. I've posted my test code below (arrived at by stripping down my 'real' code), sorry it's a bit long.
This gives me errors:

Exception in thread "RenderableImageProducer Thread" java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
       at sun.awt.image.IntegerInterleavedRaster.setDataElements(IntegerInterleavedRaster.java:404)

I've done as much tracing as I can but can't see what's wrong in my code.
The main() function works fine if I use a different image for 'base', for example something from component.getImage(String), or even a custom ImageProducer.
Therefore I think it must be something in RenderableImageProducer.
Any ideas?
Thanks,
Peter
[edit]: version info
java version "1.6.0_23"
Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
Java HotSpot(TM) Client VM (build 19.0-b09, mixed mode, sharing)

The code:
package imagemangler;
import java.awt.Component;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderContext;
import java.awt.image.renderable.RenderableImage;
import java.awt.image.renderable.RenderableImageProducer;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MyRenderableImage implements RenderableImage {
/* Implement RenderableImage methods */
public Vector<renderableimage></renderableimage> getSources() {
  return null;
}<p> </p><p>public Object getProperty(String name) {</p><p>  return java.awt.Image.UndefinedProperty;</p><p> }</p><p>public String[] getPropertyNames() {</p><p>  return null;</p><p> }</p><p>public boolean isDynamic() {</p><p>  return false;</p><p> }</p><p>public float getWidth() {</p><p>  return 256.0f;</p><p> }</p><p>public float getHeight() {</p><p>  return 256.0f;</p><p> }</p><p>public float getMinX() {</p><p>  return 0.0f;</p><p> }</p><p>public float getMinY() {</p><p>  return 0.0f;</p><p> }</p><p><br />public RenderedImage createDefaultRendering() {</p><p>int width = 256;<br />  int height = 256;</p><p>Logger.getLogger(this.getClass().getName()).log(Level.INFO, &quot;Creating render {0}x{1} on thread {2}&quot;, new Object[]{width, height, Thread.currentThread().getId()});</p><p><br />  BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);</p><p><br />  // Don't bother drawing anything</p><p>return bi;</p><p>}</p><p><br /> /* Create eight scaled copies; RenderableImageProducer will start a</p><p>  * thread for each</p><p>  */<br /> public static void main(String[] args) {</p><p>  // Create a dummy component.</p><p>  Component component = new Component() {</p><p>  };<br />  Image base = component.createImage(new RenderableImageProducer(new MyRenderableImage(), null));</p><p>  MediaTracker mt = new MediaTracker(component);<br />  for (int i = 0; i &lt; 8; ++i) {</p><p>   int size = 1 &lt;&lt; i;</p><p>   Image mipmap = base.getScaledInstance(size, size, Image.SCALE_SMOOTH);<br />   mt.addImage(mipmap, i);<br />  }</p><p>  try {</p><p>   mt.waitForAll(1000);</p><p>  } catch (InterruptedException ex) {</p><p>  }</p><p>}</p><p>public RenderedImage createScaledRendering(int w, int h, RenderingHints hints) {</p><p>  throw new UnsupportedOperationException(&quot;Not supported yet.&quot;);</p><p> }</p><p> public RenderedImage createRendering(RenderContext renderContext) {</p><p>  throw new UnsupportedOperationException(&quot;Not supported yet.&quot;);</p><p> }</p><p>}</p><p><br /> </p>