Nifty problems after update to jME3-beta

@glaucomardano I changed my id’s in the nift files so that all id’s are unique:



nifty1.xml

[xml]

<?xml version=“1.0” encoding=“UTF-8”?>

<nifty xmlns=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd http://nifty-gui.sourceforge.net/nifty-1.3.xsd”>

<!-- +++++++++++++++++++++++++++++++++++++++ -->

<!-- start screen -->

<!-- +++++++++++++++++++++++++++++++++++++++ -->

<screen id=“start1” controller=“mygame.Main”>

<layer id=“layer1” backgroundColor="#003f" childLayout=“center”>

<panel id=“panel1” height=“25%” width=“35%” align=“center” valign=“center” backgroundColor="#f60f" childLayout=“center” visibleToMouse=“true”>

<interact onClick=“nifty1()”/>

<effect>

<onStartScreen name=“move” mode=“in” direction=“top” length=“300” startDelay=“0” inherit=“true”/>

<onEndScreen name=“move” mode=“out” direction=“bottom” length=“300” startDelay=“0” inherit=“true”/>

<onHover name=“pulsate” scaleFactor=“0.008” startColor="#f600" endColor="#ffff" post=“true”/>

</effect>

<text id=“text1” font=“aurulent-sans-17.fnt” color="#000f" text=“NIFTY1” align=“center” valign=“center” />

</panel>

</layer>

</screen>

</nifty>

[/xml]



nifty2.xml

[xml]

<?xml version=“1.0” encoding=“UTF-8”?>

<nifty xmlns=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd http://nifty-gui.sourceforge.net/nifty-1.3.xsd”>

<!-- +++++++++++++++++++++++++++++++++++++++ -->

<!-- start screen -->

<!-- +++++++++++++++++++++++++++++++++++++++ -->

<screen id=“start2” controller=“mygame.Main”>

<layer id=“layer2” backgroundColor="#003f" childLayout=“center”>

<panel id=“panel2” height=“25%” width=“35%” align=“center” valign=“center” backgroundColor="#f60f" childLayout=“center” visibleToMouse=“true”>

<interact onClick=“nifty2()”/>

<effect>

<onStartScreen name=“move” mode=“in” direction=“top” length=“300” startDelay=“0” inherit=“true”/>

<onEndScreen name=“move” mode=“out” direction=“bottom” length=“300” startDelay=“0” inherit=“true”/>

<onHover name=“pulsate” scaleFactor=“0.008” startColor="#f600" endColor="#ffff" post=“true”/>

</effect>

<text id=“text2” font=“aurulent-sans-17.fnt” color="#000f" text=“NIFTY2” align=“center” valign=“center” />

</panel>

</layer>

</screen>

</nifty>

[/xml]



And also changed the nifty initialization code from



[java]

niftyDisplay.getNifty().fromXml(“Interface/nifty1.xml”, “start”, main);

[/java]



to

[java]

//in NiftyState1 class

niftyDisplay.getNifty().fromXml(“Interface/nifty1.xml”, “start1”, main);

//in NiftyState2 class

niftyDisplay.getNifty().fromXml(“Interface/nifty2.xml”, “start2”, main);

[/java]



But I’m, getting the same result.



I’m extending Application instead of SimpleApplication because there are many things extra in SimpleApplication I don’t need in my game (the attached main is based on my current project’s) and most of the code is the same as SimpleApplication (which extends Application) but removing extras (flyCam, debug info and so on). Anyway, I’ve changed it to extend SimpleApplication and tried having also the same results. This is the new code for main.java:



[java]

package mygame;



import com.jme3.app.SimpleApplication;

import de.lessvoid.nifty.Nifty;

import de.lessvoid.nifty.screen.Screen;

import de.lessvoid.nifty.screen.ScreenController;

import java.util.logging.Level;

import java.util.logging.Logger;



public class Main extends SimpleApplication implements ScreenController

{

NiftyState1 nifty1;

NiftyState2 nifty2;



public static void main(String[] args)

{

Main app = new Main();

app.start();

}



@Override

public void simpleInitApp()

{

//I want to see my mouse

flyCam.setDragToRotate(true);



//Disable clear in the default viewport in the app

this.viewPort.setClearFlags(false,false,false);

this.guiViewPort.setClearFlags(false, false, false);



nifty1=new NiftyState1(this,this.settings);

nifty2=new NiftyState2(this,this.settings);



//Only activate nifty1

nifty1.activateState();

}



public void bind(Nifty nifty, Screen screen) {

}



public void onStartScreen() {

}



public void onEndScreen() {

}



/**

  • Callback from nifty1 screen

    *
  • Deactivates nifty1 and activates nifty2

    */

    public void nifty1()

    {

    Logger.getLogger("").log(Level.WARNING, "Nifty1 callback - changing to nifty2 screen");

    nifty1.deactivateState();

    nifty2.activateState();

    }



    /**
  • Callback from nifty2 screen

    *
  • Deactivates nifty2 and activates nifty1

    */

    public void nifty2()

    {

    Logger.getLogger("").log(Level.WARNING, "Nifty2 callback - changing to nifty1 screen");

    nifty2.deactivateState();

    nifty1.activateState();

    }



    }

    [/java]

Ok. Instead of



[java]

//in NiftyState1 class

niftyDisplay.getNifty().fromXml("Interface/nifty1.xml", "start1", main);

//in NiftyState2 class

niftyDisplay.getNifty().fromXml("Interface/nifty2.xml", "start2", main);

[/java]



try



[java]

//in NiftyState1 class

niftyDisplay.getNifty().addXml("Interface/nifty1.xml", "start1", main);

//in NiftyState2 class

niftyDisplay.getNifty().addXml("Interface/nifty2.xml", "start2", main);

[/java]

I assume you (as everyone) can’t remember everything probably I misexplained myself… :roll: Just wanted to ask for another way to use addXml and use a previously instanced ScreenController. Finally I found a way and I’m still having the same result, callback from nifty1 are being called when nifty2 is active and nifty1 is not.

As you are using separated screen xml files then you should use separated screen controllers as well. It makes the things more easier and cleaner. Then instead of having NiftyState1 and NiftyState2 as just app states, make them screen controllers and in the same time app states. Take a look at this : https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:nifty_gui_scenarios#loading_several_xml_files.

@glaucomardano there is no method addXml(String file, String screen, ScreenController ctlr) in nifty just addXml(String file) or addXml(InpuStream is)

It’s because I don’t remeber everything :roll:!? Use the addXml(String filename) one. It does add the xml files to the nifty and creates automatically their mapped screen controllers, and assings ids automatically to the screens according to the xml files like: start1, start2. Then when you wish go to a screen, just use the goToScreen(String id) method e.g.: goToScreen(“start1”);

Hi again,



I changed my test code and xml files to use NiftyState1 and NiftyState2 as their own screen controllers but still having the same behaviour…

Make sure your screens are associated their respective controllers, and the controllers have theirself callbacks. It doesn’t make sense it’s having the same issue, if the screens and controllers are fully independent one of another, then it should work. You are messing up with something.

I checked the code again and seems to be correct. I copy appStates and xml’s here for you to check. Main remains the same



NiftyState1

[java]

package mygame;



import com.jme3.app.Application;

import com.jme3.app.state.AbstractAppState;

import com.jme3.app.state.AppStateManager;

import com.jme3.asset.AssetManager;

import com.jme3.audio.AudioRenderer;

import com.jme3.audio.Listener;

import com.jme3.input.InputManager;

import com.jme3.input.JoyInput;

import com.jme3.input.KeyInput;

import com.jme3.input.MouseInput;

import com.jme3.math.Vector3f;

import com.jme3.niftygui.NiftyJmeDisplay;

import com.jme3.renderer.Camera;

import com.jme3.renderer.RenderManager;

import com.jme3.renderer.ViewPort;

import com.jme3.renderer.queue.RenderQueue.Bucket;

import com.jme3.scene.Node;

import com.jme3.scene.Spatial.CullHint;

import com.jme3.system.AppSettings;

import com.jme3.system.JmeContext;

import de.lessvoid.nifty.Nifty;

import de.lessvoid.nifty.screen.Screen;

import de.lessvoid.nifty.screen.ScreenController;

import java.util.logging.Level;

import java.util.logging.Logger;



public class NiftyState1 extends AbstractAppState implements ScreenController

{

protected Main main;

protected AppSettings settings;

protected AssetManager assetManager;

protected AudioRenderer audioRenderer;

protected RenderManager renderManager;

protected AppStateManager stateManager;

protected Listener listener;

protected JmeContext context;

protected MouseInput mouseInput;

protected KeyInput keyInput;

protected JoyInput joyInput;

protected InputManager inputManager;



protected ViewPort viewPort;

protected ViewPort guiViewPort;

protected Node rootNode = new Node(“Root Node”);

protected Node guiNode = new Node(“Gui Node”);

protected Camera cam;

protected Camera guiCam;



private NiftyJmeDisplay niftyDisplay;



public NiftyState1(Main m, AppSettings s)

{

main=m;

settings=s;

Application app=(Application)main;

assetManager=app.getAssetManager();

audioRenderer=app.getAudioRenderer();

renderManager=app.getRenderManager();

stateManager=app.getStateManager();



listener=app.getListener();



context=app.getContext();

mouseInput=context.getMouseInput();

keyInput=context.getKeyInput();

joyInput=context.getJoyInput();



inputManager=app.getInputManager();



cam = new Camera(context.getSettings().getWidth(), context.getSettings().getHeight());



cam.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f);

cam.setLocation(new Vector3f(0f, 0f, 10f));

cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);



guiCam = new Camera(context.getSettings().getWidth(), context.getSettings().getHeight());



guiNode.setQueueBucket(Bucket.Gui);

guiNode.setCullHint(CullHint.Never);

}



public void activateState()

{

stateManager.attach(this);



viewPort = renderManager.createMainView(“Main nifty1”, cam);

viewPort.setClearFlags(true,true,true);

viewPort.attachScene(rootNode);



guiViewPort = renderManager.createPostView(“Gui nifty1”, guiCam);

guiViewPort.setClearFlags(false,true,true);

guiViewPort.attachScene(guiNode);



niftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, guiViewPort);

niftyDisplay.getNifty().fromXml(“Interface/nifty1.xml”, “start1”, this);

guiViewPort.addProcessor(niftyDisplay);

}





public void deactivateState()

{

stateManager.detach(this);



if(viewPort!=null)

{

viewPort.setClearFlags(false,false,false);

renderManager.removeMainView(viewPort);

}



if(guiViewPort!=null)

{

guiViewPort.removeProcessor(niftyDisplay);

guiViewPort.setClearFlags(false,false,false);

renderManager.removePostView(guiViewPort);

}



}



@Override

public void update(float tpf) {

super.update(tpf);



rootNode.updateLogicalState(tpf);

rootNode.updateGeometricState();

guiNode.updateLogicalState(tpf);

guiNode.updateGeometricState();

}



public void bind(Nifty nifty, Screen screen) {

}



public void onStartScreen() {

}



public void onEndScreen() {

}



/**

  • Callback from nifty1 screen

    *
  • Deactivates nifty1 and activates nifty2

    */

    public void nifty1()

    {

    Logger.getLogger("").log(Level.WARNING, "Nifty1 callback - changing to nifty2 screen");

    this.deactivateState();

    NiftyState2 nifty2=new NiftyState2(main,settings);

    nifty2.activateState();

    }





    }

    [/java]





    NiftyState2

    [java]

    package mygame;



    import com.jme3.app.Application;

    import com.jme3.app.state.AbstractAppState;

    import com.jme3.app.state.AppStateManager;

    import com.jme3.asset.AssetManager;

    import com.jme3.audio.AudioRenderer;

    import com.jme3.audio.Listener;

    import com.jme3.input.InputManager;

    import com.jme3.input.JoyInput;

    import com.jme3.input.KeyInput;

    import com.jme3.input.MouseInput;

    import com.jme3.math.Vector3f;

    import com.jme3.niftygui.NiftyJmeDisplay;

    import com.jme3.renderer.Camera;

    import com.jme3.renderer.RenderManager;

    import com.jme3.renderer.ViewPort;

    import com.jme3.renderer.queue.RenderQueue.Bucket;

    import com.jme3.scene.Node;

    import com.jme3.scene.Spatial.CullHint;

    import com.jme3.system.AppSettings;

    import com.jme3.system.JmeContext;

    import de.lessvoid.nifty.Nifty;

    import de.lessvoid.nifty.screen.Screen;

    import de.lessvoid.nifty.screen.ScreenController;

    import java.util.logging.Level;

    import java.util.logging.Logger;



    public class NiftyState2 extends AbstractAppState implements ScreenController

    {

    protected Main main;

    protected AppSettings settings;

    protected AssetManager assetManager;

    protected AudioRenderer audioRenderer;

    protected RenderManager renderManager;

    protected AppStateManager stateManager;

    protected Listener listener;

    protected JmeContext context;

    protected MouseInput mouseInput;

    protected KeyInput keyInput;

    protected JoyInput joyInput;

    protected InputManager inputManager;



    protected ViewPort viewPort;

    protected ViewPort guiViewPort;

    protected Node rootNode = new Node("Root Node");

    protected Node guiNode = new Node("Gui Node");

    protected Camera cam;

    protected Camera guiCam;



    private NiftyJmeDisplay niftyDisplay;



    public NiftyState2(Main m, AppSettings s)

    {

    main=m;

    settings=s;

    Application app=(Application)main;

    assetManager=app.getAssetManager();

    audioRenderer=app.getAudioRenderer();

    renderManager=app.getRenderManager();

    stateManager=app.getStateManager();



    listener=app.getListener();



    context=app.getContext();

    mouseInput=context.getMouseInput();

    keyInput=context.getKeyInput();

    joyInput=context.getJoyInput();



    inputManager=app.getInputManager();



    cam = new Camera(context.getSettings().getWidth(), context.getSettings().getHeight());



    cam.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f);

    cam.setLocation(new Vector3f(0f, 0f, 10f));

    cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);



    guiCam = new Camera(context.getSettings().getWidth(), context.getSettings().getHeight());



    guiNode.setQueueBucket(Bucket.Gui);

    guiNode.setCullHint(CullHint.Never);

    }



    public void activateState()

    {

    stateManager.attach(this);



    viewPort = renderManager.createMainView("Main nifty2", cam);

    viewPort.setClearFlags(true,true,true);

    viewPort.attachScene(rootNode);



    guiViewPort = renderManager.createPostView("Gui nifty2", guiCam);

    guiViewPort.setClearFlags(false,true,true);

    guiViewPort.attachScene(guiNode);



    niftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, guiViewPort);

    niftyDisplay.getNifty().fromXml("Interface/nifty2.xml", "start2", this);

    guiViewPort.addProcessor(niftyDisplay);

    }





    public void deactivateState()

    {

    stateManager.detach(this);



    if(viewPort!=null)

    {

    viewPort.setClearFlags(false,false,false);

    renderManager.removeMainView(viewPort);

    }



    if(guiViewPort!=null)

    {

    guiViewPort.removeProcessor(niftyDisplay);

    guiViewPort.setClearFlags(false,false,false);

    renderManager.removePostView(guiViewPort);

    }



    }



    @Override

    public void update(float tpf) {

    super.update(tpf);



    rootNode.updateLogicalState(tpf);

    rootNode.updateGeometricState();

    guiNode.updateLogicalState(tpf);

    guiNode.updateGeometricState();

    }



    public void bind(Nifty nifty, Screen screen) {

    }



    public void onStartScreen() {

    }



    public void onEndScreen() {

    }



    /**
  • Callback from nifty2 screen

    *
  • Deactivates nifty2 and activates nifty1

    */

    public void nifty2()

    {

    Logger.getLogger("").log(Level.WARNING, “Nifty2 callback - changing to nifty1 screen”);

    this.deactivateState();

    NiftyState1 nifty1=new NiftyState1(main,settings);

    nifty1.activateState();

    }



    }

    [/java]



    nifty1.xml

    [xml]

    <?xml version=“1.0” encoding=“UTF-8”?>

    <nifty xmlns=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd http://nifty-gui.sourceforge.net/nifty-1.3.xsd”>

    <!-- +++++++++++++++++++++++++++++++++++++++ -->

    <!-- start screen -->

    <!-- +++++++++++++++++++++++++++++++++++++++ -->

    <screen id=“start1” controller=“mygame.NiftyState1”>

    <layer id=“layer1” backgroundColor="#003f" childLayout=“center”>

    <panel id=“panel1” height=“25%” width=“35%” align=“center” valign=“center” backgroundColor="#f60f" childLayout=“center” visibleToMouse=“true”>

    <interact onClick=“nifty1()”/>

    <effect>

    <onStartScreen name=“move” mode=“in” direction=“top” length=“300” startDelay=“0” inherit=“true”/>

    <onEndScreen name=“move” mode=“out” direction=“bottom” length=“300” startDelay=“0” inherit=“true”/>

    <onHover name=“pulsate” scaleFactor=“0.008” startColor="#f600" endColor="#ffff" post=“true”/>

    </effect>

    <text id=“text1” font=“aurulent-sans-17.fnt” color="#000f" text=“NIFTY1” align=“center” valign=“center” />

    </panel>

    </layer>

    </screen>

    </nifty>

    [/xml]



    nifty2.xml

    [xml]

    <?xml version=“1.0” encoding=“UTF-8”?>

    <nifty xmlns=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd http://nifty-gui.sourceforge.net/nifty-1.3.xsd”>

    <!-- +++++++++++++++++++++++++++++++++++++++ -->

    <!-- start screen -->

    <!-- +++++++++++++++++++++++++++++++++++++++ -->

    <screen id=“start2” controller=“mygame.NiftyState2”>

    <layer id=“layer2” backgroundColor="#003f" childLayout=“center”>

    <panel id=“panel2” height=“25%” width=“35%” align=“center” valign=“center” backgroundColor="#f60f" childLayout=“center” visibleToMouse=“true”>

    <interact onClick=“nifty2()”/>

    <effect>

    <onStartScreen name=“move” mode=“in” direction=“top” length=“300” startDelay=“0” inherit=“true”/>

    <onEndScreen name=“move” mode=“out” direction=“bottom” length=“300” startDelay=“0” inherit=“true”/>

    <onHover name=“pulsate” scaleFactor=“0.008” startColor="#f600" endColor="#ffff" post=“true”/>

    </effect>

    <text id=“text2” font=“aurulent-sans-17.fnt” color="#000f" text=“NIFTY2” align=“center” valign=“center” />

    </panel>

    </layer>

    </screen>

    </nifty>

    [/xml]



    I’m starting to think this might be a bug in the nifty-jme integration in this release because this code worked perfectly on jme3-alpha3.



    EDIT: I also tryed with addXml instead of fromXml

You are doing the things wrong. You are generating new screen controller instances every interaction. It won’t work. You are ignoring the screen controllers instances associated with their respective screens. You have to use the instances that you have created before when you called nifty.addXml() then in your callback method do:



[java]

public void nifty1()

{

Logger.getLogger("").log(Level.WARNING, “Nifty1 callback - changing to nifty2 screen”);

this.deactivateState();

NiftyState2 nifty2=(NiftyState2)nifty.findScreen(“start2”);

nifty2.activateState();

}

[/java]



Do the same for the nifty2() callback. About the “nifty” object, you get it by overrinding the “bind()” method :



[java]

public void bind(Nifty nifty, Screen screen) {

//get the nifty and screen objects here

this.nifty = nifty;

this.screen = screen;

}

[/java]

Probably I misunderstand what you mean, but, from my point of view, in the previously attached code, I am not creating new screen controllers as I’m using fromXml passing the screen controller I want to use but I’m creating a new appState each time the panel is clicked (which is some useless waste of memory ). Also, I cannot cast nifty.findScreen() to NiftyState2 or NiftyState1 because findScreen returns a Screen object (and my appState classes don’t extend Screen). About the additions to bind method, I don’t think I really need them because I’m keeping the NiftyJmeDisplay and passed nifty if the same as niftyDisplay.getNifty() and passed screen is the same as niftyDisplay.getNifty().getCurrentScreen()



Just in case it’s useful, the test using addXml instead of fromXml I was keeping a public static variable pointing to the appState to be able to handle it correctly. Code of NiftyState1 (same changes applied to NiftyState2):



[java]

package mygame;



import com.jme3.app.Application;

import com.jme3.app.state.AbstractAppState;

import com.jme3.app.state.AppStateManager;

import com.jme3.asset.AssetManager;

import com.jme3.audio.AudioRenderer;

import com.jme3.audio.Listener;

import com.jme3.input.InputManager;

import com.jme3.input.JoyInput;

import com.jme3.input.KeyInput;

import com.jme3.input.MouseInput;

import com.jme3.math.Vector3f;

import com.jme3.niftygui.NiftyJmeDisplay;

import com.jme3.renderer.Camera;

import com.jme3.renderer.RenderManager;

import com.jme3.renderer.ViewPort;

import com.jme3.renderer.queue.RenderQueue.Bucket;

import com.jme3.scene.Node;

import com.jme3.scene.Spatial.CullHint;

import com.jme3.system.AppSettings;

import com.jme3.system.JmeContext;

import de.lessvoid.nifty.Nifty;

import de.lessvoid.nifty.screen.Screen;

import de.lessvoid.nifty.screen.ScreenController;

import java.util.logging.Level;

import java.util.logging.Logger;



public class NiftyState1 extends AbstractAppState implements ScreenController

{

public static NiftyState1 active;



protected static Main main;

protected static AppSettings settings;

protected AssetManager assetManager;

protected AudioRenderer audioRenderer;

protected RenderManager renderManager;

protected AppStateManager stateManager;

protected Listener listener;

protected JmeContext context;

protected MouseInput mouseInput;

protected KeyInput keyInput;

protected JoyInput joyInput;

protected InputManager inputManager;



protected ViewPort viewPort;

protected ViewPort guiViewPort;

protected Node rootNode = new Node(“Root Node”);

protected Node guiNode = new Node(“Gui Node”);

protected Camera cam;

protected Camera guiCam;



private NiftyJmeDisplay niftyDisplay;



/** empty Constructor for nifty */

public NiftyState1(){}



public NiftyState1(Main m, AppSettings s)

{

main=m;

settings=s;

Application app=(Application)main;

assetManager=app.getAssetManager();

audioRenderer=app.getAudioRenderer();

renderManager=app.getRenderManager();

stateManager=app.getStateManager();



listener=app.getListener();



context=app.getContext();

mouseInput=context.getMouseInput();

keyInput=context.getKeyInput();

joyInput=context.getJoyInput();



inputManager=app.getInputManager();



cam = new Camera(context.getSettings().getWidth(), context.getSettings().getHeight());



cam.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f);

cam.setLocation(new Vector3f(0f, 0f, 10f));

cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);



guiCam = new Camera(context.getSettings().getWidth(), context.getSettings().getHeight());



guiNode.setQueueBucket(Bucket.Gui);

guiNode.setCullHint(CullHint.Never);

}



public void activateState()

{

NiftyState1.active=this;



stateManager.attach(this);



viewPort = renderManager.createMainView(“Main nifty1”, cam);

viewPort.setClearFlags(true,true,true);

viewPort.attachScene(rootNode);



guiViewPort = renderManager.createPostView(“Gui nifty1”, guiCam);

guiViewPort.setClearFlags(false,true,true);

guiViewPort.attachScene(guiNode);



niftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, guiViewPort);

// niftyDisplay.getNifty().fromXml(“Interface/nifty1.xml”, “start1”, this);

niftyDisplay.getNifty().addXml(“Interface/nifty1.xml”);

niftyDisplay.getNifty().gotoScreen(“start1”);

guiViewPort.addProcessor(niftyDisplay);

}





public void deactivateState()

{

stateManager.detach(this);



if(viewPort!=null)

{

viewPort.setClearFlags(false,false,false);

renderManager.removeMainView(viewPort);

}



if(guiViewPort!=null)

{

guiViewPort.removeProcessor(niftyDisplay);

guiViewPort.setClearFlags(false,false,false);

renderManager.removePostView(guiViewPort);

}



NiftyState1.active=null;

}



@Override

public void update(float tpf) {

super.update(tpf);



rootNode.updateLogicalState(tpf);

rootNode.updateGeometricState();

guiNode.updateLogicalState(tpf);

guiNode.updateGeometricState();

}



public void bind(Nifty nifty, Screen screen) {

}



public void onStartScreen() {

}



public void onEndScreen() {

}



/**

  • Callback from nifty1 screen

    *
  • Deactivates nifty1 and activates nifty2

    */

    public void nifty1()

    {

    Logger.getLogger("").log(Level.WARNING, "Nifty1 callback - changing to nifty2 screen");

    NiftyState1.active.deactivateState();

    NiftyState2 nifty2=new NiftyState2(main,settings);

    nifty2.activateState();

    }





    }

    [/java]



    Sorry if I misundertood, in that case, could you try to be more clear?
I am not creating new screen controllers but I’m creating a new appState each time the panel is clicked


No. You was. Because your App States extends screen controllers. They should be instanced only once. About the fromXml() method, it will never work the way you want, because you are using separated xml screens. Then just do what I said and use the addXml() method, otherwise it won't work.

Also, I cannot cast nifty.findScreen() to NiftyState2 or NiftyState1 because findScreen returns a Screen object


Hmm, I can't remeber all the things, then you should know that you can get the screen controller object from the given screen object like that:

[java]
NiftyState2 nifty2=(NiftyState2)nifty.findScreen("start2").getScreenController();
[/java]

and my appState classes don’t extend Screen


Well, then someone here is blind :roll: :

[java]public class NiftyState1 extends AbstractAppState implements ScreenController[/java]

It means it's a screen controller and in the same time a app state. It looks you didn't understand well the things...

About the additions to bind method, I don’t think I really need them because I’m keeping the NiftyJmeDisplay and passed nifty if the same as niftyDisplay.getNifty() and passed screen is the same as niftyDisplay.getNifty().getCurrentScreen()


And it's very baaaaad. You are creating several NiftyJmeDisplay objects. OMG. You aren't following the nifty coding stardarts. I strongly advise you to go through the nifty and app states tutorials again. You didn't get how app states and screen controllers works. You really don't need your screen controller's contructor, since you can get those all parameters in bind() method and the initialize() method.

So my conclusion is, read the nifty and app states from the start to the end.
@glaucomardano said:
No. You was. Because your App States extends screen controllers. They should be instanced only once. About the fromXml() method, it will never work the way you want, because you are using separated xml screens. Then just do what I said and use the addXml() method, otherwise it won't work.


Also, as far as I know (or I think I know), just to clarify, each time you go to a screen, nifty itself creates a new instance of the screen controller, right?

@glaucomardano said:
Hmm, I can't remeber all the things, then you should know that you can get the screen controller object from the given screen object like that:

[java]
NiftyState2 nifty2=(NiftyState2)nifty.findScreen("start2").getScreenController();
[/java]

Well, then someone here is blind :roll: :

[java]public class NiftyState1 extends AbstractAppState implements ScreenController[/java]

It means it's a screen controller and in the same time a app state. It looks you didn't understand well the things...


Yes, I know my NiftyState is an app state and a screen controller (and I understand it :P), but what I didn't know is that I could get the screen controller from the screen object... good to know ;)

@glaucomardano said:
And it's very baaaaad. You are creating several NiftyJmeDisplay objects. OMG. You aren't following the nifty coding stardarts. I strongly advise you to go through the nifty and app states tutorials again. You didn't get how app states and screen controllers works. You really don't need your screen controller's contructor, since you can get those all parameters in bind() method and the initialize() method.

So my conclusion is, read the nifty and app states from the start to the end.


Just one more question, what do you exactly mean by "You really don't need your screen controller's contructor..."? What part of the code you are refering to? The NiftyDisplay.getNifty() stuff I was talking about?

OK, I'll re-read the documentation and the tutorials once again and try to fit to the standards.

Thanks for your comments and tomorrow I'll try to modify/rewrite my code and post if it worked right.
Also, as far as I know (or I think I know), just to clarify, each time you go to a screen, nifty itself creates a new instance of the screen controller, right?


No. You use the same instance all the time. The instances only are created when you call nifty.addXml() or nifty.fromXml() (I know theses 2). The goToScreen() stops rendering the current screen and starts rendering the wanted screen. See with yourself eyes the source code :

Nifty

[java]
public void gotoScreen(String id)
{
if (this.gotoScreenInProgess) {
this.log.info("gotoScreen [" + id + "] aborted because still in gotoScreenInProgress phase");
return;
}

this.log.info("gotoScreen [" + id + "]");
this.gotoScreenInProgess = true;

if (this.currentScreen.isNull()) {
gotoScreenInternal(id);
}
else
this.currentScreen.endScreen(new EndNotify(id)
{
public void perform() {
Nifty.this.gotoScreenInternal(this.val$id);
}
});
}

private void gotoScreenInternal(String id)
{
this.log.info("gotoScreenInternal [" + id + "]");

this.currentScreen = ((Screen)this.screens.get(id));
if (this.currentScreen == null) {
this.currentScreen = new NullScreen();
this.log.warning("screen [" + id + "] not found");
this.gotoScreenInProgess = false;
return;
}

if (this.alternateKeyForNextLoadXml != null) {
this.currentScreen.setAlternateKey(this.alternateKeyForNextLoadXml);
this.alternateKeyForNextLoadXml = null;
}
this.currentScreen.startScreen(new EndNotify() {
public void perform() {
Nifty.access$402(Nifty.this, false);
}
});
}
[/java]


Just one more question, what do you exactly mean by “You really don’t need your screen controller’s contructor…”? What part of the code you are refering to? The NiftyDisplay.getNifty() stuff I was talking about?


About the construtor, I meant all those ugly stuffs that you've putted into your screen controllers' constructor :

[java]
public NiftyState1(Main m, AppSettings s)
{
main=m;
settings=s;
Application app=(Application)main;
assetManager=app.getAssetManager();
audioRenderer=app.getAudioRenderer();
renderManager=app.getRenderManager();
stateManager=app.getStateManager();

listener=app.getListener();

context=app.getContext();
mouseInput=context.getMouseInput();
keyInput=context.getKeyInput();
joyInput=context.getJoyInput();

inputManager=app.getInputManager();

cam = new Camera(context.getSettings().getWidth(), context.getSettings().getHeight());

cam.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f);
cam.setLocation(new Vector3f(0f, 0f, 10f));
cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);

guiCam = new Camera(context.getSettings().getWidth(), context.getSettings().getHeight());

guiNode.setQueueBucket(Bucket.Gui);
guiNode.setCullHint(CullHint.Never);
}
[/java]

I'll be clear. Since your screen controllers extends AbstractAppState, that constructor is useless and unneeded at all, because all those objects can be requested in AbstractAppState.initialize(Application app, AppStateManager stateManager) method, then just override the initialize(Application app, AppStateManager stateManager) method and get access to all those objects easily. And if you wanna get access to the nifty and screens object, override the ScreenController.bind(Screen screen, Nifty nifty) method.

About the NiftyJmeDisplay, you was instancing it several times, every time you call the activateState() method. Just instance it once, do it inside your "Main" application class instead, and create a getter method for this. Then you can get access to the niftyJmeDisplay object into your app states/screen controllers just by doing:

[java]
@Override
public void initialize(Application app, StateManager stateManager) {
this.niftyJmeDisplay = ((Main)app).getNiftyJmeDisplay();
}
[/java]

Finally I got what you meant. I’ve changed my code to follow (more or less) your advice, samples and standars (only one NiftyJmeDisplay on main, changed my initialization code to initialize(AppStateManger, Application) and so on). And it works when changing between the two nifty states.



But I wanted to go forward into the problem I’m still facing in my project and I’ve added to this test case two new panels on each nifty and a new app state (which renders a simple blue box just like the default main example). One of the panel’s callback just disables the current state and the other changes to the new state. When the all states are disabled or when both nifty states are disabled and the new state is enabled, if you click where the panels were located, nifty callbacks are still being called.



I copy all my code here.



Main:

[java]

package mygame;



import com.jme3.app.SimpleApplication;

import com.jme3.niftygui.NiftyJmeDisplay;

import java.util.logging.Level;

import java.util.logging.Logger;



public class Main extends SimpleApplication

{

private NiftyJmeDisplay niftyDisplay;

private OtherState otherState;



public static void main(String[] args)

{

Main app = new Main();

app.start();

}



@Override

public void simpleInitApp()

{

//I want to see my mouse

flyCam.setDragToRotate(true);



niftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, guiViewPort);

niftyDisplay.getNifty().addXml(“Interface/nifty1.xml”);

niftyDisplay.getNifty().addXml(“Interface/nifty2.xml”);



NiftyState1 nifty1=(NiftyState1)niftyDisplay.getNifty().getScreen(“start1”).getScreenController();

nifty1.initialize(stateManager, this);

NiftyState2 nifty2=(NiftyState2)niftyDisplay.getNifty().getScreen(“start2”).getScreenController();

nifty2.initialize(stateManager, this);

otherState=new OtherState();

otherState.initialize(stateManager, this);



//Only activate nifty1

nifty1.activateState();



Logger.getLogger("").setLevel(Level.WARNING);



}



public NiftyJmeDisplay getNiftyDisplay()

{

return niftyDisplay;

}



public OtherState getOtherState()

{

return otherState;

}

}

[/java]



NiftyState1

[java]

package mygame;



import com.jme3.app.Application;

import com.jme3.app.state.AbstractAppState;

import com.jme3.app.state.AppStateManager;

import com.jme3.niftygui.NiftyJmeDisplay;

import com.jme3.renderer.Camera;

import com.jme3.renderer.RenderManager;

import com.jme3.renderer.ViewPort;

import com.jme3.renderer.queue.RenderQueue.Bucket;

import com.jme3.scene.Node;

import com.jme3.scene.Spatial.CullHint;

import de.lessvoid.nifty.Nifty;

import de.lessvoid.nifty.screen.Screen;

import de.lessvoid.nifty.screen.ScreenController;

import java.util.logging.Level;

import java.util.logging.Logger;



public class NiftyState1 extends AbstractAppState implements ScreenController

{

protected Main main;

protected AppStateManager stateManager;

protected RenderManager renderManager;



protected ViewPort guiViewPort;

protected Node guiNode = new Node(“Gui Node”);

protected Camera guiCam;



private NiftyJmeDisplay niftyDisplay;

private Nifty nifty;

private Screen screen;



@Override

public void initialize(AppStateManager stateManager, Application app)

{

super.initialize(stateManager, app);



main=((Main)app);

niftyDisplay = main.getNiftyDisplay();



renderManager=app.getRenderManager();

this.stateManager=stateManager;



guiCam = new Camera(app.getContext().getSettings().getWidth(), app.getContext().getSettings().getHeight());



guiNode.setQueueBucket(Bucket.Gui);

guiNode.setCullHint(CullHint.Never);

}



public void activateState()

{

stateManager.attach(this);



guiViewPort = renderManager.createPostView(“Gui nifty1”, guiCam);

guiViewPort.setClearFlags(false,true,true);

guiViewPort.attachScene(guiNode);



niftyDisplay.getNifty().gotoScreen(“start1”);

guiViewPort.addProcessor(niftyDisplay);

}





public void deactivateState()

{

stateManager.detach(this);



if(guiViewPort!=null)

{

guiViewPort.removeProcessor(niftyDisplay);

guiViewPort.setClearFlags(false,false,false);

renderManager.removePostView(guiViewPort);

}



}



@Override

public void update(float tpf) {

super.update(tpf);



guiNode.updateLogicalState(tpf);

guiNode.updateGeometricState();

}



public void bind(Nifty nifty, Screen screen)

{

this.nifty=nifty;

this.screen=screen;

}



public void onStartScreen() {

}



public void onEndScreen() {

}



/**

  • Callback from nifty1 screen

    *
  • Deactivates nifty1 and activates nifty2

    */

    public void nifty1()

    {

    Logger.getLogger("").log(Level.WARNING, "Nifty1 callback - changing to nifty2 screen");

    this.deactivateState();

    NiftyState2 nifty2=(NiftyState2)nifty.getScreen("start2").getScreenController();

    nifty2.activateState();

    }



    /**
  • Callback from nifty1 screen

    *
  • Deactivates nifty1

    */

    public void nifty1deactivate()

    {

    Logger.getLogger("").log(Level.WARNING, "Nifty1 callback - deactivate");

    this.deactivateState();

    }



    /**
  • Callback from nifty1 screen

    *
  • Deactivates nifty1 and activates other state

    */

    public void nifty1other()

    {

    Logger.getLogger("").log(Level.WARNING, "Nifty1 callback - changing to otherstate screen");

    this.deactivateState();

    main.getOtherState().activateState();

    }



    }

    [/java]



    NiftyState2

    [java]

    package mygame;



    import com.jme3.app.Application;

    import com.jme3.app.state.AbstractAppState;

    import com.jme3.app.state.AppStateManager;

    import com.jme3.niftygui.NiftyJmeDisplay;

    import com.jme3.renderer.Camera;

    import com.jme3.renderer.RenderManager;

    import com.jme3.renderer.ViewPort;

    import com.jme3.renderer.queue.RenderQueue.Bucket;

    import com.jme3.scene.Node;

    import com.jme3.scene.Spatial.CullHint;

    import de.lessvoid.nifty.Nifty;

    import de.lessvoid.nifty.screen.Screen;

    import de.lessvoid.nifty.screen.ScreenController;

    import java.util.logging.Level;

    import java.util.logging.Logger;



    public class NiftyState2 extends AbstractAppState implements ScreenController

    {

    protected Main main;

    protected AppStateManager stateManager;

    protected RenderManager renderManager;



    protected ViewPort guiViewPort;

    protected Node guiNode = new Node("Gui Node");

    protected Camera guiCam;



    private NiftyJmeDisplay niftyDisplay;

    private Nifty nifty;

    private Screen screen;



    @Override

    public void initialize(AppStateManager stateManager, Application app)

    {

    super.initialize(stateManager, app);



    main=((Main)app);

    niftyDisplay = main.getNiftyDisplay();



    renderManager=app.getRenderManager();

    this.stateManager=stateManager;



    guiCam = new Camera(app.getContext().getSettings().getWidth(), app.getContext().getSettings().getHeight());



    guiNode.setQueueBucket(Bucket.Gui);

    guiNode.setCullHint(CullHint.Never);

    }



    public void activateState()

    {

    stateManager.attach(this);



    guiViewPort = renderManager.createPostView("Gui nifty2", guiCam);

    guiViewPort.setClearFlags(false,true,true);

    guiViewPort.attachScene(guiNode);



    niftyDisplay.getNifty().gotoScreen("start2");

    guiViewPort.addProcessor(niftyDisplay);

    }





    public void deactivateState()

    {

    stateManager.detach(this);



    if(guiViewPort!=null)

    {

    guiViewPort.removeProcessor(niftyDisplay);

    guiViewPort.setClearFlags(false,false,false);

    renderManager.removePostView(guiViewPort);

    }



    }



    @Override

    public void update(float tpf) {

    super.update(tpf);



    guiNode.updateLogicalState(tpf);

    guiNode.updateGeometricState();

    }



    public void bind(Nifty nifty, Screen screen)

    {

    this.nifty=nifty;

    this.screen=screen;

    }



    public void onStartScreen() {

    }



    public void onEndScreen() {

    }



    /**
  • Callback from nifty2 screen

    *
  • Deactivates nifty2 and activates nifty1

    */

    public void nifty2()

    {

    Logger.getLogger("").log(Level.WARNING, "Nifty2 callback - changing to nifty1 screen");

    this.deactivateState();

    NiftyState1 nifty1=(NiftyState1)nifty.getScreen("start1").getScreenController();

    nifty1.activateState();

    }



    /**
  • Callback from nifty2 screen

    *
  • Deactivates nifty2

    */

    public void nifty2deactivate()

    {

    Logger.getLogger("").log(Level.WARNING, "Nifty2 callback - deactivate");

    this.deactivateState();

    }



    /**
  • Callback from nifty2 screen

    *
  • Deactivates nifty2 and activates other state

    */

    public void nifty2other()

    {

    Logger.getLogger("").log(Level.WARNING, “Nifty2 callback - changing to otherstate screen”);

    this.deactivateState();

    main.getOtherState().activateState();

    }



    }

    [/java]



    OtherState (the new one):

    [java]

    package mygame;



    import com.jme3.app.Application;

    import com.jme3.app.state.AbstractAppState;

    import com.jme3.app.state.AppStateManager;

    import com.jme3.material.Material;

    import com.jme3.math.ColorRGBA;

    import com.jme3.math.Vector3f;

    import com.jme3.renderer.Camera;

    import com.jme3.renderer.RenderManager;

    import com.jme3.renderer.ViewPort;

    import com.jme3.scene.Geometry;

    import com.jme3.scene.Node;

    import com.jme3.scene.shape.Box;



    public class OtherState extends AbstractAppState

    {

    protected Main main;

    protected AppStateManager stateManager;

    protected RenderManager renderManager;



    protected ViewPort viewPort;

    protected Node rootNode = new Node(“Root Node”);

    protected Camera cam;



    @Override

    public void initialize(AppStateManager stateManager, Application app)

    {

    super.initialize(stateManager, app);



    main=((Main)app);



    renderManager=app.getRenderManager();

    this.stateManager=stateManager;



    //main camera

    cam = new Camera(app.getContext().getSettings().getWidth(), app.getContext().getSettings().getHeight());



    cam.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f);

    cam.setLocation(new Vector3f(0f, 0f, 10f));

    cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);



    Box b = new Box(Vector3f.ZERO, 1, 1, 1);

    Geometry geom = new Geometry(“Box”, b);



    Material mat = new Material(main.getAssetManager(), “Common/MatDefs/Misc/Unshaded.j3md”);

    mat.setColor(“Color”, ColorRGBA.Blue);

    geom.setMaterial(mat);



    rootNode.attachChild(geom);

    }



    public void activateState()

    {

    stateManager.attach(this);



    viewPort = renderManager.createMainView(“Main Other”, cam);

    viewPort.setClearFlags(true,true,true);

    viewPort.attachScene(rootNode);



    }





    public void deactivateState()

    {

    stateManager.detach(this);



    if(viewPort!=null)

    {

    viewPort.setClearFlags(false,false,false);

    renderManager.removeMainView(viewPort);

    }



    }



    @Override

    public void update(float tpf) {

    super.update(tpf);



    rootNode.updateLogicalState(tpf);

    rootNode.updateGeometricState();

    }



    }

    [/java]



    nifty1.xml

    [xml]

    <?xml version=“1.0” encoding=“UTF-8”?>

    <nifty xmlns=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd http://nifty-gui.sourceforge.net/nifty-1.3.xsd”>

    <!-- +++++++++++++++++++++++++++++++++++++++ -->

    <!-- start screen -->

    <!-- +++++++++++++++++++++++++++++++++++++++ -->

    <screen id=“start1” controller=“mygame.NiftyState1”>

    <layer id=“layer1” backgroundColor="#003f" childLayout=“vertical”>

    <panel id=“panel1” height=“25%” width=“35%” align=“center” valign=“center” backgroundColor="#f60f" childLayout=“center” visibleToMouse=“true”>

    <interact onClick=“nifty1()”/>

    <effect>

    <onStartScreen name=“move” mode=“in” direction=“top” length=“300” startDelay=“0” inherit=“true”/>

    <onEndScreen name=“move” mode=“out” direction=“bottom” length=“300” startDelay=“0” inherit=“true”/>

    <onHover name=“pulsate” scaleFactor=“0.008” startColor="#f600" endColor="#ffff" post=“true”/>

    </effect>

    <text id=“text1” font=“aurulent-sans-17.fnt” color="#000f" text=“NIFTY1” align=“center” valign=“center” />

    </panel>

    <panel id=“panel1-de” height=“25%” width=“35%” align=“center” valign=“center” backgroundColor="#f60f" childLayout=“center” visibleToMouse=“true”>

    <interact onClick=“nifty1deactivate()”/>

    <effect>

    <onStartScreen name=“move” mode=“in” direction=“top” length=“300” startDelay=“0” inherit=“true”/>

    <onEndScreen name=“move” mode=“out” direction=“bottom” length=“300” startDelay=“0” inherit=“true”/>

    <onHover name=“pulsate” scaleFactor=“0.008” startColor="#f600" endColor="#ffff" post=“true”/>

    </effect>

    <text id=“text1-de” font=“aurulent-sans-17.fnt” color="#000f" text=“NIFTY1 - Deactivate” align=“center” valign=“center” />

    </panel>

    <panel id=“panel1-other” height=“25%” width=“35%” align=“center” valign=“center” backgroundColor="#f60f" childLayout=“center” visibleToMouse=“true”>

    <interact onClick=“nifty1other()”/>

    <effect>

    <onStartScreen name=“move” mode=“in” direction=“top” length=“300” startDelay=“0” inherit=“true”/>

    <onEndScreen name=“move” mode=“out” direction=“bottom” length=“300” startDelay=“0” inherit=“true”/>

    <onHover name=“pulsate” scaleFactor=“0.008” startColor="#f600" endColor="#ffff" post=“true”/>

    </effect>

    <text id=“text1-other” font=“aurulent-sans-17.fnt” color="#000f" text=“NIFTY1 - Goto OtherState” align=“center” valign=“center” />

    </panel>

    </layer>

    </screen>

    </nifty>

    [/xml]



    nifty2.xml

    [xml]

    <?xml version=“1.0” encoding=“UTF-8”?>

    <nifty xmlns=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd http://nifty-gui.sourceforge.net/nifty-1.3.xsd”>

    <!-- +++++++++++++++++++++++++++++++++++++++ -->

    <!-- start screen -->

    <!-- +++++++++++++++++++++++++++++++++++++++ -->

    <screen id=“start2” controller=“mygame.NiftyState2”>

    <layer id=“layer2” backgroundColor="#003f" childLayout=“vertical”>

    <panel id=“panel2” height=“25%” width=“35%” align=“center” valign=“center” backgroundColor="#f60f" childLayout=“center” visibleToMouse=“true”>

    <interact onClick=“nifty2()”/>

    <effect>

    <onStartScreen name=“move” mode=“in” direction=“top” length=“300” startDelay=“0” inherit=“true”/>

    <onEndScreen name=“move” mode=“out” direction=“bottom” length=“300” startDelay=“0” inherit=“true”/>

    <onHover name=“pulsate” scaleFactor=“0.008” startColor="#f600" endColor="#ffff" post=“true”/>

    </effect>

    <text id=“text2” font=“aurulent-sans-17.fnt” color="#000f" text=“NIFTY2” align=“center” valign=“center” />

    </panel>

    <panel id=“panel2-de” height=“25%” width=“35%” align=“center” valign=“center” backgroundColor="#f60f" childLayout=“center” visibleToMouse=“true”>

    <interact onClick=“nifty2deactivate()”/>

    <effect>

    <onStartScreen name=“move” mode=“in” direction=“top” length=“300” startDelay=“0” inherit=“true”/>

    <onEndScreen name=“move” mode=“out” direction=“bottom” length=“300” startDelay=“0” inherit=“true”/>

    <onHover name=“pulsate” scaleFactor=“0.008” startColor="#f600" endColor="#ffff" post=“true”/>

    </effect>

    <text id=“text2-de” font=“aurulent-sans-17.fnt” color="#000f" text=“NIFTY2 - Deactivate” align=“center” valign=“center” />

    </panel>

    <panel id=“panel2-other” height=“25%” width=“35%” align=“center” valign=“center” backgroundColor="#f60f" childLayout=“center” visibleToMouse=“true”>

    <interact onClick=“nifty2other()”/>

    <effect>

    <onStartScreen name=“move” mode=“in” direction=“top” length=“300” startDelay=“0” inherit=“true”/>

    <onEndScreen name=“move” mode=“out” direction=“bottom” length=“300” startDelay=“0” inherit=“true”/>

    <onHover name=“pulsate” scaleFactor=“0.008” startColor="#f600" endColor="#ffff" post=“true”/>

    </effect>

    <text id=“text2-other” font=“aurulent-sans-17.fnt” color="#000f" text=“NIFTY2 - Goto OtherState” align=“center” valign=“center” />

    </panel>

    </layer>

    </screen>

    </nifty>

    [/xml]



    Probably there is something I’m missing or doing wrong :?.



    Thanks for all your help.



    EDIT: Just to clarify, in my project, I have an app state which doesn’t use nifty at all. That’s why I changed the test this way

Hey, You are almost done :). But you are not handling your app states right. You really don’t need to call the method AbstractAppState.initialize(AppStateManager stateManager, Application application) by hand, that method is automatically called once when you attach your app state to the state manager. Then probably your app states are being initialized twice. Remove the lines where you are initializing them by hand like this one:



[java]

nifty1.initialize(stateManager, this);

[/java]



Also, your app states aren’t being updated, because your application extends the Application.java, and don’t wait it will update your app states automatically, because it won’t. As you are extending Application.java, you should know that, because it’s not so easy to handle the Application.java. The app states are updated automatically in SimpleApplication.java instead, just compare the Application.update() and SimpleApplication.update() methods, and you’ll see that the stateManager only is updated by the SimpleApplication.java. As you are extending Application.java, then update it by hand like SimpleApplication.java does at line 254:



[java]

// update states

stateManager.update(tpf);

[/java]



I definitely think you should extend SimpleApplication.java, it does handle all the things automatically for you, and you don’t need to worry about minor things like that.



-Regards

Hi again,



I removed the initialization by hand in Main, removed the method “activateState” and added its content to initialize and use stateManager.attach instead of state.activateState. I copy the changed parts of NiftyState1:



[java]

@Override

public void initialize(AppStateManager stateManager, Application app)

{

super.initialize(stateManager, app);



main=((Main)app);

niftyDisplay = main.getNiftyDisplay();



renderManager=app.getRenderManager();

this.stateManager=stateManager;



guiCam = new Camera(app.getContext().getSettings().getWidth(), app.getContext().getSettings().getHeight());



guiNode.setQueueBucket(Bucket.Gui);

guiNode.setCullHint(CullHint.Never);



guiViewPort = renderManager.createPostView(“Gui nifty1”, guiCam);

guiViewPort.setClearFlags(false,true,true);

guiViewPort.attachScene(guiNode);



niftyDisplay.getNifty().gotoScreen(“start1”);

guiViewPort.addProcessor(niftyDisplay);

}



/**

  • Callback from nifty1 screen

    *
  • Deactivates nifty1 and activates nifty2

    */

    public void nifty1()

    {

    Logger.getLogger("").log(Level.WARNING, "Nifty1 callback - changing to nifty2 screen");

    this.deactivateState();

    NiftyState2 nifty2=(NiftyState2)nifty.getScreen("start2").getScreenController();

    stateManager.attach(nifty2);

    }



    /**
  • Callback from nifty1 screen

    *
  • Deactivates nifty1

    */

    public void nifty1deactivate()

    {

    Logger.getLogger("").log(Level.WARNING, "Nifty1 callback - deactivate");

    this.deactivateState();

    }



    /**
  • Callback from nifty1 screen

    *
  • Deactivates nifty1 and activates other state

    */

    public void nifty1other()

    {

    Logger.getLogger("").log(Level.WARNING, “Nifty1 callback - changing to otherstate screen”);

    this.deactivateState();

    stateManager.attach(main.getOtherState());

    }

    [/java]



    About the Main class, I think you didn’t notice, but it extends SimpleApplication :wink:



    [java]

    public class Main extends SimpleApplication

    [/java]



    So I assume the code is correct now at last :stuck_out_tongue: :smiley:



    Any idea about nifty consuming mouse events when both nifty app states are disabled?

Wow. hehe. Glad to see you jumped to SimpleApplication ;). About the events, it looks you think when you detach your screen controllers - app states from state manager they stops consuming events. But it’s not. Screen controllers’s events are handled by nifty, not by input manager. So just detaching them from state manager won’t stop their events.

how can I stop nifty from consuming events?


Remove NiftyJmeDisplay from viewport or deactive the "interact" event from your panels. For the second way, first you request the panel element :

[java]
Element panel = screen.findElementById("MyPanelId");
[/java]

Then you can get the "interact" event from the element. I don't remember the exactly name, but you can get it from a getter method in element object.
Also, maybe there's a way to remove the current screen from the NiftyJmeDisplay without removing NiftyJmeDisplay from viewport, but I never tried it before.

Also, why previous versions of jme (alpha3) worked this way?


I don't know. But it should never work anyway. Jme has itself input system. Nifty has itself too.

mmmm… You’re right, I think this worked that way :S but… how can I stop nifty from consuming events? Also, why previous versions of jme (alpha3) worked this way? :?