Nifty and AppStates

Hello,

I’m working on a game right now, and I’m trying to move to Nifty GUI. I have a basic XML file working, but when I try to modify one of my other AppStates, I get an enormous amount of exceptions. When I call a simple method such as System.out.println() using my button in the XML file, that works. But when I try to call something like:

app.getStateManager().getState(GamePlayAppState.class).chargeTower();

I don’t get the intended result, and I get the aforementioned angry red exception pile. It seems strange that I can call this exact line of code from a different AppState and have the intended effect, but from my ScreenController class, I get errors. I’ve tested it on Android, PC, and Linux and none seem to work properly.

Relevant code from Main class:
[java]
public void startGame() {
Start = new NiftyStart();
GameState = new GamePlayAppState();
PauseState = new PauseState();
OverState = new GameOverAppState();
InputState = new GamePlayInput();
GameState.setEnabled(true);

    NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,
                                                      inputManager,
                                                      audioRenderer,
                                                      guiViewPort);
    Nifty nifty = niftyDisplay.getNifty();

    nifty.fromXml("Interface/newNiftyGui.xml", "start", Start);
    nifty.registerScreenController(Start);
    
    guiViewPort.addProcessor(niftyDisplay);
    inputManager.setCursorVisible(true);
    
    stateManager.attach(GameState);
    stateManager.attach(InputState);
    stateManager.attach(Start);
}
[/java] 

NiftyStart.java
[java]package mygame;

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

/**
*

  • @author clarence
    */
    public class NiftyStart extends AbstractAppState implements ScreenController {
    public Node rootNode;
    public Nifty nifty;
    public Screen screen;
    public GamePlayAppState GameState;
    public GameOverAppState GameOverAppState;
    public PauseState PauseState;
    private SimpleApplication app;
    private GamePlayInput InputState;

    public NiftyStart() {

    }

    @Override
    public void initialize(AppStateManager stateManager, Application app) {
    super.initialize(stateManager, app);
    this.app = (SimpleApplication) app;
    }

    @Override
    public void update(float tpf) {

    }

    public void charge() {
    nifty.removeScreen(“start”);
    }

    public void bind(Nifty nifty, Screen screen) {
    this.nifty = nifty;
    this.screen = screen;
    }

    public void onStartScreen() {
    //throw new UnsupportedOperationException(“Not supported yet.”); //To change body of generated methods, choose Tools | Templates.
    }

    public void onEndScreen() {
    //throw new UnsupportedOperationException(“Not supported yet.”); //To change body of generated methods, choose Tools | Templates.
    }

    @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
    }

}[/java]

XML file:
[xml]

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

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

<useStyles filename=“nifty-default-styles.xml”/>

<useControls filename=“nifty-default-controls.xml”/>

-<screen controller=“mygame.NiftyStart” id=“start”>

-<layer id=“foreground” childLayout=“center” backgroundColor="#0000">

-<panel id=“panel_mid” childLayout=“center” backgroundColor="#0f08" align=“center” width=“75%” height=“50%”>

-<control id=“StartButton” align=“center” visibleToMouse=“true” valign=“center” label=“Start” name=“button”>

<interact onClick=“charge()”/>

</control>

</panel>

</layer>

</screen>

</nifty>
[/xml]

If someone could enlighten me as to what I’m doing wrong, that would be greatly appreciated.

Thanks!

Note that in the charge() method in NiftyStart, a call such as that will work. However, the code I actually want to execute is:

app.getStateManager().getState(GamePlayAppState.class).chargeTower();

i.e. get my GamePlayAppState and execute the method chargeTower() (which takes no input parameters)

I haven’t tried running your code. A casual inspection only found one weirdness: removing a screen from inside a ScreenController method. Perhaps you should simply disable the screen instead of removing it.

Also: what’s the first exception you get? With stack trace, please.

1 Like

Thanks for your reply! That code isn’t what I’d really like to execute, but it is something that CAN be executed. In my second post, I said what I’d really like to execute.

Here is the stack trace:

Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker callMethod
WARNING: Exception: java.lang.reflect.InvocationTargetException
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: sun.reflect.NativeMethodAccessorImpl invoke0 (NativeMethodAccessorImpl.java:-2)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: sun.reflect.NativeMethodAccessorImpl invoke (NativeMethodAccessorImpl.java:57)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: sun.reflect.DelegatingMethodAccessorImpl invoke (DelegatingMethodAccessorImpl.java:43)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: java.lang.reflect.Method invoke (Method.java:606)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.NiftyMethodInvoker callMethod (NiftyMethodInvoker.java:145)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.NiftyMethodInvoker performInvoke (NiftyMethodInvoker.java:104)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty$DelayedMethodInvoke perform (Nifty.java:1174)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty invokeMethods (Nifty.java:1152)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty handleDynamicElements (Nifty.java:354)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty access$1700 (Nifty.java:77)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl processEvent (Nifty.java:1374)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl processMouseEvent (Nifty.java:1329)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.niftygui.InputSystemJme handleMouseEvent (InputSystemJme.java:124)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.niftygui.InputSystemJme onMouseButtonEventQueued (InputSystemJme.java:232)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.niftygui.InputSystemJme forwardEvents (InputSystemJme.java:296)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty update (Nifty.java:288)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.niftygui.InputSystemJme endInput (InputSystemJme.java:113)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.input.InputManager processQueue (InputManager.java:819)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.input.InputManager update (InputManager.java:883)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.app.Application update (Application.java:604)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.app.SimpleApplication update (SimpleApplication.java:231)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.system.lwjgl.LwjglAbstractDisplay runLoop (LwjglAbstractDisplay.java:151)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.system.lwjgl.LwjglDisplay runLoop (LwjglDisplay.java:185)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.system.lwjgl.LwjglAbstractDisplay run (LwjglAbstractDisplay.java:228)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: java.lang.Thread run (Thread.java:744)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: Root Cause: java.lang.NullPointerException
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: mygame.NiftyText charge (NiftyText.java:46)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: sun.reflect.NativeMethodAccessorImpl invoke0 (NativeMethodAccessorImpl.java:-2)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: sun.reflect.NativeMethodAccessorImpl invoke (NativeMethodAccessorImpl.java:57)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: sun.reflect.DelegatingMethodAccessorImpl invoke (DelegatingMethodAccessorImpl.java:43)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: java.lang.reflect.Method invoke (Method.java:606)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.NiftyMethodInvoker callMethod (NiftyMethodInvoker.java:145)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.NiftyMethodInvoker performInvoke (NiftyMethodInvoker.java:104)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty$DelayedMethodInvoke perform (Nifty.java:1174)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty invokeMethods (Nifty.java:1152)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty handleDynamicElements (Nifty.java:354)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty access$1700 (Nifty.java:77)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl processEvent (Nifty.java:1374)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl processMouseEvent (Nifty.java:1329)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.niftygui.InputSystemJme handleMouseEvent (InputSystemJme.java:124)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.niftygui.InputSystemJme onMouseButtonEventQueued (InputSystemJme.java:232)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.niftygui.InputSystemJme forwardEvents (InputSystemJme.java:296)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: de.lessvoid.nifty.Nifty update (Nifty.java:288)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.niftygui.InputSystemJme endInput (InputSystemJme.java:113)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.input.InputManager processQueue (InputManager.java:819)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.input.InputManager update (InputManager.java:883)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.app.Application update (Application.java:604)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.app.SimpleApplication update (SimpleApplication.java:231)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.system.lwjgl.LwjglAbstractDisplay runLoop (LwjglAbstractDisplay.java:151)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.system.lwjgl.LwjglDisplay runLoop (LwjglDisplay.java:185)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: com.jme3.system.lwjgl.LwjglAbstractDisplay run (LwjglAbstractDisplay.java:228)
Mar 19, 2014 12:14:45 PM de.lessvoid.nifty.NiftyMethodInvoker logException
WARNING: java.lang.Thread run (Thread.java:744)

Filtered to save everyone else the time:
Root Cause: java.lang.NullPointerException
mygame.NiftyText charge (NiftyText.java:46)

1 Like
@pspeed said: Filtered to save everyone else the time: Root Cause: java.lang.NullPointerException mygame.NiftyText charge (NiftyText.java:46)

To help better, people will need to know what line of code that is… maybe with a little more context.

1 Like

Sorry! I’m working between Android and JME projects in the IDE, and I got those two confused. Those two files are basically the same, but here is the exact one that I just ran for that stack trace:
[java]
package mygame;

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

/**
*

  • @author clarence
    */
    public class NiftyText extends AbstractAppState implements ScreenController {
    public Node rootNode;
    public Nifty nifty;
    public Screen screen;
    public GamePlayAppState GameState;
    public GameOverAppState GameOverAppState;
    public PauseState PauseState;
    private SimpleApplication app;
    private GamePlayInput InputState;

    public NiftyText() {

    }

    @Override
    public void initialize(AppStateManager stateManager, Application app) {
    super.initialize(stateManager, app);
    this.app =(SimpleApplication) app;
    this.GameState = this.app.getStateManager().getState(GamePlayAppState.class);
    }

    @Override
    public void update(float tpf) {

    }

    public void charge() {
    GameState.chargeTower();
    }

    public void bind(Nifty nifty, Screen screen) {
    this.nifty = nifty;
    this.screen = screen;
    }

    public void onStartScreen() {
    //throw new UnsupportedOperationException(“Not supported yet.”); //To change body of generated methods, choose Tools | Templates.
    }

    public void onEndScreen() {
    //throw new UnsupportedOperationException(“Not supported yet.”); //To change body of generated methods, choose Tools | Templates.
    }

    @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
    }

}
[/java]

For whatever reason, the lines of code in the IDE and on this forum are different… probably because of leading whitespace or something like that. The line that it points to exactly is:
GameState.chargeTower();

in the method charge()

Triple post I know, but what I’m saying is if I replace that line with something like System.out.println(“here”), it will work and dump “here” out to the console. If I use the code as is in my above post, I get the stack trace without the intended effect.

Sorry if I’m being unclear, this is my first time actually asking for help on the internet rather than just lurking on the forums. I appreciate you guys taking the time to try and help me out!

FYI that’s not a stack trace, rather it’s a series of warnings. But it does help pin down the problem. Something in your
[java]
app.getStateManager().getState(GamePlayAppState.class).chargeTower();
[/java]
appears to be throwing an exception, but Nifty doesn’t tell us what it was. I suggest wrapping it in a try/catch block and logging what the original exception was. Something like this:
[java]

final private static Logger logger = Logger.getLogger(NiftyStart.class.getName());
public void charge() {
    try {
        app.getStateManager().getState(GamePlayAppState.class).chargeTower();
    } catch (Throwable throwable) {
        logger.log(Level.SEVERE, "Caught unexpected throwable:", throwable);
        app.stop(false);
    }
}

[/java]

1 Like

Thanks, I believe this is the actual stack trace using the code you provided:

Mar 19, 2014 12:36:37 PM mygame.NiftyStart charge
SEVERE: Caught unexpected throwable:
java.lang.NullPointerException
at mygame.NiftyStart.charge(NiftyStart.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at de.lessvoid.nifty.NiftyMethodInvoker.callMethod(NiftyMethodInvoker.java:145)
at de.lessvoid.nifty.NiftyMethodInvoker.performInvoke(NiftyMethodInvoker.java:104)
at de.lessvoid.nifty.Nifty$DelayedMethodInvoke.perform(Nifty.java:1174)
at de.lessvoid.nifty.Nifty.invokeMethods(Nifty.java:1152)
at de.lessvoid.nifty.Nifty.handleDynamicElements(Nifty.java:354)
at de.lessvoid.nifty.Nifty.access$1700(Nifty.java:77)
at de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl.processEvent(Nifty.java:1374)
at de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl.processMouseEvent(Nifty.java:1329)
at com.jme3.niftygui.InputSystemJme.handleMouseEvent(InputSystemJme.java:124)
at com.jme3.niftygui.InputSystemJme.onMouseButtonEventQueued(InputSystemJme.java:232)
at com.jme3.niftygui.InputSystemJme.forwardEvents(InputSystemJme.java:296)
at de.lessvoid.nifty.Nifty.update(Nifty.java:288)
at com.jme3.niftygui.InputSystemJme.endInput(InputSystemJme.java:113)
at com.jme3.input.InputManager.processQueue(InputManager.java:819)
at com.jme3.input.InputManager.update(InputManager.java:883)
at com.jme3.app.Application.update(Application.java:604)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:231)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228)
at java.lang.Thread.run(Thread.java:744)

Line 48 in the modified code is:
app.getStateManager().getState(GamePlayAppState.class).chargeTower();

It seems I’m getting a NullPointer exception from this class, but when I execute the exact same command from a different AppState it works just fine. Is there something about the way in which Nifty makes method calls that would cause this sort of exception?

@sgold said: FYI that's not a stack trace, rather it's a series of warnings.

FYI: that’s how nifty reports exceptions… a bunch of log warnings with each log being a line of the stack trace.

2 Likes
@Screamconjoiner said: It seems I'm getting a NullPointer exception from this class, but when I execute the exact same command from a different AppState it works just fine. Is there something about the way in which Nifty makes method calls that would cause this sort of exception?

You will have to do some debugging:
app.getStateManager().getState(GamePlayAppState.class).chargeTower();

An NPE on that line means that app is null or that the state isn’t in the app state… most likely app is null like this particular state has never been initialized, ie: not actually attached and let run once.

1 Like

@pspeed
Thanks, I tried instantiating them in a different order (GameState first, NiftyStart second) and attaching them in that same order, that didn’t seem to help. I tried calling a couple other methods from GameState to see if it was the chargeTower() method that was causing the nullpointer, but they all caused nullpointers.

It’s strange because in this code:
GamePlayInput.java
[java]
/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package mygame;

import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.collision.CollisionResults;
import com.jme3.input.InputManager;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.input.controls.Trigger;
import com.jme3.math.Ray;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Node;

/**
*

  • @author clarence
    */
    public class GamePlayInput extends AbstractAppState {
    private static final Trigger TRIGGER_ACTIVATE = new MouseButtonTrigger(
    MouseInput.BUTTON_LEFT);
    private final static String MAPPING_ACTIVATE = “Touch”;
    private SimpleApplication app;
    private Camera cam;
    private InputManager inputManager;
    private GamePlayAppState GameState;
    private Node rootNode;
    private int selected = 0;

    @Override
    public void initialize(AppStateManager stateManager, Application app) {
    super.initialize(stateManager, app);
    this.app = (SimpleApplication) app;
    this.cam = this.app.getCamera();
    this.inputManager = this.app.getInputManager();
    this.GameState = this.app.getStateManager().getState(GamePlayAppState.class);
    this.rootNode = this.app.getRootNode();
    inputManager.addMapping(MAPPING_ACTIVATE, TRIGGER_ACTIVATE);
    inputManager.addListener(actionListener, new String[]{MAPPING_ACTIVATE});
    // might run into trouble with sync, if so then just do this line everywhere
    }

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

    private ActionListener actionListener = new ActionListener() {
    public void onAction(String name, boolean keyPressed, float tpf) {
    if (keyPressed) {
    if (name.equals(MAPPING_ACTIVATE)) {
    Vector2f click2d = inputManager.getCursorPosition();
    Vector3f click3d = cam.getWorldCoordinates(new Vector2f(
    click2d.getX(), click2d.getY()), 0f);

                 float x = click2d.getX();
                 float y = click2d.getY();
                 //debugt = "X: " + Float.toString(x) + " Y: " + Float.toString(y);;
                 if (GameState.isEnabled()) {
                     selectTower(click2d, click3d);
                 }
             }
         }
     }
    

    };

    private void selectTower(Vector2f click2d, Vector3f click3d) {
    CollisionResults results = new CollisionResults();
    Vector3f dir = cam.getWorldCoordinates(
    new Vector2f(click2d.getX(), click2d.getY()), 1f);
    Ray ray = new Ray(click3d, dir);
    rootNode.collideWith(ray, results);
    // Selecting a tower
    for (int i = 0; i < results.size(); i++) {
    String target = results.getCollision(i).getGeometry().getName();
    if (target.equals(“Tower”)) {
    GameState.deselectTowers();
    selected = results.getCollision(i).getGeometry().getUserData(“Index”);
    GameState.towerSelected(selected);

             System.out.println(selected);
         }
     }
    

    }

    public int getSelected() {
    return selected;
    }

    @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
    }
    }
    [/java]

I do the same sort of calling/accessing, and I don’t get an NPE.

Is this the correct way to manipulate separate AppStates? I’ve browsed a lot of code and I’m pretty sure this is what the Best Practices page suggests, it’s just mind boggling to me that the same code that works in one AppState doesn’t work in the other…

See lines 85, 87 for those similar calls.

I think Paul’s on the right track here. getState() could be returning null because the GamePlayAppState isn’t listed yet.

NPEs are quite easy to debug, but having multiple calls on a single line makes it somewhat tricky.

I suggest breaking the failing line into several lines (one deref in each) and stepping through in the debugger.

1 Like

Well, a state will be listed as soon as it’s attached… even if it hasn’t been initialized yet.

…but it won’t be initialized until the update loop after it has been attached so to me it’s more likely that app is null.

It could also be that it is never initialized for some reason because it is a different instance than the one registered.

…actually, that’s it. If the code in the first post is accurate then the controller wasn’t registered until after the XML was loaded. So the XML loading would have created its own instance.

1 Like

So what you’re saying is, I should move the line:
nifty.fromXml(“Interface/newNiftyGui.xml”, “start”)

to after I’ve attached the GameState to the StateManager in the main class?

I tried that, but it didn’t work. While debugging, breaking the calls down line by line as suggested by @sgold, I found that the NPE is being caused by the getStateManager() method call. I don’t understand why, would you guys know of a reason as to why this would happen?