Thread problem with JMEDesktop - random?

can you post a small example to reproduce the problem?

Its the fastest way to identify the problem.

well, i posted my code above.



but here is a shortened version, only one file

you need the JME jars and the JME Librarys to start this…but everyone here knows that i think g



when you execute this, you'll see the following: some times a blue desktop is shown…or only 2 boxes which should symbolize the montage plattform of the desktop. if you hit "b" you see a quad where the desktop should be / or is




package desktoptests;
import java.awt.Color;
import java.util.concurrent.Callable;
import javax.swing.JDesktopPane;
import javax.swing.SwingUtilities;
import com.jme.app.SimpleGame;
import com.jme.input.InputHandler;
import com.jme.input.KeyboardLookHandler;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.util.GameTaskQueueManager;
import com.jmex.awt.swingui.JMEDesktop;


public class SimpleDesktopArray extends SimpleGame {

   /**
    * @param args
    */
   public static void main(String[] args) {
      // TODO Auto-generated method stub

      new SimpleDesktopArray().start();
   }
   
   public SimpleDesktopArray()
   {
      this.setDialogBehaviour(SimpleDesktopArray.FIRSTRUN_OR_NOCONFIGFILE_SHOW_PROPS_DIALOG);
   }

   
   
   @Override
   protected void simpleInitGame() {

      InputHandler handlerForDefaultKeyActions = input;
        handlerForDefaultKeyActions.removeAllFromAttachedHandlers();
       
        // input handler
        input = new InputHandler();
        input.addToAttachedHandlers( handlerForDefaultKeyActions );
       
        //cn = new CameraNode("cn", display.getRenderer().getCamera());
       //rootNode.attachChild(cn);
       
        KeyboardLookHandler lookHandler = new KeyboardLookHandler( cam, 50,1 );
        input.addToAttachedHandlers( lookHandler );
      
      /////////////////////////////////////////
        /////////////////////////////////////////
       
        final DesktopExecutor exec[] = new DesktopExecutor[3];
       
        exec[1] = new DesktopExecutor()
        {
           public void run()
           {
            JDesktopPane pane = desktoppane;
            
            pane.setBackground(Color.blue);
            
            pane.validate();
            pane.repaint();
           }
        };
        exec[0] = new DesktopExecutor()
        {
           public void run()
           {
            JDesktopPane pane = desktoppane;
            
            pane.setBackground(Color.blue);
            
            pane.validate();
            pane.repaint();
           }
        };
    
        final int DesktopCount = 2;
        final int dist = 200;
        final int size = 300;
        final int height = 10;
        final float angle=45f;
       
       
      final Node desktops[] = new Node[DesktopCount];
      final Node all = new Node();
      
      
      GameTaskQueueManager.getManager().update(
            
         new Callable<Object>() {
         public Object call() throws Exception {
            
            
            for (int i=0; i<DesktopCount; i++)
            {
               desktops[i] = new Node();
               
               //creating the JMEDEsktop
               JMEDesktop t = new JMEDesktop("Desktop", size*2, size*2, input);
               
               // starting the Swing UI-Creation
               exec[i].setDesktopPane(t.getJDesktop());
               SwingUtilities.invokeLater(exec[i]);
               //SwingUtilities.invokeAndWait(executors[i]);
               
               // moving the JMEDesktop and the box to the right place
               t.getLocalRotation().fromAngles(-angle * FastMath.DEG_TO_RAD, 0, 0);
               t.setLocalTranslation(0, height + size* FastMath.sin(FastMath.DEG_TO_RAD * angle),-size * FastMath.cos(FastMath.DEG_TO_RAD*angle));

               Box b = new Box("Box Desktop",new Vector3f(0,0,0), size, height, 1);
               
               desktops[i].attachChild(t);
               desktops[i].attachChild(b);
               
               // arranging the Desktop + Box in a circle
               desktops[i].setLocalTranslation(dist * FastMath.sin(i*360f/DesktopCount * FastMath.DEG_TO_RAD),
                     0,
                     dist * FastMath.cos(i*360f/DesktopCount * FastMath.DEG_TO_RAD));
               desktops[i].getLocalRotation().fromAngleAxis(180 * FastMath.DEG_TO_RAD + i*360f/DesktopCount * FastMath.DEG_TO_RAD, new Vector3f(0,1,0));



               all.attachChild(desktops[i]);
               all.updateRenderState();
               
            }
            all.updateRenderState();
            
            all.lock();
            all.setLocalScale(0.2f);
            
            rootNode.attachChild(all);
            
            return null;
         }
        });
       
       
       
       
   }

   
   protected void simpleRender()
   {
      super.simpleRender();
      
      //DisplaySystem.getDisplaySystem().getRenderer().clearBuffers();
      
      //test.render();
   }
   
   protected void simpleUpdate()
   {
      super.simpleUpdate();
      
      //test.update();
   }
   
   public abstract class DesktopExecutor implements Runnable {

      protected JDesktopPane desktoppane;
      
      public void setDesktopPane(JDesktopPane pane)   
      {
         desktoppane = pane;
      }
      
      public JDesktopPane getDesktopPane()
      {
         return desktoppane;
      }
      
      public abstract void run() ;
   }

}

I took a look at your code, and I am left wondering.  What are you trying to accomplish?



First it looks as though you are trying to use the GameTaskQueueManager, as was stated before ONLY StandardGame uses this functionality.  You are still using SimpleGame.

Second, it looks as though you are trying to put into the OpenGL thread a call to the Swing Thread.  I really don't know if this is what you should be doing.



My advice to you would be to immediately implement StandardGame, so you can take advantage of the GameTaskQueueManager.  If you are actually working on a would-be 'finished' product; complete with audio, load screens and game menus, etc., you will need the functionality it can provide.  After that ask yourself what exactly is the end goal that you are trying to get JmeDesktop to do.  If it's just to have multiple frames displayed in one GUI I think you just need 1 JmeDesktopState.  If it is to have multiple JmeDesktop states then you must extend StandardGame or implement your own JmeBase class that uses GameTaskQueueManager.

ok, that's a word :wink:



I'll try it with the StandardGame…



My target was to create multiple desktops for an ui environment around the player



why the swing thread - swing ui should only be accessed in a swing event dispatcher thread, which is imho not the normal game thread nor the OGL Thread, so it needs to be invoked into the Swing thread. But I have got nearly to no clue to multithreading and its problem, so correct me please!

With SimpleGame there is only ONE thread, the OpenGL thread.  With standard Game, a new thread is spawned which takes over the OpenGL responsibilities (such as calling update() and render()). (Someone correct me if I am wrong please)



So with your example, your Swing thread call is accomplished in the OpenGL thread.  In standard game a call to the Swing thread would be outside the OpenGL thread, unless you use GameTaskQueueManager.



When you say multiple desktops, do you mean multiple frames?

well…i tried it…



i created a StandardGame, started it and created my PhysicsGameState - so i should have what you have explained.



in this gamestate i tried to created a JMEDesktop - which gave me a NullPointerexception, as it should as the Desktop isn't created in the OGL thread ( creation in the constructor of the Gamestate)



Then i invoked the creation code of the JMEDesktop into the OGL Thread - the boxes are there, no error.

the i invoked my swing code via Swingutilities into a swing event dispatcher thread.

jmedesktops are still only visible some times…i also tried simply starting the thread by new Thread(runnable).start();, but it's still only visible some times.



I don't really now what you mean by frames, but i want to have several JMEDesktops at different places in my gamestate, so the player could walk to one edge to access the options, for example.

I don't use jME desktop, but from what I gather there should be only one DesktopState, frames I think is really what you a want to use. (frames=bordered windows possibly with a little close button in the top-left corner)



If you are not familiar with Swing then you might want to take a look at that, jME desktop is just rendering a Swing GUI then rendering it to a texture and places it on a quad.