Search code examples
javaswingawtjogl

First GLWindow in first NewtCanvasAWT doesn't get .repaint(), when there are other windows


I have two JOGL native GLWindows wrapped in NewtCanvasAWT.

These canvases are added to JInternalFrames each. JInternalFrames are added to JDesktopPane which is added to a JFrame.

I don't have an Animator running because .display() is called manually, when scene changes.


This setup works as expected apart from one thing:

  • when the second JInternalFrame (order of creation) moves over the first, the first is not repainted, what is quite unexpected,

  • when the first moves over the second, the second is repainted, as expected.

  • If I add more frames, only the last one behaves as expected.

The JInternalFrames are identical (the same class).

The first GLWindow doesn't receive WindowUpdateEvent in WindowListener.windowRepaint(). The second one does.

Here's the stack trace of my GLEventListener.display(GLAutoDrawable drawable) from the working JInternalFrame:

java.lang.IllegalArgumentException: test
    at edu.agh.tunev.ui.opengl.Scene.display(Scene.java:42)
    at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:373)
    at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:358)
    at jogamp.opengl.GLAutoDrawableBase$2.run(GLAutoDrawableBase.java:280)
    at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:655)
    at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:594)
    at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:543)
    at jogamp.opengl.GLAutoDrawableBase.defaultWindowRepaintOp(GLAutoDrawableBase.java:99)
    at com.jogamp.newt.opengl.GLWindow.access$000(GLWindow.java:94)
    at com.jogamp.newt.opengl.GLWindow$1.windowRepaint(GLWindow.java:107)
    at jogamp.newt.WindowImpl.consumeWindowEvent(WindowImpl.java:2392)
    at jogamp.newt.WindowImpl.consumeEvent(WindowImpl.java:1943)
    at jogamp.newt.DisplayImpl.dispatchMessage(DisplayImpl.java:388)
    at jogamp.newt.DisplayImpl.dispatchMessages(DisplayImpl.java:436)
    at jogamp.newt.DisplayImpl$DispatchMessagesRunnable.run(DisplayImpl.java:371)
    at jogamp.newt.DefaultEDTUtil$EventDispatchThread.run(DefaultEDTUtil.java:293)

This should also happen with the first frame. Why doesn't it?


All this does not happen when using GLJPanel or GLCanvas. However, I do not want to use AWT thread for rendering and these GLAutoDrawables use it. NEWT native windowing toolkit uses another thread.


Solution

  • OK. This is a bug in JOGL.

    I ended up adding a listener to JDesktopPane, that listens for JInternalFrame adds. If added frame contains GLWindow, it remembers a reference to it in a List. It also adds a shared ComponentListener to every JInternalFrame. Upon componentHidden/componentMoved/componentResized/componentShown events, all previously remembered GLWindows are refreshed.

    Edit: refreshing is implemented by invoking .display() method on GLWindow (inherited from GLAutoDrawable).