When does ArrayIndexOutOfBoundsException get thrown?

Started by AGP, June 11, 2009, 07:42:56 PM

Previous topic - Next topic

AGP

Since I went from the lwjgl window to the AWTGLCanvas (to get access to awt.Graphics) I've been getting this exception thrown at random times in my program a few seconds into it. I imagine it's some sort of thread synchronization issue, but I'm not quite sure how to solve it. The following are the lines that seem to cause it:
else {//IF HARDWARE RENDERER
      Graphics canvasG = awtGlCanvas.getGraphics();
      buffer.display(canvasG);
      this.paint(this.getGraphics());
      awtGlCanvas.paint(canvasG);
}

EgonOlsen

You seem to call the canvas' paint-method directly, which is highly dubios. The same seems to apply for this.paint(). Have a look at the HelloWorldAWTGL example on how it's meant to be used. Maybe that will help to get rid of this exception.

AGP

Oh, for some reason I thought displayGLOnly() could only be used with the lwjgl frame. So I changed back to repaint() and used displayGLOnly() and that did it, thanks. And I was using paint(Graphics) in an effort to avoid the error, which was being caused even when repaint() was called with the display(canvas.getGraphics()) call.

AGP

Actually, I'm beginning to think it's the following method (though the JVM's message doesn't get that far). Note that I left commented-out code that isn't always commented out. Just before the ArrayIndexOutOfBoundsException, "Left drawAxisRep()" doesn't get printed. And yes, it only happens with the hardware renderer:

      private void drawAxisRep() {
SimpleVector position = xWing.getTransformedCenter();
SimpleVector xPoint1 = Interact2D.project3D2D(camera, buffer, new SimpleVector(position.x-8f, position.y, position.z));
SimpleVector xPoint2 = Interact2D.project3D2D(camera, buffer, new SimpleVector(position.x+8f, position.y, position.z));
SimpleVector yPoint1 = Interact2D.project3D2D(camera, buffer, new SimpleVector(position.x, position.y-8f, position.z));
SimpleVector yPoint2 = Interact2D.project3D2D(camera, buffer, new SimpleVector(position.x, position.y+8f, position.z));
SimpleVector zPoint1 = Interact2D.project3D2D(camera, buffer, new SimpleVector(position.x, position.y, position.z-8f));
SimpleVector zPoint2 = Interact2D.project3D2D(camera, buffer, new SimpleVector(position.x, position.y, position.z+8f));
Graphics2D g = null;
// if (software)
      g = (Graphics2D)buffer.getGraphics();
/* else {
      Drawable drawable = Display.getDrawable();
      if (drawable instanceof AWTGLCanvas)
// g =(Graphics2D) ((AWTGLCanvas)drawable).getGraphics();
g = awtGlCanvas.getGraphics();
}
*/
if (g == null)
      return;
g.setStroke(new BasicStroke(4));
g.translate(300, 200);
g.setColor(Color.red);
g.drawLine((int)xPoint1.x, (int)xPoint1.y, (int)xPoint2.x, (int)xPoint2.y);
g.setColor(Color.green);
g.drawLine((int)yPoint1.x, (int)yPoint1.y, (int)yPoint2.x, (int)yPoint2.y);
g.setColor(Color.blue);
g.drawLine((int)zPoint1.x, (int)zPoint1.y, (int)zPoint2.x, (int)zPoint2.y);
System.out.println("Left drawAxisRep().");
      }

EgonOlsen

Drawing into the canvas from outside the AWT event dispatch thread is very questionable. Try to put that code in an IPaintListener in one of the methods depending on when you want to draw it. That ensures that all the painting happens in one thread. I'm not sure if you can paint in an AWTGLCanvas anyway, but i've never tried...