Canvas in JInternalFrame will render, but only once

(For the impatient ones: this question is very likely not related to any light / heavyweight overlapping issues in Swing; I know it doesn’t work) 





Hi,



I have the following problem. I’m writing kind of a dashboard in Java using JInternalFrames as the main widget class. Now I tried to include a 3D widget as well.



I read some tutorials in here and created a canvas which I placed inside this frame, set up an Implementor for the scene and everything seems to render fine: I have multiple widgets, some swing, and one 3D one sitting nicely besides each other.



However, the problems start as soon as the 3D widget looses focus and gains it again. In this case, it turns black instantly and will never ever render again anything.



Please see this movie:



http://data.xeoh.net/jmerenderingproblems.mov




  • First you can see the the application starting up.
  • Next you will see the yellow 3d widget (the color is the bgColor of the JInternalFrame for debugging purposes)
  • After a couple of seconds a timer will initialize 3d (it's a hack too, as I'm currently unable to initialize the canvas when the dashboard didn't become active yet)
  • Now the 3d scene is rendered, all fine up to here.


  • Next you will see the dashboard deactivated for a short moment (set hidden) and activated again. As you will notice, the scene still draws perfectly.


  • However, problems start as soon as I click another JInternalFrame and switch back. The moment the 3d frame has the focus again, the scene will turn black (neither the background color of the jinternalframe (yellow), nor of the scene (blue)). No matter what I do, the rendering won't come back unless the application is being restarted.





    The code for the internal frame is this:







public class Shell extends JInternalFrame {
    final Logger logger = Logger.getLogger(this.getClass().getName());

    private static final long serialVersionUID = -375860182685605900L;

    final PluginManager pluginManager;

    private Canvas canvas;

    public Shell(PluginManager pluginManager) {
        this.pluginManager = pluginManager;

        initGUI();
        // initOpenGL();
    }

    // This method will be called by a timer approx 3 secs. after startup.
    public void initOpenGL() {
        DisplaySystem displaySystem = DisplaySystem.getDisplaySystem("lwjgl");

        this.canvas = displaySystem.createCanvas(getWidth(), getHeight());

        JMECanvas jmeCanvas = (JMECanvas) this.canvas;

        jmeCanvas.setImplementor(new MyImplementor(getWidth(), getHeight()));

        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(this.canvas, BorderLayout.CENTER);
    }

    private void initGUI() {
        setTitle("3D Test");
        setSize(300, 300);

        setVisible(true);
        setIconifiable(true);

        getContentPane().setBackground(Color.YELLOW);
    }

}




And the Implementor:


class MyImplementor extends SimpleCanvasImpl {

    private Quaternion rotQuat;
    private final float angle = 0;
    private Vector3f axis;
    private Box box;
    long startTime = 0;
    long fps = 0;
    private InputHandler input;

    public MyImplementor(int width, int height) {
        super(width, height);
    }

    @Override
    public void simpleSetup() {
        this.renderer.setBackgroundColor(ColorRGBA.blue);

        // Normal Scene setup stuff...
        this.rotQuat = new Quaternion();
        this.axis = new Vector3f(1, 1, 0.5f);
        this.axis.normalizeLocal();

        Vector3f max = new Vector3f(5, 5, 5);
        Vector3f min = new Vector3f(-5, -5, -5);

        this.box = new Box("Box", min, max);
        this.box.setModelBound(new BoundingBox());
        this.box.updateModelBound();
        this.box.setLocalTranslation(new Vector3f(0, 0, -10));
        this.box.setRenderQueueMode(Renderer.QUEUE_SKIP);
        this.rootNode.attachChild(this.box);

        this.box.setRandomColors();

        // this.rootNode.setRenderState(ts);
        this.startTime = System.currentTimeMillis() + 5000;
    }
}



Does anyone have any idea what I can do to make the frame render properly?

Many thanks in advance
-Ralf


What I found out so far:

If I overwrite doRender() to this:

@Override
public void doRender() {
        this.renderer.setBackgroundColor(ColorRGBA.blue);
        super.doRender();
}

the screen will at least turn blue; however, still no other content is being drawn. Any ideas, anyone ?

Sorry, no ideas come to me without actually finding some time to do an in depth test.  :frowning: