Changing Screens in Nifty causes Exception

Hello, I can´t figure out how to make Nifty switch screens. My first screen is running fine and even the buttons do what they shall do, but whenever I attach the method “gotoScreen” or “fromXML” to a button, I get dozens of similar exceptions starting with “de.lessvoid.nifty.NiftyMethodInvoker callMethod
Warnung: Exception: java.lang.reflect.InvocationTargetException”

My current code looks like this:

       controller = new GUI_Controller(niftyDisplay, nifty);       
       stateManager.attach(controller);
             
    NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, guiViewPort);
    Nifty nifty = niftyDisplay.getNifty();
    guiViewPort.addProcessor(niftyDisplay);
    
        try {
        nifty.validateXml("Interface/xmltest.xml");
    } catch (Exception ex) {
        Logger.getLogger(GUI_Controller.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("XML seems broken"); 
    }

    nifty.fromXml("Interface/xmltest.xml", "start", this.controller);

My XML looks like this:

<?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">
  <useStyles filename="nifty-default-styles.xml" />
  <useControls filename="nifty-default-controls.xml" />

<screen id="start" controller="mygame.GUI_Controller">

        <layer id="background" childLayout="center">
            <panel id="panel_background" width = "50%" height="80%"  childLayout="vertical">

                <panel id="panel_top" backgroundColor="#ff0000ff" width="*" height="33%" childLayout="center">
                </panel>

                <panel id="panel_middle" backgroundColor="#1240abff" width="*" height="33%" childLayout="center">
                </panel>

                <panel id="panel_bottom" backgroundColor="#ffff00ff" width="*" height="*" childLayout="center">
                </panel>

            </panel>
        </layer>

        <layer id="foreground" childLayout="center">

   <panel id="panel_top" height="50%" width="50%" valign="center" childLayout="center">  
          <control name="button" label="Start Game" id="StartButton" align="center" valign="center" 
          visibleToMouse="true" > 
            <interact onClick="startGame()"/>
          </control>
        </panel>
         
   <panel id="panel_bottom" height="50%" width="50%" valign="bottom" childLayout="center">  
          <control name="button" label="Quit Game" id="QuitButton" align="center" valign="center" 
          visibleToMouse="true" > 
            <interact onClick="quitGame()"/>
          </control>
        </panel>    

       </layer>      

    </screen>
    </nifty>

Does anybody know what I am doing wrong? Do I maybe need to call other methods together with “gotoScreen” or “fromXML” to switch from one screen to another?

Thanks in advance!

Exceptions without a stack trace are almost totally useless, by the way.

Thanks, didnt´t know that. This is the output after pressing the switch-screen-button:

Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker callMethod
Warnung: Exception: java.lang.reflect.InvocationTargetException
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: sun.reflect.NativeMethodAccessorImpl invoke0 (NativeMethodAccessorImpl.java:-2)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: sun.reflect.NativeMethodAccessorImpl invoke (NativeMethodAccessorImpl.java:57)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: sun.reflect.DelegatingMethodAccessorImpl invoke (DelegatingMethodAccessorImpl.java:43)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: java.lang.reflect.Method invoke (Method.java:606)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.NiftyMethodInvoker callMethod (NiftyMethodInvoker.java:145)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.NiftyMethodInvoker performInvoke (NiftyMethodInvoker.java:104)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty$DelayedMethodInvoke perform (Nifty.java:1174)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty invokeMethods (Nifty.java:1152)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty handleDynamicElements (Nifty.java:354)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty access$1700 (Nifty.java:77)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl processEvent (Nifty.java:1374)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl processMouseEvent (Nifty.java:1329)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.niftygui.InputSystemJme handleMouseEvent (InputSystemJme.java:124)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.niftygui.InputSystemJme onMouseButtonEventQueued (InputSystemJme.java:232)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.niftygui.InputSystemJme forwardEvents (InputSystemJme.java:296)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty update (Nifty.java:288)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.niftygui.InputSystemJme endInput (InputSystemJme.java:113)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.input.InputManager processQueue (InputManager.java:819)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.input.InputManager update (InputManager.java:883)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.app.Application update (Application.java:604)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.app.SimpleApplication update (SimpleApplication.java:231)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.system.lwjgl.LwjglAbstractDisplay runLoop (LwjglAbstractDisplay.java:151)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.system.lwjgl.LwjglDisplay runLoop (LwjglDisplay.java:185)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.system.lwjgl.LwjglAbstractDisplay run (LwjglAbstractDisplay.java:228)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: java.lang.Thread run (Thread.java:744)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: Root Cause: java.lang.NullPointerException
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: mygame.GUI_Controller startGame (GUI_Controller.java:48)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: sun.reflect.NativeMethodAccessorImpl invoke0 (NativeMethodAccessorImpl.java:-2)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: sun.reflect.NativeMethodAccessorImpl invoke (NativeMethodAccessorImpl.java:57)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: sun.reflect.DelegatingMethodAccessorImpl invoke (DelegatingMethodAccessorImpl.java:43)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: java.lang.reflect.Method invoke (Method.java:606)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.NiftyMethodInvoker callMethod (NiftyMethodInvoker.java:145)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.NiftyMethodInvoker performInvoke (NiftyMethodInvoker.java:104)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty$DelayedMethodInvoke perform (Nifty.java:1174)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty invokeMethods (Nifty.java:1152)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty handleDynamicElements (Nifty.java:354)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty access$1700 (Nifty.java:77)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl processEvent (Nifty.java:1374)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl processMouseEvent (Nifty.java:1329)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.niftygui.InputSystemJme handleMouseEvent (InputSystemJme.java:124)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.niftygui.InputSystemJme onMouseButtonEventQueued (InputSystemJme.java:232)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.niftygui.InputSystemJme forwardEvents (InputSystemJme.java:296)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: de.lessvoid.nifty.Nifty update (Nifty.java:288)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.niftygui.InputSystemJme endInput (InputSystemJme.java:113)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.input.InputManager processQueue (InputManager.java:819)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.input.InputManager update (InputManager.java:883)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.app.Application update (Application.java:604)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.app.SimpleApplication update (SimpleApplication.java:231)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.system.lwjgl.LwjglAbstractDisplay runLoop (LwjglAbstractDisplay.java:151)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.system.lwjgl.LwjglDisplay runLoop (LwjglDisplay.java:185)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: com.jme3.system.lwjgl.LwjglAbstractDisplay run (LwjglAbstractDisplay.java:228)
Feb 18, 2016 10:41:56 AM de.lessvoid.nifty.NiftyMethodInvoker logException
Warnung: java.lang.Thread run (Thread.java:744)
BUILD SUCCESSFUL (total time: 7 seconds)

It’s your Code. You have to look through the code for a Root Cause and in this case it’s a NullPointerException in mygame.GUI_Controller.startGame() or Line 48.

Show us that Line or have a look at it. Nullpointer means you do something like “var.xyz” whereas var = null (Not defined (yet))

Line 48 just says: nifty.fromXml(“Interface/ingame.xml”, “ingame”);
Btw the “ingame.xml” is just an identical copy of the posted XML file with the title of the screen changed.
This is the code up to the start method:

  /*
     * 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.niftygui.NiftyJmeDisplay;
    import com.jme3.scene.Node;
    import de.lessvoid.nifty.Nifty;
    import de.lessvoid.nifty.builder.ScreenBuilder;
    import de.lessvoid.nifty.screen.Screen;
    import de.lessvoid.nifty.screen.ScreenController;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    
    
    public class GUI_Controller extends AbstractAppState implements ScreenController {
     
        private SimpleApplication app;
     
        private Node x = new Node("x");  // some custom class fields...    
        public Node getX(){ return x; }  // some custom methods... 
        
        NiftyJmeDisplay niftyJmeDisplay;
        Nifty nifty;
        
       public GUI_Controller(NiftyJmeDisplay ni, Nifty nif){
    this.niftyJmeDisplay = ni;
    this.nifty = nif;
    }
       
       
            public void startGame() {
    
        System.out.println("Du haettest ins Spiel gewechselt"); 
        
        
     //  nifty.gotoScreen("ingame");  // switch to another screen
        //    Screen ingame = new ScreenBuilder("ingame") {{nifty.fromXml("Interface/ingame.xml", "ingame");}}.build(nifty);
        
          
      //TEST 
   nifty.fromXml("Interface/xmltest.xml", "ingame");
       
        // start the game and do some more stuff...
      }

The ‘nifty’ field is null if that’s the line throwing the NPE.

Then I guess nifty only uses the default (empty) constructor so keep a static “nifty” around :stuck_out_tongue:

Most likely this is caused be letting nifty create the screen controller for you instead of passing it in or registering it with nifty. But your class doesn’t have a no-arg constructor so there is no way that it could be creating that.

Best check the inputs to your constructor as the caller seems to be passing null.

It works now! I have been searching for ages, but I had never thought, that my mistake was that simple and obvious. Thanks a lot!

You’re welcome. That’s why stack traces are important as this time it told you exactly what the problem was.

It’s just a shame that nifty chooses to display exceptions in such an obnoxious way. The guys who wrote nifty are otherwise super-smart guys but this exception logging is just dumb.

Oh, and btw, NiftyJmeProcessor has a method that returns a Nifty. So, you can simply ask for a NiftyJmeDisplay in the constructor and get the Nifty object from it:

public GUI_Controller(NiftyJmeDisplay ni){
    this.niftyJmeDisplay = ni;
    this.nifty = niftyJmeDisplay.getNifty();
}

I had a discussion with them on their old site about the log format and logging in general - I know the logging has been changed in later versions of nifty so it might be better now. I haven’t actually checked but one can always hope :slight_smile: