NullPointException in AbstractAppState von JME3

Man kann seine eigenen AppStates einfach durch das Überlagern der AbstractAppState Klasse erzeugen. Dann fügt man sie dem stateManager durch die Methode attach(AbstractAppState) hinzu. Zuletzt startet man den AppState über enable(true).

In der überlagerten enable(boolean) Methode macht man nun zum Beispiel Objekte über Node.setCullHint(Spatial.CullHint.Dynamic); sichtbar.

Main.java


public class Main extends SimpleApplication {

MyState sws;

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

@Override
 public void simpleInitApp() {
 sws = new MyState();
 stateManager.attach(sws);
 sws.enable(true)
}}

MyState.java


public class MyState extends AbstractAppState {

private boolean isRunning;
private Node node;

public@Override
 void initialize(AppStateManager stateManager, Application app) {
 super.initialize(stateManager, app);
 //Not called
 node = new Node();

}

 @Override
 public void setEnabled(boolean enabled) {
 // Pause and unpause
 super.setEnabled(enabled);
 if(enabled){
 // init stuff that is in use while this state is RUNNING
//NPE!!!
 node.setCullHint(Spatial.CullHint.Dynamic);
 isRunning = true;
 } else {
 isRunning = false;
 // take away everything not needed while this state is PAUSED
 }
 }
}

Nach einem ersten Testlauf wurde gleich einmal eine NullPointException in enable(boolean) ausgelöst. Warum?

Der Fehler

Ich habe stateManager.attach(AbstaractAppState) und AppState.enable(true) in der simpleInitApp() ausgeführt.

Der stateManager initialisiert alle AppStates der Reihe nach. Das heißt, dass zuerst simpleInitApp() ausgeführt wird. In simpleInitApp() wird zuerst MyState dem stateManager hinzugefügt. Dieser tut diesen in eine List und führt ihn nach der Fertigstellung von simpleInitApp() aus. Zuvor wird jedoch MyState.enable(true) ausgeführt, weil dies in simpleInitApp() steht. In enable(boolean) wird aber auf ein Objekt zugegriffen, welches erst in initialize() erzeugt wird. Dies führt zur NPE.

Die Lösung

MyState.enable(true) darf man erst in simpleUpdate() aufrufen.

Main.java


public class Main extends SimpleApplication {

MyState sws;
 int step = 0;
 public static void main(String[] args) {
 Main app = new Main();
 app.start();
 }

@Override
 public void simpleInitApp() {
 sws = new MyState();
 stateManager.attach(sws);
 step = 1;

 }

@Override
 public void simpleUpdate(float tpf) {
 if(step == 1){
 sws.setEnabled(true);
 step = 2;
 }
}}

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s