Mouse position wrong on JMEDesktop after recreate window

after I call

display.recreateWindow(width, height, depth, freq, fullscreen);



the mouse is off, you have to click above box and to the right to get it to work. I assume the problem lies in the fact that the windows getting resized but not the JMEDesktop. I tried

desktop.resize(display.getWidth(), display.getHeight());



but it didnt work. here is example showing problem:

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;

import jmetest.awt.swingui.TestJMEDesktop;

import com.jme.app.SimpleGame;
import com.jme.input.AbsoluteMouse;
import com.jme.input.MouseInput;
import com.jme.input.action.InputActionEvent;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.state.LightState;
import com.jme.system.PropertiesIO;
import com.jmex.awt.swingui.JMEAction;
import com.jmex.awt.swingui.JMEDesktop;

/**
 * Very short example for JMEDesktop - see {@link TestJMEDesktop} for more features.
 */
public class HelloJMEDesktop extends SimpleGame {

    private Node guiNode;
    private int width, height, depth, freq;
   private boolean fullscreen;
   PropertiesIO properties;
   private AbsoluteMouse cursor;
   
    protected void simpleInitGame() {
       properties = new PropertiesIO("properties.cfg");
      width = properties.getWidth();
      height = properties.getHeight();
      depth = properties.getDepth();
      freq = properties.getFreq();
      fullscreen = properties.getFullscreen();
        // create a node for ortho gui stuff
        guiNode = new Node( "gui" );
        guiNode.setRenderQueueMode( Renderer.QUEUE_ORTHO );

        // create the desktop Quad
        JMEDesktop desktop = new JMEDesktop( "desktop", 500, 400, input );
       
        // make it transparent blue
        desktop.getJDesktop().setBackground( new Color( 0, 0, 1, 0.2f ) );
        // and attach it to the gui node
        guiNode.attachChild( desktop );
        // center it on screen
        desktop.getLocalTranslation().set( display.getWidth() / 2 - 30, display.getHeight() / 2 + 50, 0 );

        // create a swing button
        final JButton button = new JButton( "click me" );
        // and put it directly on the desktop
        desktop.getJDesktop().add( button );
        // desktop has no layout - we layout ourselfes (could assign a layout to desktop here instead)
        button.setLocation( 200, 200 );
        button.setSize( button.getPreferredSize() );
        // add some actions
        // standard swing action:
        button.addActionListener( new ActionListener() {
            public void actionPerformed( ActionEvent e ) {
                // this gets executed in swing thread
                // alter swing components ony in swing thread!
               // button.setLocation( FastMath.rand.nextInt( 400 ), FastMath.rand.nextInt( 300 ) );
                System.out.println( "clicked!" );
            }
        } );
        // action that gets executed in the update thread:
        button.addActionListener( new JMEAction( "my action", input ) {
            public void performAction( InputActionEvent evt ) {
                // this gets executed in jme thread
                // do 3d system calls in jme thread only!
               reinit();
                guiNode.updateRenderState(); // this call has no effect but should be done in jme thread :)
            }
        });
       
         // don't cull the gui away
        guiNode.setCullMode( Spatial.CULL_NEVER );
        // gui needs no lighting
        guiNode.setLightCombineMode( LightState.OFF );
        // update the render states (especially the texture state of the deskop!)
        guiNode.updateRenderState();
        // update the world vectors (needed as we have altered local translation of the desktop and it's
        //  not called in the update loop)
        guiNode.updateGeometricState( 0, true );

        // finally show the system mouse cursor to allow the user to click our button
        MouseInput.get().setCursorVisible( true );
    }
    protected void reinit() {
      display.recreateWindow(width, height, depth, freq, fullscreen);
      
   }
   
    protected void simpleRender() {
        // draw the gui stuff after the scene
        display.getRenderer().draw( guiNode );
    }

    public static void main( String[] args ) {
        new HelloJMEDesktop().start();
    }
}


how do I resize display AND JMEDesktop together? or should I dispose of JMEDesktop and create a new one?

Take a look at this topic/post.



http://www.jmonkeyengine.com/jmeforum/index.php?topic=2875.msg22001#msg22001



FYI, I'm changing the default mode as we speak though (edit: now in CVS). Too many people running into this…

well I wish I could say this fixed it but it didnt. I updated from CVS and still have same problem.

Check if it works like in the topic, with setUseDelta(false). If it does, your CVS/workspace did not update properly.

ive already tried that, Ive updated example to better show problem as its hard to explain.

I added another JMEDesktop when window is resized and it works with mouse but I cant get 1 to work alone. I know this is a crappy explantion I hope exaples are good enough.I just added the JMEDesktop creation code to the reinit() method to create another JMEDesktop on top of old one when button is pressed.

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;

import jmetest.awt.swingui.TestJMEDesktop;

import com.jme.app.SimpleGame;
import com.jme.input.AbsoluteMouse;
import com.jme.input.MouseInput;
import com.jme.input.action.InputActionEvent;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.state.LightState;
import com.jme.system.PropertiesIO;
import com.jmex.awt.swingui.JMEAction;
import com.jmex.awt.swingui.JMEDesktop;

/**
 * Very short example for JMEDesktop - see {@link TestJMEDesktop} for more features.
 */
public class HelloJMEDesktop extends SimpleGame {

    private Node guiNode;
    private int width, height, depth, freq;
   private boolean fullscreen;
   PropertiesIO properties;
   private AbsoluteMouse cursor;
    JMEDesktop desktop;
   
    protected void simpleInitGame() {
       properties = new PropertiesIO("properties.cfg");
      width = properties.getWidth();
      height = properties.getHeight();
      depth = properties.getDepth();
      freq = properties.getFreq();
      fullscreen = properties.getFullscreen();
        // create a node for ortho gui stuff
        guiNode = new Node( "gui" );
        guiNode.setRenderQueueMode( Renderer.QUEUE_ORTHO );

        // create the desktop Quad
   desktop = new JMEDesktop( "desktop", 500, 400, input );
       
        // make it transparent blue
        desktop.getJDesktop().setBackground( new Color( 0, 0, 1, 0.2f ) );
        // and attach it to the gui node
        guiNode.attachChild( desktop );
        // center it on screen
        desktop.getLocalTranslation().set( display.getWidth() / 2 - 30, display.getHeight() / 2 + 50, 0 );

        // create a swing button
        final JButton button = new JButton( "click me" );
        // and put it directly on the desktop
        desktop.getJDesktop().add( button );
        // desktop has no layout - we layout ourselfes (could assign a layout to desktop here instead)
        button.setLocation( 200, 200 );
        button.setSize( button.getPreferredSize() );
        // add some actions
        // standard swing action:
        button.addActionListener( new ActionListener() {
            public void actionPerformed( ActionEvent e ) {
                // this gets executed in swing thread
                // alter swing components ony in swing thread!
               // button.setLocation( FastMath.rand.nextInt( 400 ), FastMath.rand.nextInt( 300 ) );
                System.out.println( "clicked!" );
            }
        } );
        // action that gets executed in the update thread:
        button.addActionListener( new JMEAction( "my action", input ) {
            public void performAction( InputActionEvent evt ) {
                // this gets executed in jme thread
                // do 3d system calls in jme thread only!
               reinit();
                guiNode.updateRenderState(); // this call has no effect but should be done in jme thread :)
            }
        });
       
         // don't cull the gui away
        guiNode.setCullMode( Spatial.CULL_NEVER );
        // gui needs no lighting
        guiNode.setLightCombineMode( LightState.OFF );
        // update the render states (especially the texture state of the deskop!)
        guiNode.updateRenderState();
        // update the world vectors (needed as we have altered local translation of the desktop and it's
        //  not called in the update loop)
        guiNode.updateGeometricState( 0, true );

        // finally show the system mouse cursor to allow the user to click our button
        MouseInput.get().setCursorVisible( true );
    }
    protected void reinit() {
      display.recreateWindow(width, height, depth, freq, fullscreen);
      
      
      
desktop = new JMEDesktop( "desktop", 500, 400, input );
       
        // make it transparent blue
        desktop.getJDesktop().setBackground( new Color( 0, 0, 1, 0.2f ) );
        // and attach it to the gui node
        guiNode.attachChild( desktop );
        // center it on screen
        desktop.getLocalTranslation().set( display.getWidth() / 2 - 30, display.getHeight() / 2 + 50, 0 );

        // create a swing button
        final JButton button = new JButton( "click me" );
        // and put it directly on the desktop
        desktop.getJDesktop().add( button );
        // desktop has no layout - we layout ourselfes (could assign a layout to desktop here instead)
        button.setLocation( 200, 200 );
        button.setSize( button.getPreferredSize() );
        // add some actions
        // standard swing action:
        button.addActionListener( new ActionListener() {
            public void actionPerformed( ActionEvent e ) {
                // this gets executed in swing thread
                // alter swing components ony in swing thread!
               // button.setLocation( FastMath.rand.nextInt( 400 ), FastMath.rand.nextInt( 300 ) );
                System.out.println( "clicked!" );
            }
        } );
        // action that gets executed in the update thread:
        button.addActionListener( new JMEAction( "my action", input ) {
            public void performAction( InputActionEvent evt ) {
                // this gets executed in jme thread
                // do 3d system calls in jme thread only!
               reinit();
                guiNode.updateRenderState(); // this call has no effect but should be done in jme thread :)
            }
        });
       
         // don't cull the gui away
        guiNode.setCullMode( Spatial.CULL_NEVER );
        // gui needs no lighting
        guiNode.setLightCombineMode( LightState.OFF );
        // update the render states (especially the texture state of the deskop!)
        guiNode.updateRenderState();
        // update the world vectors (needed as we have altered local translation of the desktop and it's
        //  not called in the update loop)
        guiNode.updateGeometricState( 0, true );
      
   }
   
    protected void simpleRender() {
        // draw the gui stuff after the scene
        display.getRenderer().draw( guiNode );
    }

    public static void main( String[] args ) {
        new HelloJMEDesktop().start();
    }
}

When you reinit (which goes horribly wrong on my system for some reason, I go fullscreen with 1 FPS and horrible trippy colors, but I added some code to prevent this) you add a second JMEDesktop. Irrisor is the expert for this, but afaik you can have only 1 active JMEDesktop. With the setUseDelta(false) or latest CVS, the coordinates are now correct for the first JMEDesktop you added. However when applied to second one you added, they're wrong.

the coordinates are now correct for the first JMEDesktop you added. However when applied to second one you added, they're wrong.

I added the second one just to show the right position for the button, the coords are wrong for the first one. if you point the mouse at second button the first one is highlighted. I only need the first JMEDesktop. this is starting to sound like an Abbot and Costello routine. :wink:

edit: also after window resizing the JMEDesktop is noticably off center

I got it to work with a custom cursor, but I wasnt going to use a custom cursor just the system cursor.

how to I get the system cursor to be in same position as custom?

Ive updated this example to show difference between system and custom cursor positions.

the system and mouse cursor are shown together and they move at same rate until button is clicked then custom cursor moves at different rate but it can click box where system cursor is way off. also cursor goes behind box instead of on top not sure why.

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;

import javax.swing.JButton;

import jmetest.awt.swingui.TestJMEDesktop;

import com.jme.app.SimpleGame;
import com.jme.image.Image;
import com.jme.image.Texture;
import com.jme.input.AbsoluteMouse;
import com.jme.input.MouseInput;
import com.jme.input.action.InputActionEvent;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.system.PropertiesIO;
import com.jme.util.TextureManager;
import com.jmex.awt.swingui.JMEAction;
import com.jmex.awt.swingui.JMEDesktop;

/**
 * Very short example for JMEDesktop - see {@link TestJMEDesktop} for more features.
 */
public class HelloJMEDesktop extends SimpleGame {

    private Node guiNode;
    private int width, height, depth, freq;
   private boolean fullscreen;
   PropertiesIO properties;
   private AbsoluteMouse cursor;
    JMEDesktop desktop;
   
    protected void simpleInitGame() {
       properties = new PropertiesIO("properties.cfg");
      width = properties.getWidth();
      height = properties.getHeight();
      depth = properties.getDepth();
      freq = properties.getFreq();
      fullscreen = properties.getFullscreen();
        // create a node for ortho gui stuff
        guiNode = new Node( "gui" );
        guiNode.setRenderQueueMode( Renderer.QUEUE_ORTHO );

        createCustomCursor();
       
        // create the desktop Quad
   desktop = new JMEDesktop( "desktop", 500, 400, input );
       
        // make it transparent blue
        desktop.getJDesktop().setBackground( new Color( 0, 0, 1, 0.2f ) );
        // and attach it to the gui node
        guiNode.attachChild( desktop );
        // center it on screen
        //desktop.getLocalTranslation().set( display.getWidth() / 2 - 30, display.getHeight() / 2 + 50, 0 );
        desktop.setLocalTranslation(new Vector3f( display.getWidth() / 2 , display.getHeight() / 2, 0 ));
        // create a swing button
        final JButton button = new JButton( "click me" );
        // and put it directly on the desktop
        desktop.getJDesktop().add( button );
        // desktop has no layout - we layout ourselfes (could assign a layout to desktop here instead)
        button.setLocation( 200, 200 );
        button.setSize( button.getPreferredSize() );
        // add some actions
        // standard swing action:
        button.addActionListener( new ActionListener() {
            public void actionPerformed( ActionEvent e ) {
                // this gets executed in swing thread
                // alter swing components ony in swing thread!
               // button.setLocation( FastMath.rand.nextInt( 400 ), FastMath.rand.nextInt( 300 ) );
                System.out.println( "clicked!" );
            }
        } );
        // action that gets executed in the update thread:
        button.addActionListener( new JMEAction( "my action", input ) {
            public void performAction( InputActionEvent evt ) {
                // this gets executed in jme thread
                // do 3d system calls in jme thread only!
               reinit();
                guiNode.updateRenderState(); // this call has no effect but should be done in jme thread :)
            }
        });
       
         // don't cull the gui away
        guiNode.setCullMode( Spatial.CULL_NEVER );
        // gui needs no lighting
        guiNode.setLightCombineMode( LightState.OFF );
        // update the render states (especially the texture state of the deskop!)
        guiNode.updateRenderState();
        // update the world vectors (needed as we have altered local translation of the desktop and it's
        //  not called in the update loop)
        guiNode.updateGeometricState( 0, true );

        // finally show the system mouse cursor to allow the user to click our button
        MouseInput.get().setCursorVisible( true );
    }
    private void createCustomCursor() {
        cursor = new AbsoluteMouse( "cursor", display.getWidth(), display.getHeight() );

        // Get a picture for my mouse.
        TextureState ts = display.getRenderer().createTextureState();
        URL cursorLoc;
        cursorLoc = TestJMEDesktop.class.getClassLoader().getResource(
                "jmetest/data/cursor/cursor1.png" );
        Texture t = TextureManager.loadTexture( cursorLoc, Texture.MM_LINEAR,
                Texture.FM_LINEAR, Image.GUESS_FORMAT_NO_S3TC, 1, true );
        ts.setTexture( t );
        cursor.setRenderState( ts );

        // Make the mouse's background blend with what's already there
        AlphaState as = display.getRenderer().createAlphaState();
        as.setBlendEnabled( true );
        as.setSrcFunction( AlphaState.SB_SRC_ALPHA );
        as.setDstFunction( AlphaState.DB_ONE_MINUS_SRC_ALPHA );
        as.setTestEnabled( true );
        as.setTestFunction( AlphaState.TF_GREATER );
        cursor.setRenderState( as );

        // Assign the mouse to an input handler
        cursor.registerWithInputHandler( input );

        rootNode.attachChild( cursor );

        // important for JMEDesktop: use system coordinates
        cursor.setUsingDelta( false );
        cursor.getXUpdateAction().setSpeed( 1 );
        cursor.getYUpdateAction().setSpeed( 1 );

        cursor.setCullMode( Spatial.CULL_NEVER );
        cursor.updateRenderState();
    }
    protected void reinit() {
       rootNode.detachChild(cursor);
       desktop.dispose();
       System.out.println(display.getWidth());
      System.out.println(display.getHeight());
      display.recreateWindow(width, height, depth, freq, fullscreen);
      
      createCustomCursor();
      
        desktop = new JMEDesktop( "desktop", display.getWidth()/2, display.getHeight()/2, input );
       
        // make it transparent blue
        desktop.getJDesktop().setBackground( new Color( .8f, .8f, .8f, 0.2f ) );
        // and attach it to the gui node
        guiNode.attachChild( desktop );
        // center it on screen
        desktop.setLocalTranslation(new Vector3f( display.getWidth() / 2 , display.getHeight() / 2, 0 ));

        // create a swing button
        final JButton button = new JButton( "click me" );
        // and put it directly on the desktop
        desktop.getJDesktop().add( button );
        // desktop has no layout - we layout ourselfes (could assign a layout to desktop here instead)
        button.setLocation( 0,0 );
        //button.set
        System.out.println(display.getWidth());
      System.out.println(display.getHeight());
        button.setSize( button.getPreferredSize() );
        // add some actions
        // standard swing action:
        button.addActionListener( new ActionListener() {
            public void actionPerformed( ActionEvent e ) {
                // this gets executed in swing thread
                // alter swing components ony in swing thread!
               // button.setLocation( FastMath.rand.nextInt( 400 ), FastMath.rand.nextInt( 300 ) );
                System.out.println( "clicked!" );
            }
        } );
        // action that gets executed in the update thread:
        button.addActionListener( new JMEAction( "my action", input ) {
            public void performAction( InputActionEvent evt ) {
                // this gets executed in jme thread
                // do 3d system calls in jme thread only!
               reinit();
                guiNode.updateRenderState(); // this call has no effect but should be done in jme thread :)
            }
        });
       
         // don't cull the gui away
        guiNode.setCullMode( Spatial.CULL_NEVER );
        // gui needs no lighting
        guiNode.setLightCombineMode( LightState.OFF );
        // update the render states (especially the texture state of the deskop!)
        guiNode.updateRenderState();
        // update the world vectors (needed as we have altered local translation of the desktop and it's
        //  not called in the update loop)
        guiNode.updateGeometricState( 0, true );
       
   }
   
    protected void simpleRender() {
        // draw the gui stuff after the scene
     
        display.getRenderer().draw( guiNode );
    }

    public static void main( String[] args ) {
        new HelloJMEDesktop().start();
    }
}


I attached the cursor to guiNode insted of rootNode and moved the cursor creation code to after the guiNode is attached and now the cursor is on top of button and in right position :smiley:

thanks for help llama