Hello all!
I discovered JME and have to say, I absolutely love it! Now I try to get JME running stable on the Netbeans Platform (like the JME SDK does it), with no fancy stuff for a start.
So I extend a SimpleAmplication, instantiate and initialize it and attach its canvas to a JPanel and the panel to a TopComponent (a window in the Netbeans Platform).
But if I try to close the Netbeans application, the app freezes. It also does when I try to close the TopComponent window, even if I just call SimpleApplication.stop() from somewhere.
That’s the exception I always get:
SEVERE [com.jme3.app.Application]: Uncaught exception thrown in Thread[LWJGL Renderer Thread,6,IDE Main] java.lang.AssertionError at com.jme3.util.NativeObjectManager.deleteAllObjects(NativeObjectManager.java:201) at com.jme3.renderer.lwjgl.LwjglRenderer.cleanup(LwjglRenderer.java:413) at com.jme3.system.lwjgl.LwjglCanvas.destroyContext(LwjglCanvas.java:376) at com.jme3.system.lwjgl.LwjglCanvas.pauseCanvas(LwjglCanvas.java:247) at com.jme3.system.lwjgl.LwjglCanvas.runLoop(LwjglCanvas.java:203) at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228) [catch] at java.lang.Thread.run(Thread.java:722) BUILD STOPPED (total time: 35 seconds)
Here’s my SimpleApplication:
[java]
public class AppTry extends SimpleApplication {
private static AppTry uniqueApp = null;
private static Canvas mainCanvas = null;
private static JmeCanvasContext canvasContext = null;
protected AppTry() {/*Defeat instantiation*/}
public static AppTry getUniqueApp() {
if (uniqueApp == null) {
uniqueApp = new AppTry();
}
return uniqueApp;
}
@Override
public void simpleInitApp() {
attachWireBox(Vector3f.ZERO, 1.0f, ColorRGBA.Blue, rootNode);
flyCam.setDragToRotate(true);
flyCam.setMoveSpeed(4.0f);
}
public static Canvas getMainCanvas() {
if (mainCanvas == null) {
getUniqueApp().createCanvas();
AppSettings settings = new AppSettings(true);
settings.setFrameRate(30);
getUniqueApp().setPauseOnLostFocus(false);
getUniqueApp().setSettings(settings);
mainCanvas = getMainCanvasContext().getCanvas();
}
return mainCanvas;
}
public static AppTry getUniqueApp() {
if (uniqueApp == null) {
uniqueApp = new AppTry();
}
return uniqueApp;
}
public void attachWireBox(Vector3f pos, float size, ColorRGBA color, Node attachTo) {
putShape(new WireBox(size, size, size), "Wireframe Cube", color, pos, attachTo);
}
private Geometry putShape(Mesh shape, String shapeName, ColorRGBA color, Vector3f position, Node attachTo) {
Geometry g = new Geometry(shapeName, shape);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.getAdditionalRenderState().setWireframe(true);
mat.setColor("Color", color);
g.setMaterial(mat);
g.setLocalTranslation(position);
attachTo.attachChild(g);
return g;
}
@Override
public void stop() {
super.stop();
mainCanvas = null;
canvasContext = null;
}
@Override
public void stop(boolean waitFor) {
super.stop(waitFor);
mainCanvas = null;
canvasContext = null;
}
}
[/java]
And here’s the TopComponent:
[java]
**
-
Top component which displays something.
/
@TopComponent.Description(
preferredID = “JmeTestTopComponent”,
persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = “editor”, openAtStartup = false)
@ActionID(category = “Window”, id = “org.jmetest.JmeTestTopComponent”)
@ActionReference(path = “Menu/Window” /, position = 333 */)
@TopComponent.OpenActionRegistration(
displayName = “#CTL_JmeTestAction”,
preferredID = “JmeTestTopComponent”)
@Messages({
“CTL_JmeTestAction=JmeTest”,
“CTL_JmeTestTopComponent=JmeTest Window”,
“HINT_JmeTestTopComponent=This is a JmeTest window”
})
public final class JmeTestTopComponent extends TopComponent {private static SimpleApplication simApp;
private static Canvas canvas;public JmeTestTopComponent() {
initComponents();
setName(Bundle.CTL_JmeTestTopComponent());
setToolTipText(Bundle.HINT_JmeTestTopComponent());
setFocusable(true);simApp = AppTry.getUniqueApp(); canvas = AppTry.getMainCanvas(); jPanelCanvas.setMinimumSize(new java.awt.Dimension(10, 10)); jPanelCanvas.setLayout(new BorderLayout()); jPanelCanvas.setFocusable(false); jPanelCanvas.add(canvas, BorderLayout.CENTER);
}
private void initComponents() {
// Swing compontent initialization
…
}private void jButtonKillActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonKillActionPerformed
jPanelCanvas.remove(canvas);
simApp.enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
simApp.stop(true);
return null;
}
});
}
//GEN-LAST:event_jButtonKillActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton jButtonKill;
private javax.swing.JPanel jPanelBar;
private javax.swing.JPanel jPanelCanvas;
private javax.swing.JToolBar jToolBar;
// End of variables declaration//GEN-END:variables@Override
public void componentOpened() {
// super.componentOpened();
}@Override
public void componentClosed() {
// super.componentClosed();
// simApp.stop(true);
}
}
[/java]
As you can see, I tried simApp.stop(true) in the componentClosed() method. I also tried calling stop() within a callable with simApp.enque(…). The error also occurs if I didn’t attach anything to the root node.
I also looked into com.jme3.gde.core.scene.SceneApplication.java and com.jme3.gde.core.sceneviewer.SceneViewerTopComponent.java (from the JME SDK Core module sources), where a JME3 canvas also gets integrated into a TopComponent of the Netbeans Platform, but I couldn’t find what I should do differently when closing the application.
Do you see why it freezes when I try to close and how to prevent it, am I missing something? Or have you got some pointers on how to cleanly integrate JME3 into the Netbeans Platfrom?
Thank you for reading!
(Some side info: jME3_2013-05-26, Netbeans 7.3.1, JRE 1.7_21 on Win8 running in x86)