Search code examples
javamultithreadingsocketsjmonkeyengine

Thread in JME doesn't work


In JME I try to use threading but when I run the program the function never starts.

I have a server socket who is listening to input from Netbeans.

Listener

while (isRunning) {
            //Reads and prints the input
            String receivedString = (String) in.readObject();

            System.out.println(receivedString);

            String[] parts = receivedString.split(";");

            if(parts[0].equals("craneCon"))
            {
                final int containerId = Integer.parseInt(parts[1]);
                m.enqueue(new Callable<Spatial>(){
                    public Spatial call() throws Exception{                        
                        m.removeContainersFromMaritime(containerId);
                        return null;
                    }
                });
            }

So in the main there is the function removeContainersFromMaritime

public void removeContainersFromMaritime(final int idContainer)
    {
        Node container = Maritime.listOfContainers.get(idContainer);

        martime.detachChild(Maritime.listOfContainers.get(idContainer));
        seagoingcrane.attachChild(Maritime.listOfContainers.get(idContainer));

        container.setLocalTranslation(0,5,0);
        System.out.println(Maritime.listOfContainers.get(0).getWorldTranslation().z);

    }

The connection is alright but the method is never executed. How can I fix this?


Solution

  • jMonkeyEngine uses a swing-style threading model where there is a single render thread that does all the work. Any changes to the scene graph have to be done from that render thread.

    To get into the render thread you can implement AppStates, Controls or you can enqueue Callables which are then executed on the render thread in a similar way to Swing's invokeLater.

    The code snippet you posted looks about right, so assuming m is your running jME3 SimpleApplication then m.enqueue() will cause the enqueued callable to be executed next time around the render loop (i.e. at the start of the next frame).

    If you are not seeing it executed then either:

    1. Your application is not running
    2. You created more than one application and enqueued it to the wrong one
    3. The code is actually running and you just think it isn't.

    Stepping through the code in the debugger and/or adding debug statements (for example breakpoint inside removeContainersFromMaritime to see if it is actually called should allow you to narrow this down.