tonegodGUI Screen Null with AppState

Okay, so another t0neg0d GUI. So I heard t0neg0d’s plea, and decided to use a single screen per AppState. Simple enough. In my main menu state, I have a screen, and I add a button. Then, when the button is hit, it switches to the LevelState, where a new screen is being created. Only problem is, I get a null pointer exception on that line, and I’m not sure what is null…

Here is the MainMenuState:

[java]public class MainMenuState extends AbstractAppState {

AppStateManager stateManager;
SimpleApplication app;
Screen screen;
Node guiNode;
Node rootNode;
           
@Override
public void initialize(final AppStateManager stateManager, Application app) {
    super.initialize(stateManager, app);
    
    this.stateManager = stateManager;
    this.app = (SimpleApplication)app;
    this.rootNode = this.app.getRootNode();
    this.guiNode = this.app.getGuiNode();
    
    screen = new Screen(this.app);
    guiNode.addControl(screen);
    
    ButtonAdapter start_button = new ButtonAdapter(screen,"panel", new Vector2f(15, 15)) {
        @Override
        public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
            
            stateManager.detach(Main.main_menu_state);
         
            //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

    };
    start_button.setText("hello");
    //panel.hide();
    screen.addElement(start_button);
    
    app.getInputManager().setCursorVisible(true);
    //TODO: initialize your AppState, e.g. attach spatials to rootNode
    //this is called on the OpenGL thread after the AppState has been attached
}

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

}

@Override
public void cleanup() {
    super.cleanup();
    
    guiNode.removeControl(screen);
    stateManager.attach(Main.level_state);
    //screen.r
    //guiNode.detachAllChildren();
    //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]

And then here is up to the line where the error occurs:

[java]public void initialize(AppStateManager stateManager, Application app) {
super.initialize(stateManager, app);

    System.out.println(app);
    this.app = (SimpleApplication)app;
    this.stateManager = stateManager;
    this.assetManager = this.app.getAssetManager();
    this.cam = this.app.getCamera();
    this.rootNode = this.app.getRootNode();
    this.guiNode = this.app.getGuiNode();
    
    generalSetup();
    
    setupPlayer();
    
    //createMappings();
    
    rxf = new ReadXMLFile("Textures/testMap.tmx",assetManager,bas);
    rxf.parse();
    l = rxf.createLevel(cam);
                       
    rootNode.attachChild(l);
    
    setupCollidables();
    
    createMappings();

    game_timer = new LwjglTimer();
    
    System.out.println(this.app);

    Screen screen = new Screen(this.app);[/java]

Pretty simple, I think. Create a screen, wait for the button to get hit, detach the state, cleanup by removing the screen control and attaching the new state. In new state, create new screen. Where is something null? The System.out.println(this.app) doesn’t return nulll, so … help?

You shouldn’t have this line :
[java]guiNode.removeControl(screen);[/java]

It’s usefull only when you close the app or want to deactivate the gui. That’s all.

These 2 lines should be called once at gui initialization (in simpleInitApp for example) :
[java]screen = new Screen(this.app);
guiNode.addControl(screen);[/java]

…i know it’s not really clear but a screen is not really a screen…it’s more a screenManager…

Hello again, haze.

So having one screen across all the AppStates, is what t0neg0d really wanted us to do? I clearly misunderstood then.

Then, should I be passing a screen between every AppState?

And I should be removing elements from the screen individually when I want to clear the screen for elements of another AppState?

Yes that’s it ^^.

Yes :stuck_out_tongue: …everywhere you want a tonegod gui thing you need that screen, so pass the reference or use something like that in the main class (for example) :
[java]
private static Screen screenManager;

public static Screen getScreenManager() {
if (screenManager == null) {
screenManger = new Screen(app);
guiNode.addControl(screenManager);
}
return screenManager;
}[/java]

And yes…again…you should addElement in the initialize and remove them in the cleanup…and eventually in the setEnable too (to avoid a long elements enumeration you could setup a background panel (which really represents a screen this time) and just remove it when the screen is not enabled or loop with getChildren to remove elements from it without reference ;))

Thanks Haze. It works nicely now.

I guess I’ll talk to you again when I have another t0neg0d GUI issue :wink:

:wink:

I may have read this wrong, but… did you mean:

Single screen… multiple AppStates?

Well, it depends where you are talking about what I meant.

If you are talking about here:

and decided to use a single screen per AppState

Then I meant using a screen per AppState (i.e. I have 5 states, I’ll have 5 screens).

If you are talking about here:

one screen across all the AppStates

This is when I came to the understanding that I needed 1 screen for all the AppStates (i.e. I have 5 states, 1 screen).