Null Pointer Exception when calling a method from class

Hi.

I’m trying to get a result from a textfeild inside a method submit() in a class called SafeController. The method returns a boolean result. The submit() method is linked to an xml file as a function for a button. Everything is working fine in the class itself while i was testing:

public void  submit(){
nifty.gotoScreen("Safe");
Screen screen = nifty.getCurrentScreen();    
TextField textField = screen.findNiftyControl("input", TextField.class);
String text = textField.getText();
text = text.toString();

if("123".equals(text)){System.out.println("correct");}
else{System.out.println("Wrong");}
}

When i click the submit button, everything works how i want it.

When i turn the method into a boolean and try to call it in the main code to use the result, it returns an error “Null point exception”.

public static boolean submit(){
nifty.gotoScreen("Safe");
Screen screen = nifty.getCurrentScreen();    
TextField textField = screen.findNiftyControl("input", TextField.class);

String text = textField.getText();
text = text.toString();
boolean result = false;
if("123".equals(text)){result = true;}
else{result = false;}
return result;
}

Calling the method in main class:

if (SafeController.submit()==true)
{System.out.println("Correct");}
else
{System.out.println("Wrong")}

I know this is because initially the textbox is null and that is why it is returning the error. My question is, how can i get it to work?

Cheers

Which line is giving the null pointer?

Also changing the return type of the method as you have it shouldn’t affect it in any way. I suspect it is because you made the method static that you are getting problems.

in the main class when calling the method:

if (SafeController.submit()==true)
{System.out.println("Correct");}
else
{System.out.println("Wrong")}

Which line in the submit() method? Can you show the stack trace please. Also have you tried debugging? What IDE are you using?

How do you initialize nifty, is it static?

nifty is static yes.

This is the stack trace:

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
at mygame.SafeController.submit(SafeController.java:45)
at mygame.Main.simpleInitApp(Main.java:194)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:226)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:207)
at java.lang.Thread.run(Thread.java:744)

What is on line 45 of SafeController?

44 - public static boolean submit(){
45 - nifty.gotoScreen(“Safe”); /This is why i declared nifty as static, so to use it in another method than initialize()/
46 - Screen screen = nifty.getCurrentScreen();
47 - TextField textField = screen.findNiftyControl(“input”, TextField.class);

Ok, nifty is not initialized. If you debug then you’ll see that it is null and you get an exception when trying to call a method on it.

Making variables static is not really a problem but it seems that you have made it static for the wrong reasons.

so to use it in another method

is not the right reason to make it static.

I’m not entirely sure what you are trying to achieve but you need to make sure that nifty is initialized and accessible before you act on it. without seeing more of your code I cannot fix the problem for you but you should have enough information to fix it yourself now. If you want me to take a look then post your code, preferably a short (but complete) example.

I suspect you need to understand the difference between instance members (non-static) and class members (static):

Understanding Class Members

1 Like

This is my whole class:

public class SafeController extends AbstractAppState implements ScreenController {
public static Nifty nifty;
SimpleApplication rootApp;

 public void initialize(AppStateManager stateManager, Application app){
 super.initialize(stateManager, app);
 rootApp = (SimpleApplication)app;
 NiftyJmeDisplay niftyScreen = new NiftyJmeDisplay(app.getAssetManager(), app.getInputManager(), app.getAudioRenderer(), app.getGuiViewPort());
 nifty = niftyScreen.getNifty();
 nifty.fromXml("Interface/SafeCode.xml", "Safe", this);
 app.getGuiViewPort().addProcessor(niftyScreen);
 }

public void bind(Nifty nifty, Screen screen) {
}

public void onStartScreen() {
}

public void onEndScreen() {
}
   

public static boolean submit(){
nifty.gotoScreen("Safe");
Screen screen = nifty.getCurrentScreen();    
TextField textField = screen.findNiftyControl("input", TextField.class);

String text = textField.getText();
text = text.toString();
boolean result = false;
if("123".equals(text)){result = true;System.out.println("correct");}
return result;
}

I’m basically doing a safe combination thing and this class is supposed to verify if the code is correct or not. It does that within the class itself, however, when calling it into the main code, it gives me that error because it is null. Granted that i’m using it for the wrong reasons, so how do I do it? To clarify, my question is, how can I use the boolean result in the main class?

Can I please see the Main class too?

This is up until I am trying to call the method:

public void simpleInitApp() {   
//don't show stats
setDisplayFps(false);
setDisplayStatView(false);
/** Set up Physics */

bulletAppState = new BulletAppState();
bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);//for bullets
stateManager.attach(bulletAppState);
//bulletAppState.getPhysicsSpace().enableDebug(assetManager);
// We re-use the flyby camera for rotation, while positioning is handled by physics
viewPort.setBackgroundColor(ColorRGBA.DarkGray);
flyCam.setMoveSpeed(100);
setUpKeys();
setUpLight();
stateManager.attach("safeC");
flyCam.setEnabled = false;
if (SafeController.submit()==true)
{System.out.println("Correct");}
else
{System.out.println("Wrong");}

//Preload Levels
level = assetManager.loadModel("Scenes/Scene.j3o");  
level.setLocalTranslation(0,0,0);
level.setLocalScale(5f);
...

Do you need to see the entire code? It’s about 500 lines

Here is some test code

import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;

public class TestApplication extends SimpleApplication {

    public static void main(String[] args) {
        TestApplication app = new TestApplication();
        app.start(/* JmeContext.Type.Display */);
    }

    @Override
    public void simpleInitApp() {
        MyTestState state = new MyTestState();
        this.stateManager.attach(state);
        System.out.println(MyTestState.submit());
    }

    @Override
    public void simpleUpdate(float tpf) {

    }

    private static class MyTestState extends AbstractAppState {

        private static String myString = null;

        public void initialize(AppStateManager stateManager, Application app) {
            super.initialize(stateManager, app);
            myString = "hello world!";
        }

        public static boolean submit() {
            if (myString == null)
                return false;
            else
                return true;
        }

    }

}

The output is:

false

It exhibits the same problem as your code. it hits the submit() method before initialize().

This is because…

initialize(AppStateManager stateManager, Application app)
Called by AppStateManager when transitioning this AppState from initializing to running.
This will happen on the next iteration through the update loop after AppStateManager#attach() was called.

How do you suggest i solve this issue? Is there a way around it?

Well you can’t do this…

stateManager.attach("safeC"); // Is this attaching the state even????
flyCam.setEnabled = false;
if (SafeController.submit()==true) 
{System.out.println("Correct");}
else
{System.out.println("Wrong");}

for the reason I explained. Because initialize() will not have been called by the time you call SafeController.submit()

Fixing it depends entirely on what you are trying to achieve (I’m still a little unsure).

For instance you can call the SafeController.submit() method from within the simpleUpdate(float tpf) method no problems. But then you’d need an extra boolean to stop it being called every iteration of the loop! Something like

@Override
public void simpleUpdate(float tpf) {
    if (!isChecked) {
        System.out.println(MyTestState.submit());
        isChecked= true;
    }
}

But I suspect that there is a better way of achieving what you want, if only I knew what it was :smile: