Problem with accessing nifty object from ScreenController

Hey there, newbie here.

I’m having a difficult time understanding how nifty objects are passed around. I’ve got a simple menu up from here: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:nifty_gui_java_interaction . I have the Quit button working, but when I try to get rid of the overlay with the Start button I am hitting problems because my ScreenController doesn’t see the nifty instance.

Main.java:

[java]
public class Main extends SimpleApplication {

private MainMenuController myMainMenuController;

private Spatial sceneModel;
private WaterFilter water;
private Vector3f lightDir = new Vector3f(-4.9f, -1.3f, 5.9f); // same as light source
private float initialWaterHeight = 0.8f; // choose a value for your scene
private Nifty nifty; 

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

@Override
public void simpleInitApp() {
    flyCam.setMoveSpeed(100f);
    //initBox();
    initScene();
    initLight();
    initPPcWater();
    
    
    myMainMenuController = new MainMenuController();
    stateManager.attach(myMainMenuController);
    NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, guiViewPort);
    nifty = niftyDisplay.getNifty();
    nifty.fromXml("Interface/MainMenuLayout.xml", "start", myMainMenuController);
    guiViewPort.addProcessor(niftyDisplay);
    flyCam.setDragToRotate(true);               
}

[/java]

and so on, but that’s the relevant part. MainMenuController is here: mygame.GUI.MainMenuController

MainMenuController:
[java]
package mygame.GUI;

import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController;

public class MainMenuController extends AbstractAppState implements ScreenController {

private Application app;
private AppStateManager stateManager;

public MainMenuController() {

}

@Override
public void initialize(AppStateManager stateManager, Application app) {
super.initialize(stateManager, app);
this.app = (SimpleApplication) app; // Gives access to app object
this.stateManager = stateManager;
//TODO: initialize your AppState, e.g. attach spatials to rootNode
//this is called on the OpenGL thread after the AppState has been attached
}

@Override
public void update(float tpf) {
    //TODO: implement behavior during runtime
}

@Override
public void cleanup() {
    super.cleanup();
    //TODO: clean up what you initialized in the initialize method,
    //e.g. remove all spatials from rootNode
    //this is called on the OpenGL thread after the AppState has been detached
}

public void bind(Nifty nifty, Screen screen) {
    //throw new UnsupportedOperationException("Not supported yet.");
}

public void onStartScreen() {
    //throw new UnsupportedOperationException("Not supported yet.");
}

public void onEndScreen() {
    //throw new UnsupportedOperationException("Not supported yet.");
}

public void startGame(String nextScreen) {
    //nifty.gotoScreen(nextScreen);  // switch to another screen
    // start the game and do some more stuff...

  }

public void quitGame() {
  app.stop(); 
}

}
[/java]

If I try to access nifty.[anything], the IDE tells me “can’t find symbol”. Obviously I haven’t created a nifty variable in my controller in the code above (though I have tried and failed several ways).

  1. My goal is to either remove the start screen with Screen.endScreen(), or just to end nifty altogether with nifty.exit(). Is this something taht is typically done in the ScreenController, or in Main?

  2. If it’s done in the ScreenController, how do I access the appropriate objects?

Thanks in advance,
Kit

I should add that I would also be happy (I guess) to gotoScreen([some_entirely_empty_screen]), but that of course won’t work without access to the nifty object either.

Ok, so I have a working example, but would still like to know if I am doing this via best practices.

I collect the nifty object during the bind event:
[java]
public void bind(Nifty nifty, Screen screen) {
//throw new UnsupportedOperationException(“Not supported yet.”);
this.nifty = nifty;
}
[/java]

That makes it available when I call startGame(), so now it functions, at least. But is that how people normally do it? You don’t get the object somehow through the app or stateManager?

Thx, Kit

that way is fine. It’s similar to the initialize() method of AppStates. Well you could create a nifty appstate if you want, and access it through the stateManager. Or make a getter on your Main class for it. There are many ways.