I’m trying to make a GUI screen with an exit button. When I click the button, I get a null pointer exception from getApplication().stop() because getApplication() is returning null. (The Nifty GUI tutorial didn’t check for that so I assume it’s not supposed to happen.) This is my first attempt at using an AppState so I might be doing something wrong there.
StartScreen.java:
package mygame;
import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.BaseAppState;
import com.jme3.niftygui.NiftyJmeDisplay;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.builder.LayerBuilder;
import de.lessvoid.nifty.builder.PanelBuilder;
import de.lessvoid.nifty.builder.ScreenBuilder;
import de.lessvoid.nifty.builder.TextBuilder;
import de.lessvoid.nifty.controls.button.builder.ButtonBuilder;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController;
public class StartScreen extends BaseAppState implements ScreenController {
@Override
protected void initialize(Application app) {
//It is technically safe to do all initialization and cleanup in the
//onEnable()/onDisable() methods. Choosing to use initialize() and
//cleanup() for this is a matter of performance specifics for the
//implementor.
//TODO: initialize your AppState, e.g. attach spatials to rootNode
}
@Override
protected void cleanup(Application app) {
//TODO: clean up what you initialized in the initialize method,
//e.g. remove all spatials from rootNode
}
//onEnable()/onDisable() can be used for managing things that should
//only exist while the state is enabled. Prime examples would be scene
//graph attachment or input listener attachment.
@Override
protected void onEnable() {
NiftyJmeDisplay niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(
getApplication().getAssetManager(),
getApplication().getInputManager(),
getApplication().getAudioRenderer(),
getApplication().getGuiViewPort());
Nifty nifty = niftyDisplay.getNifty();
getApplication().getGuiViewPort().addProcessor(niftyDisplay);
((SimpleApplication) getApplication()).getFlyByCamera().setDragToRotate(true);
nifty.loadStyleFile("nifty-default-styles.xml");
nifty.loadControlFile("nifty-default-controls.xml");
// <screen>
nifty.addScreen("Screen_ID", new ScreenBuilder("Hello Nifty Screen"){{
controller(new mygame.StartScreen()); // Screen properties
// <layer>
layer(new LayerBuilder("Menu_Layer") {{
childLayoutVertical(); // layer properties, add more...
panel(new PanelBuilder("Title_Panel") {{
childLayoutCenter();
alignCenter();
height("25%");
width("75%");
text(new TextBuilder() {{
text("Game with a Name");
font("Interface/Fonts/Default.fnt");
height("100%");
width("100%");
}});
}});
// <panel>
panel(new PanelBuilder("Menu_Panel") {{
childLayoutCenter(); // panel properties, add more...
alignCenter();
valignCenter();
height("50%");
width("50%");
control(new ButtonBuilder("ExitButton", "Exit"){{
alignCenter();
valignBottom();
height("10%");
width("30%");
visibleToMouse(true);
interactOnClick("quitGame()");
}});
//.. add more GUI elements here
}});
// </panel>
}});
// </layer>
}}.build(nifty));
// </screen>
nifty.gotoScreen("Screen_ID"); // start the screen
}
@Override
protected void onDisable() {
//Called when the state was previously enabled but is now disabled
//either because setEnabled(false) was called or the state is being
//cleaned up.
}
@Override
public void update(float tpf) {
//TODO: implement behavior during runtime
}
@Override
public void bind(Nifty nifty, Screen screen) {
System.out.println("Bind not supported yet.");
}
@Override
public void onStartScreen() {
System.out.println("onStartScreen not supported yet.");
}
@Override
public void onEndScreen() {
System.out.println("onEndScreen not supported yet.");
}
public void quitGame() {
getApplication().stop();
}
}
Main.java:
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.renderer.RenderManager;
public class Main extends SimpleApplication {
StartScreen startScreen = new StartScreen();
public static void main(String[] args) {
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp() {
stateManager.attach(startScreen);
}
@Override
public void simpleUpdate(float tpf) {
// This prints a non-null value
//System.out.println(startScreen.getApplication());
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}
Any idea what could be the problem? (Thanks in advance)