Pass argument from AbstractAppState to main class

Hello.

I have: a main class called Kartex.java, a second class called MainMenu.java which extends AbstractAppState and has a Nifty object as a class field. The Nifty field uses its appropriate nifty file called MainMenu.xml.

Usually when I want to call a method from the main class I just do onClick=“advanceNow()” on the xml file. But now the MainMenu.java (not the main class) class is handling the gui and not Kartex.java. So how do I call a method like advanceNow(); which resides in Kartex.java from the MainMenu.xml?

I tried setting the controller of the MainMenu.xml to be Kartex.java and not MainMenu.java but this causes the AbstractAppState which is MainMenu.java to not terminate correctly because arguments need to be passed during initialization. So assigning the class Kartex.java as a controller to MainMenu.xml instead of MainMenu.java doesn’t work in reality. Also, I want the MainMenu.java and MainMenu.xml to be self contained so making Kartex.java the controller for MainMenu.xml defeats that idea. Moreover, I would like a solution that doesn’t use any update loops to achieve this, for obvious performance reasons.

You can register controllers with nifty rather than have it automatically create them.

Like I said, the controllers are registered on the MainMenu.xml. But I have no way of calling methods in the main class which is Kartex.java.

Moreover, the problem is that the tutorials here only tell how to pass arguments and call methods from the main class to the class that extends AbstractAppState but not the other way around.

I hope I’m making it crystal clear. :slight_smile:

You could just set it up as a delegate, i.e MainMenu.java is the controller, and has an advanceNow (), which just calls Kartex.advanceNow ().

Or you can register on the Event bus (Nifty Bible), and intercept all mouse clicks on Nifty elements (optionally with a RegEx) and do what you want with them.

@wezrule:

Your second solution is what I described on the first post. It’s just not self contained which makes my screen display previously detached AbstractAppState.

But your first solution:

Yes I want this “You could just set it up as a delegate, i.e MainMenu.java is the controller” which is what I’m doing. But remember MainMenu.java doesn’t know Kartex.java exists so I can not do Kartex.advanceNow() inside MainMenu.java. That only works if I in Kartex.java made an object called MainMenu myMainMenu; mymainMeny.advanceNow(); which goes back to the problem of calling from main class to AbstractAppState and not the other way around.

Additionally, you might be tempted to say just do “super.advanceNow()”, but remember that MainMenu extends AbstractAppState and not Kartex.java.

Is this Kartex.java your SimpleApplication class? You can create a static accessor to it, and then access that from anywhere

Edit: actually its an appstate, so an Application object is passed in the initialize method, so you should be able to access most things from that.

Sorry, but this gives me and error for the assetManager which can not be referenced from a static method. Also, error with countless variables.

Thanks for the answer though.

The thing I notice is that using AbstractAppState seems to be a one way street only. :’(

For my initial suggestion:
http://hub.jmonkeyengine.org/forum/topic/outsourcing-code-from-simpleapplication/#post-146838

But there’s another solution, maybe you missed my edit above?

AppStates have a method which passes the application object to it:
[java] public void initialize(AppStateManager stateManager, Application app)[/java]

Where you can cast the app variable to your SimpleApplication class

The tutorial is very clear about what you just said. Here’s my code doing it:

[java]
/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package co.pixelapp.kartex;

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.asset.AssetManager;
import com.jme3.audio.AudioRenderer;
import com.jme3.bullet.BulletAppState;
import com.jme3.input.InputManager;
import com.jme3.niftygui.NiftyJmeDisplay;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MainMenu extends AbstractAppState implements ScreenController
{
private Nifty nifty;

private SimpleApplication app;
private Node              rootNode;
private AssetManager      assetManager;
private AppStateManager   stateManager;
private InputManager      inputManager;
private ViewPort          viewPort;
private BulletAppState    physics;
private AudioRenderer     audioRenderer;

@Override
public void initialize(AppStateManager stateManager, Application app)
{
    
    super.initialize(stateManager, app);
    this.app = (SimpleApplication) app; // can cast Application to something more specific
    this.rootNode     = this.app.getRootNode();
    this.assetManager = this.app.getAssetManager();
    this.stateManager = this.app.getStateManager();
    this.inputManager = this.app.getInputManager();
    this.viewPort     = this.app.getViewPort();
    this.physics      = this.stateManager.getState(BulletAppState.class);
    this.audioRenderer     = this.app.getAudioRenderer();

    
    
    NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,
                                                      inputManager,
                                                      audioRenderer,
                                                      viewPort);
    nifty = niftyDisplay.getNifty();
    
    Logger.getLogger("de.lessvoid.nifty").setLevel(Level.SEVERE); 
    Logger.getLogger("NiftyInputEventHandlingLog").setLevel(Level.SEVERE);

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

    // attach the nifty display to the gui view port as a processor
    viewPort.addProcessor(niftyDisplay);
    
    System.out.println("I have been initialized!");
}

@Override
public void update(float tpf) 
{
    
}    

@Override
public void stateDetached(AppStateManager stateManager) 
{
    
}

@Override
public void stateAttached(AppStateManager stateManager) 
{
    
}

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

public void onStartScreen() 
{
    
}

public void onEndScreen() 
{
    
}

public void advanceNow()
{
}

}

[/java]

Still this doesn’t allow me to call methods from Kartex.java. Even this.app doesn’t allow to do this this.app.advanceNow(), it is impossible.

Edit: Here is the rest of the program so you can judge for yourself.

[java]
public class Kartex extends SimpleApplication
{
private MainMenu mainMenuState;

@Override
public void simpleInitApp()
{
mainMenuState = new MainMenu();
stateManager.attach(mainMenuState);
//stateManager.detach(mainMenuState); //Here just for testing to see if it detaches completely/
}


}
[/java]

This is the DesktopGui.xml which I have been calling MainMenu.xml to make it intuitive to the readers here:

<?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” />
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- This demo shows a two-screen layout in Nifty’s XML syntax. -->
<!-- You see two screens with two layers each, contain several panels. -->
<!-- The panels contain images, text, and controls (label and buttons). -->
<!-- Buttons have an interaction defined, and some of the text -->
<!-- is dynamically defined, using the MyStartScreen controller. -->
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->

<!-- +++++++++++++++++++++++++++++++++++++++ -->
<!-- lay out the start screen/layers/panels -->
<!-- +++++++++++++++++++++++++++++++++++++++ -->
<screen id=“start” controller=“co.pixelapp.kartex.MainMenu”>
<layer id=“background” childLayout=“center”>
<image filename=“Textures/Kartexcard.png”></image>
</layer>
<layer id=“foreground” childLayout=“vertical”>
<panel id=“panel_top” height=“25%” width=“75%” align=“center” childLayout=“center”>
</panel>
<panel id=“panel_mid” height=“50%” width=“75%” align=“center” childLayout=“center”>

  &lt;/panel&gt;
  &lt;panel id="panel_bottom" height="25%" width="75%" align="center" childLayout="horizontal"&gt;  
    &lt;panel id="panel_bottom_left" height="50%" width="50%" valign="center" childLayout="center"&gt;  
      &lt;control name="button" label="Start" id="StartButton" align="center" valign="center" 
               visibleToMouse="true"&gt; 
        &lt;interact onClick="advanceNow()" /&gt;
      &lt;/control&gt;
    &lt;/panel&gt;
    &lt;panel id="panel_bottom_right" height="50%" width="50%" valign="center" childLayout="center"&gt;  
      &lt;control name="button" label="Quit" id="QuitButton" align="center" valign="center" 
      visibleToMouse="true" &gt; 
        &lt;interact onClick="quitGame()"/&gt;
      &lt;/control&gt;
    &lt;/panel&gt;
  &lt;/panel&gt;
&lt;/layer&gt;

</screen>

thats because SimpleApplication doesn’t have an advanceNow (). You need to cast it to your derived SimpleApplication class.

Edit: Cast it to Kartex

You also could have just passed “this” to MainMenu directly. This is all generic java related stuff

@wezrule

Please see the “full” update code above.

[java]private Kartex app;

@Override
public void initialize(AppStateManager stateManager, Application app)
{
this.app = (Kartex) app; // can cast Application to something more specific
}

public void advanceNow()
{
app.advanceNow();
}[/java]

Edit: also noticed your XML is wrong, it shouldn’t be

[java]controller=”co.pixelapp.kartex.Kartex”>[/java]

it should point to MainMenu

Argh. The previous states don’t get properly detached. We got back to square one. :frowning:

Edit: Yes, I know, it was co.pixelapp.kartex.MainMenu in my code.

It’s not the first time I encounter code like that. I guess my two way street approach is incompatible with the AbstractAppStates. :frowning:

@Pixelapp said: It's not the first time I encounter code like that. I guess my two way street approach is incompatible with the AbstractAppStates. :(

No, it’s fine. You just aren’t doing it right.

wezrule’s suggestions have been spot-on. Post the latest (not as an update but as a new message) with the problem you are having now and we will show you where your mistake is. This is one of the reasons we recommend that users know Java well before attempting to write a Java game. Casting to specific classes, etc. is very basic stuff.

1 Like

For your convenience: MenuSwitchProject

This is a test case. Notice how the first menu doesn’t go away. Instead you get stuck with the old and new menu.

[java]
/*

  • Copyright © 2009-2010 jMonkeyEngine
  • All rights reserved.
  • Redistribution and use in source and binary forms, with or without
  • modification, are permitted provided that the following conditions are
  • met:
    • Redistributions of source code must retain the above copyright
  • notice, this list of conditions and the following disclaimer.
    • Redistributions in binary form must reproduce the above copyright
  • notice, this list of conditions and the following disclaimer in the
  • documentation and/or other materials provided with the distribution.
    • Neither the name of ‘jMonkeyEngine’ nor the names of its contributors
  • may be used to endorse or promote products derived from this software
  • without specific prior written permission.
  • THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  • “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  • TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  • PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  • CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  • EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  • PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  • PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  • LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  • NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  • SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */
    package co.pixelapp.kartex;

import co.pixelapp.ocean.MyProjectedGrid;
import co.pixelapp.ocean.WaterHeightGenerator;
import com.jme3.input.event.TouchEvent.Type;
import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.app.SimpleApplication;
import com.jme3.bounding.BoundingBox;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
import com.jme3.bullet.control.GhostControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.control.VehicleControl;
import com.jme3.bullet.objects.VehicleWheel;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.cinematic.MotionPath;
import com.jme3.cinematic.MotionPathListener;
import com.jme3.cinematic.events.MotionEvent;
import com.jme3.collision.CollisionResults;
import com.jme3.input.KeyInput;
import com.jme3.input.TouchInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.TouchListener;
import com.jme3.input.controls.TouchTrigger;
import com.jme3.input.event.TouchEvent;
import com.jme3.material.MatParam;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Matrix3f;
import com.jme3.math.Quaternion;
import com.jme3.math.Ray;
import com.jme3.math.Vector3f;
import com.jme3.niftygui.NiftyJmeDisplay;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.CameraControl;
import com.jme3.scene.shape.Box;
import com.jme3.shadow.BasicShadowRenderer;
import com.jme3.texture.Texture.MagFilter;
import com.jme3.texture.Texture.MinFilter;
import com.jme3.texture.Texture2D;
import com.jme3.util.SkyFactory;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.elements.Element;
import de.lessvoid.nifty.elements.render.TextRenderer;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import jme3tools.optimize.GeometryBatchFactory;

public class Kartex extends SimpleApplication
{
float gravity = 9.81f; // Need private identifier.
float gameScale = 0.1f;
WaterHeightGenerator whGEN;
MyProjectedGrid grid;

private MainMenu mainMenuState;
private Hud hudState;

private byte level = 0;
   

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

@Override
public void simpleInitApp() 
{

    
    mainMenuState = new MainMenu();
    stateManager.attach(mainMenuState);
    //stateManager.detach(mainMenuState);

    flyCam.setEnabled(false);
    
    inputManager.setCursorVisible(true);
    
    cam.setFrustumFar(1000f);
    //flyCam.setMoveSpeed(10);      

}







public void simpleUpdate(float tpf) 
{   



      
}

public void startGame() 
{

}

public void setLevel(String arg)
{       
    level = Byte.parseByte(arg);
    
    switch(level)
    {
        case 1:
            stateManager.detach(mainMenuState);
            hudState = new Hud();
            stateManager.attach(hudState);
            break;
            
    }
}

public void quitGame()
{
  this.stop(); 
  System.out.println("Pressing quit!");
}

public void quit()
{
    
} 

}
[/java]

[java]
/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package co.pixelapp.kartex;

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.asset.AssetManager;
import com.jme3.audio.AudioRenderer;
import com.jme3.bullet.BulletAppState;
import com.jme3.input.InputManager;
import com.jme3.niftygui.NiftyJmeDisplay;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MainMenu extends AbstractAppState implements ScreenController
{
private Nifty nifty;

private SimpleApplication app;
private Node              rootNode;
private AssetManager      assetManager;
private AppStateManager   stateManager;
private InputManager      inputManager;
private ViewPort          viewPort;
private BulletAppState    physics;
private AudioRenderer     audioRenderer;
private Kartex kartapp;

@Override
public void initialize(AppStateManager stateManager, Application app)
{
    
    super.initialize(stateManager, app);
    this.app = (SimpleApplication) app; // can cast Application to something more specific
    this.rootNode     = this.app.getRootNode();
    this.assetManager = this.app.getAssetManager();
    this.stateManager = this.app.getStateManager();
    this.inputManager = this.app.getInputManager();
    this.viewPort     = this.app.getViewPort();
    this.physics      = this.stateManager.getState(BulletAppState.class);
    this.audioRenderer     = this.app.getAudioRenderer();

    this.kartapp = (Kartex) app; // can cast Application to something more specific
    
    NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,
                                                      inputManager,
                                                      audioRenderer,
                                                      viewPort);
    nifty = niftyDisplay.getNifty();
    
    Logger.getLogger("de.lessvoid.nifty").setLevel(Level.SEVERE); 
    Logger.getLogger("NiftyInputEventHandlingLog").setLevel(Level.SEVERE);

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

    // attach the nifty display to the gui view port as a processor
    viewPort.addProcessor(niftyDisplay);
    
    System.out.println("I have been initialized!");
}

@Override
public void update(float tpf) 
{
    
}    

@Override
public void stateDetached(AppStateManager stateManager) 
{
    
}

@Override
public void stateAttached(AppStateManager stateManager) 
{
    
}

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

public void onStartScreen() 
{
    
}

public void onEndScreen() 
{
    
}

public void setLevel(String lv)
{
    kartapp.setLevel(lv);
    
    System.out.println("Setting the level!");
}

public void quitGame()
{
    app.stop();
}

}

[/java]

[java]
/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package co.pixelapp.kartex;

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.asset.AssetManager;
import com.jme3.audio.AudioRenderer;
import com.jme3.bullet.BulletAppState;
import com.jme3.input.InputManager;
import com.jme3.niftygui.NiftyJmeDisplay;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.elements.Element;
import de.lessvoid.nifty.elements.render.TextRenderer;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Hud extends AbstractAppState implements ScreenController
{
private Nifty nifty;

private SimpleApplication app;
private Node              rootNode;
private AssetManager      assetManager;
private AppStateManager   stateManager;
private InputManager      inputManager;
private ViewPort          viewPort;
private BulletAppState    physics;
private AudioRenderer     audioRenderer;

@Override
public void initialize(AppStateManager stateManager, Application app)
{
    
    super.initialize(stateManager, app);
    this.app = (SimpleApplication) app; // can cast Application to something more specific
    this.rootNode     = this.app.getRootNode();
    this.assetManager = this.app.getAssetManager();
    this.stateManager = this.app.getStateManager();
    this.inputManager = this.app.getInputManager();
    this.viewPort     = this.app.getViewPort();
    this.physics      = this.stateManager.getState(BulletAppState.class);
    this.audioRenderer     = this.app.getAudioRenderer();

    
    
    NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,
                                                      inputManager,
                                                      audioRenderer,
                                                      viewPort);
    nifty = niftyDisplay.getNifty();
    
    Logger.getLogger("de.lessvoid.nifty").setLevel(Level.SEVERE); 
    Logger.getLogger("NiftyInputEventHandlingLog").setLevel(Level.SEVERE);

    nifty.fromXml("Interface/DesktopGUI.xml", "hud", this);

    // attach the nifty display to the gui view port as a processor
    viewPort.addProcessor(niftyDisplay);
    
    Element lapElement = nifty.getCurrentScreen().findElementByName("lapNumber");
    
    lapElement.getRenderer(TextRenderer.class).setText("Lap:\n 1");
    
    Element positionElement = nifty.getCurrentScreen().findElementByName("positionNumber");
    
    positionElement.getRenderer(TextRenderer.class).setText("Position:\n 4th");
    
    Element speedElement = nifty.getCurrentScreen().findElementByName("speedNumber");
    
    speedElement.getRenderer(TextRenderer.class).setText("Speed:\n 100k/h");
    
}

@Override
public void update(float tpf) 
{
    
}    

@Override
public void stateDetached(AppStateManager stateManager) 
{
    
}

@Override
public void stateAttached(AppStateManager stateManager) 
{
    
}


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

public void onStartScreen() 
{
    
}

public void onEndScreen() 
{

}

}
[/java]

[java]
<?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” />
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- This demo shows a two-screen layout in Nifty’s XML syntax. -->
<!-- You see two screens with two layers each, contain several panels. -->
<!-- The panels contain images, text, and controls (label and buttons). -->
<!-- Buttons have an interaction defined, and some of the text -->
<!-- is dynamically defined, using the MyStartScreen controller. -->
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->

<!-- +++++++++++++++++++++++++++++++++++++++ -->
<!-- lay out the start screen/layers/panels -->
<!-- +++++++++++++++++++++++++++++++++++++++ -->
<screen id=“start” controller=“co.pixelapp.kartex.MainMenu”>
<layer id=“background” childLayout=“center”>
<image filename=“Textures/Kartexcard.jpg”></image>
</layer>
<layer id=“foreground” childLayout=“vertical”>
<panel id=“panel_top” height=“25%” width=“75%” align=“center” childLayout=“center”>
</panel>
<panel id=“panel_mid” height=“50%” width=“75%” align=“center” childLayout=“center”>

  &lt;/panel&gt;
  &lt;panel id="panel_bottom" height="25%" width="75%" align="center" childLayout="horizontal"&gt;  
    &lt;panel id="panel_bottom_left" height="50%" width="50%" valign="center" childLayout="center"&gt;  
      &lt;control name="button" label="Start" id="StartButton" align="center" valign="center" 
               visibleToMouse="true"&gt; 
        &lt;interact onClick="setLevel(1)" /&gt;
      &lt;/control&gt;
    &lt;/panel&gt;
    &lt;panel id="panel_bottom_right" height="50%" width="50%" valign="center" childLayout="center"&gt;  
      &lt;control name="button" label="Quit" id="QuitButton" align="center" valign="center" 
      visibleToMouse="true" &gt; 
        &lt;interact onClick="quitGame()"/&gt;
      &lt;/control&gt;
    &lt;/panel&gt;
  &lt;/panel&gt;
&lt;/layer&gt;

</screen>

<!-- +++++++++++++++++++++++++++++++++++++++ -->
<!-- lay out the HUD screen/layers/panels -->
<!-- +++++++++++++++++++++++++++++++++++++++ -->
<screen id=“hud” controller=“co.pixelapp.kartex.Hud”>
<layer id=“background” childLayout=“center”>
<image filename=“Interface/tutorial/hud-frame.png”></image>
</layer>
<layer id=“foreground” childLayout=“vertical”>
<panel id=“panel_top” height=“25%” width=“75%” align=“center” childLayout=“horizontal”>
<panel id=“panel_bottom_left” height=“50%” width=“33%” valign=“center” childLayout=“center”>
<control name=“label” id=“lapNumber” font=“Interface/Fonts/BioDiscTitle.fnt”
color="#000" text=“Lap” width=“100%” height=“100%” />
</panel>
<panel id=“panel_bottom_center” height=“50%” width=“33%” valign=“center” childLayout=“center”>
<control name=“label” id=“positionNumber” font=“Interface/Fonts/BioDiscTitle.fnt”
color="#000" text=“Poston:” width=“100%” height=“100%” />
</panel>
<panel id=“panel_bottom_right” height=“50%” width=“33%” valign=“center” childLayout=“center”>
<control name=“label” id=“speedNumber” font=“Interface/Fonts/BioDiscTitle.fnt” color="#000" text=“Speed:” width=“100%” height=“100%” />
</panel>
</panel>
<panel id=“panel_bottom” height=“75%” width=“75%” align=“center” childLayout=“center”>
</panel>
</layer>
<!–
<layer id=“foreground” childLayout=“horizontal”>
<panel id=“panel_left” width=“80%” height=“100%” childLayout=“vertical” >
<control name=“label” id=“positionNumber” font=“Interface/Fonts/BioDiscTitle.fnt”
color="#000" text=“1st” width=“100%” height=“100%” />

  &lt;/panel&gt;
  &lt;panel id="panel_right" width="20%" height="100%" childLayout="vertical" &gt;  
    &lt;panel id="panel_top_right1" width="100%" height="15%" childLayout="center" &gt;  
      
    &lt;/panel&gt;
    &lt;panel id="panel_top_right2" width="100%" height="15%" childLayout="center" &gt;  
      
    &lt;/panel&gt;
    &lt;panel id="panel_bot_right" width="100%" height="70%" valign="center" &gt;  
    &lt;/panel&gt;
  &lt;/panel&gt;
&lt;/layer&gt;
--&gt;

</screen>
</nifty>

[/java]

kartexlogo

Hudimage

I notice your creating a new nifty processor in each initialize without cleaning up the previous one. It would be better to have just 1 and pass that reference around. If you remove setting nifty to SEVERE logging for now, you may see some more messages which can be useful.

@wezrule The classes are suppose to be independent. passing around the nifty object defeats the whole point of an modular (plug in style) AbstractAppState. Passing around the nifty would require one class to be always started first, and I don’t now if I’ll always use the class that starts first.

Edit: I feel we are chasing and invisible chicken here.

Create one nifty in the application. Set it up as a singleton and access it via application context from all the app states etc.

That’s all. I just wanted to see if I was overlooking something that was easy.

I know how to make those tricky hacks to make it work, but that was not the point.

Thanks anyways, everyone.