Swing unresponsive with SimpleCanvas


I am developing a jME application in which a 3D canvas will need to be embedded in a Swing application. I tried running the example "jmetest.util.JMESwingTest.java" from the 2.0.1 stable distribution on two linux variants: "debian 5.03 amd64" and "openSUSE 11.2 x86_64", but the Swing buttons/jtree are not responsive. However, the 3D canvas with the rotating 3D block & monkey display fine and continue to rotate smoothly. To be more specific:

In debian:

symptom: The swing elements only respond after several clicks. When the window is resized, there is a 1-2 second lag before the components are scaled.

java: sun Java 1.5.0_22

jME: 2.0.1 distribution with the correct native libraries

In openSUSE:

symptom: I've tried clicking the same button for a minute, with no response. When the window is resized, the components never scale, and may not redraw.

java: openJDK 1.6.2

jME: 2.0.1 distribution with the correct native libraries

Can anyone think of a reason for this problem? Or, better yet, know of a fix?

Please let me know if there's important info I've left out.

  • Thank you!

I believe I have figured out the problem.

In the class "com.jmex.awt.lwjgl.LWJGLCanvas", the paintGL() method, which I'm guessing is called in the Swing event thread, has a Thread.sleep() in it. It looks like the sleep() is used to enforce the frame rate. In other words, the paintGL() method: performs the redrawing, sleeps for a duration required to delay until the next frame, then calls repaint().

For some reason I can run "JMESwingTest.java" fine on the Windows and Macs I've tried it on, but it really ties up the Swing event dispatcher on the two listed linux distributions.

I have hacked together a fix for this that removes the call to sleep(). Instead, periodic calls to repaint() are made through a swing Timer. This doesn't do as good a job at enforcing the frame rate as the original code due both to the nature of how the timer works and the fact that the timer only has ms resolution. BUT… JMESwingTest.java and my own application run smoothly on Windows, Mac, openSuse, and Debian.

Since I didn't dive into the code in detail, I thought I would wait before posting my hack, to see if anybody else agrees with my interpretation. I don't want to mislead anyone if my sleep-deprived analysis is incorrect.

  • Thanks.

I had the same issue (Ubuntu amd64). I can confirm that the sleep() call in the paintGL method of LWJGLCanvas is a bug: you can’t really call sleep in the AWT Event Dispatcher Thread.

What i can’t figure out is why this doesn’t cause problems in Windows of Mac. Maybe the swallowed InterruptedException has something to do with that but i didn’t tested it.

I’ve used a timer too (removing the sync stuff in a subclass of LWGLCanvas) and it works. A better solution would be to change the rendering loop to be “edt aware”.

BTW, JME3 has the same symptom. Nope, maybe a false alarm.