SimpleJMEApplet GUI

I didn't know where to put this. I figured since it involved applets it would work here, because it has more to do with the SimpleJMEApplet class more then anything. I'll start off with providing the source, pretty simple:

public class Main extends SimpleJMEApplet {
    private Spatial t;
    public void simpleAppletSetup() {
        t = new Box("Box", new Vector3f(0,0,0),1,1,1);
        t.setModelBound(new BoundingBox());
        t.updateModelBound();
        getRootNode().attachChild(t);
        JButton button = new JButton("Click!");
        this.add(button);
    }
}


Adds a box and a Swing button. Not too complicated. But the problem is I run this, and I can't see my button! Do I have to enable something, or did I add it wrong? :-o

Yay, I am sure it is the code. I tried it in a normal applet, just the button, and it didn't work. So it is me, not JME.

When not specifying a layout manager for your applet, you may have to give your button a location to make it show up.

button.setLocation(x, y);


I'm not sure if this will work with the JMEApplet though, if that's a heavyweight component you won't be able to see the button.

It didn't work.  :frowning: Can I use a JMEDesktop to do it?

I tried to do JMEDesktop in my applet. It turned out with an error! Oh noes! And only with the applet, too. Here is the code:

ublic class Main extends SimpleJMEApplet {

    private Spatial t;
    public static Node guiNode;

    @Override
    public void simpleAppletSetup() {
        guiNode = new Node("gui");
        guiNode.setRenderQueueMode(Renderer.QUEUE_ORTHO);
        final JMEDesktop desktop = new JMEDesktop("desktop", 500, 400, getInputHandler());
        guiNode.attachChild(desktop);
        desktop.getLocalTranslation().set(getWidth() / 2 - 30, getHeight() / 2 + 50, 0);
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                desktop.getJDesktop().setBackground(new Color(0, 0, 1, 0));
                final JButton button = new JButton("click me");
                desktop.getJDesktop().add(button);
                button.setLocation(200, 200);
                button.setSize(button.getPreferredSize());
                button.addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        button.setLocation(FastMath.rand.nextInt(400), FastMath.rand.nextInt(300));
                    }
                });
                button.addActionListener(new JMEAction("my action", getInputHandler()) {

                    public void performAction(InputActionEvent evt) {
                        guiNode.updateRenderState();
                    }
                });
            }
        });
        guiNode.setCullHint(Spatial.CullHint.Never);
        guiNode.setLightCombineMode(Spatial.LightCombineMode.Off);
        guiNode.updateRenderState();
        guiNode.updateGeometricState(0, true);
        t = new Box("Box", new Vector3f(0, 0, 0), 1, 1, 1);
        t.setModelBound(new BoundingBox());
        t.updateModelBound();
        getRootNode().attachChild(t);
    }

    public void simpleAppletRender() {
        getRenderer().draw(guiNode);
    }
}


And the error:

Exception in thread "AWT-EventQueue-1" java.lang.Error: Cannot call invokeAndWait from the event dispatcher thread
        at java.awt.EventQueue.invokeAndWait(EventQueue.java:980)
        at javax.swing.SwingUtilities.invokeAndWait(SwingUtilities.java:1323)
        at com.jmex.awt.swingui.JMEDesktop.onButton(JMEDesktop.java:452)
        at com.jmex.awt.swingui.JMEDesktop$ButtonAction.performAction(JMEDesktop.java:1172)
        at com.jme.input.ActionTrigger.performAction(ActionTrigger.java:264)
        at com.jme.input.InputHandler.processTriggers(InputHandler.java:426)
        at com.jme.input.InputHandler.update(InputHandler.java:411)
        at com.jme.input.InputHandler.updateAttachedHandlers(InputHandler.java:440)
        at com.jme.input.InputHandler.update(InputHandler.java:412)
        at com.jmex.awt.applet.SimpleJMEApplet$SimpleAppletCanvasImplementor.simpleUpdate(SimpleJMEApplet.java:340)
        at com.jme.system.canvas.SimpleCanvasImpl.doUpdate(SimpleCanvasImpl.java:135)
        at com.jmex.awt.lwjgl.LWJGLCanvas.paintGL(LWJGLCanvas.java:130)
        at org.lwjgl.opengl.AWTGLCanvas.paint(AWTGLCanvas.java:290)
        at org.lwjgl.opengl.AWTGLCanvas.update(AWTGLCanvas.java:321)
        at sun.awt.RepaintArea.updateComponent(RepaintArea.java:239)
        at sun.awt.RepaintArea.paint(RepaintArea.java:216)
        at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:301)
        at java.awt.Component.dispatchEventImpl(Component.java:4489)
        at java.awt.Component.dispatchEvent(Component.java:4243)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)


Thanks for any help in advance, I need to get this working.

Please try this patch and report if it helps:


Index: JMEDesktop.java
--- JMEDesktop.java Base (BASE)
+++ JMEDesktop.java Locally Modified (Based On LOCAL)
@@ -428,9 +428,17 @@
     //todo: reuse the runnables
     //todo: possibly reuse events, too?
 
+    private void invokeAndWaitIfNotInEDT(Runnable r) throws InterruptedException, InvocationTargetException{
+        if(SwingUtilities.isEventDispatchThread()){
+            r.run();
+        } else {
+            SwingUtilities.invokeAndWait(r);
+        }
+    }
+   
     public void onKey( final char character, final int keyCode, final boolean pressed ) {
         try {
-            SwingUtilities.invokeAndWait( new Runnable() {
+            invokeAndWaitIfNotInEDT( new Runnable() {
                 public void run() {
                     sendAWTKeyEvent( keyCode, pressed, character );
                 }
@@ -449,7 +457,7 @@
         final int awtX = (int) location.x;
         final int awtY = (int) location.y;
         try {
-            SwingUtilities.invokeAndWait( new Runnable() {
+            invokeAndWaitIfNotInEDT( new Runnable() {
                 public void run() {
                     sendAWTMouseEvent( awtX, awtY, pressed, swingButton );
                 }
@@ -468,7 +476,7 @@
         final int awtX = (int) location.x;
         final int awtY = (int) location.y;
         try {
-            SwingUtilities.invokeAndWait( new Runnable() {
+            invokeAndWaitIfNotInEDT( new Runnable() {
                 public void run() {
                     sendAWTWheelEvent( wheelDelta, awtX, awtY );
                 }
@@ -487,7 +495,7 @@
         final int awtX = (int) location.x;
         final int awtY = (int) location.y;
         try {
-            SwingUtilities.invokeAndWait( new Runnable() {
+            invokeAndWaitIfNotInEDT( new Runnable() {
                 public void run() {
                     sendAWTMouseEvent( awtX, awtY, false, MouseEvent.NOBUTTON );
                 }
@@ -1271,7 +1279,7 @@
                 inputHandler.getParent().removeFromAttachedHandlers( inputHandler );
             }
             try {
-                SwingUtilities.invokeAndWait( new Runnable() {
+                invokeAndWaitIfNotInEDT( new Runnable() {
                     public void run() {
                         desktop.removeAll();
                         awtWindow.dispose();

Sweet, thanks, I will try it.

How do I patch it?

NVM

There is no error now, but it doesn't display the Swing components.