What is the problem of my code?

You can try to run my code.

My code is ok if you only press the buttons below ten times, but when you press it very fast and alots time you always get a error message.

here is the error message:

Scene graph is not properly updated for rendering. State was changed after rootNode.updateGeometric State() call. Make sure you do not modify the scene from another thread!Problem spatial name: Root Node



Does anyone can help me? Thanks!


package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
* you can embed a jme canvas inside a swing application
*
* @author harry1315
*/
public class Main extends SimpleApplication {

static int event = 0;
static int[] f = new int[5];
Geometry cube_0 = new Geometry();
Geometry cube_1 = new Geometry();
Geometry cube_2 = new Geometry();
Geometry cube_3 = new Geometry();
Geometry cube_4 = new Geometry();

public void show() {
rootNode.detachAllChildren();
if (event == 0) {
if (f[0] == 0) {
Box b0 = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry geom0 = new Geometry("Box0", b0);
Material mat0 = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md");
mat0.setColor("Color", ColorRGBA.Yellow);
geom0.setMaterial(mat0);
cube_0 = geom0;
rootNode.attachChild(cube_0);
} else {
rootNode.attachChild(cube_0);

}
}
if (event == 1) {
if (f[1] == 0) {
Box b1 = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry geom1 = new Geometry("Box1", b1);
Material mat1 = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md");
mat1.setColor("Color", ColorRGBA.Blue);
geom1.setMaterial(mat1);
cube_1 = geom1;
rootNode.attachChild(cube_1);
} else {
rootNode.attachChild(cube_1);

}
}
if (event == 2) {
if (f[2] == 0) {
Box b2 = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry geom2 = new Geometry("Box2", b2);
Material mat2 = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md");
mat2.setColor("Color", ColorRGBA.White);
geom2.setMaterial(mat2);
cube_2 = geom2;
rootNode.attachChild(cube_2);
} else {
rootNode.attachChild(cube_2);
}
}
if (event == 3) {
if (f[3] == 0) {
Box b3 = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry geom3 = new Geometry("Box3", b3);
Material mat3 = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md");
mat3.setColor("Color", ColorRGBA.Green);
geom3.setMaterial(mat3);
cube_3 = geom3;
rootNode.attachChild(cube_3);
} else {
rootNode.attachChild(cube_3);
}
}
if (event == 4) {
if (f[4] == 0) {
Box b4 = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry geom4 = new Geometry("Box4", b4);
Material mat4 = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md");
mat4.setColor("Color", ColorRGBA.Red);
geom4.setMaterial(mat4);
cube_4 = geom4;
rootNode.attachChild(cube_4);
} else {
rootNode.attachChild(cube_4);
}
}
}

@Override
public void simpleInitApp() {
// activate windowed input behaviour
flyCam.setDragToRotate(true);
// display a cube
show();
}

public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
f = 0;
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
// create new JME appsettings
AppSettings settings = new AppSettings(true);
settings.setWidth(640);
settings.setHeight(480);

// create new canvas application
final Main app = new Main();
app.setSettings(settings);
app.createCanvas(); // create canvas!
JmeCanvasContext ctx = (JmeCanvasContext) app.getContext();
ctx.setSystemListener(app);
Dimension dim = new Dimension(640, 480);
ctx.getCanvas().setPreferredSize(dim);

// Create Swing window
JFrame window = new JFrame("Swing Application");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// Fill Swing window with canvas and swing components
JPanel panel = new JPanel(new GridLayout(0, 1)); // a panel
JPanel canvas = new JPanel();
JPanel mainPanel = new JPanel(new FlowLayout());
canvas.add(ctx.getCanvas());
JButton but0 = new JButton("Character");
JButton but1 = new JButton("Skills");
JButton but2 = new JButton("Equips");
JButton but3 = new JButton("Items");
JButton but4 = new JButton("option");
but0.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
event = 0;
app.show();
}
});
but1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
event = 1;
app.show();
}
});
but2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
event = 2;
app.show();
}
});
but3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
event = 3;
app.show();
}
});
but4.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
event = 4;
app.show();
}
});
panel.add(but0); // add some Swing
panel.add(but1);
panel.add(but2);
panel.add(but3);
panel.add(but4);
mainPanel.add(canvas);
mainPanel.add(panel);
window.add(mainPanel);
window.pack();

// Display Swing window including JME canvas!
window.setVisible(true);
app.startCanvas();
}
});
}
}

Because you change the scenegraph from the awt thread. Best use nifty as a gui if you have problems understanding the multithreading docs and enqueueing of calls.

but0.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

event = 0;

app.show(); // this is made in other thread. need to be synchronized

}

});



edit:



like normen said

I have problem with using nifty because it does not support other language such as Chinese

here is my other post:

http://hub.jmonkeyengine.org/groups/gui/forum/topic/how-to-display-chineseor-other-language-by-using-nifty-gui/



In nifty, I can use bitmap font but it still cannot use in button name, label name and so on.

Therefore, I try to use Swing for the gui.

The answers to your questions are: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:multithreading



You should also read up on the Swing Threading Model.