[nifty-gui] Multiple Screens with the same ScreenController

Hey,

i’m developing my GUI in nifty with some appstates, but when i try to use the nifty gui in one appstate - the gamerunningstate - i’ve got the following problem:



[java]

nifty.fromXml(“PATH”, “pausescreen”);

nifty.registerScreenController(this);

[/java]

So i can use my screencontroller in the class. But when i press my button i want to change the screen:

[java]

nifty.gotoScreen(“settingsscreen”);

[/java]



On my settings screen i cant use my buttons: but when i use a button that were on the place from the button of the screen before and i click, i get the command from the last screen. can anyone help me?



thanks and regards,

tom

You need to register the screen controller before doing the fromXml (or as part of the fromXml call) as otherwise nifty creates a new one for you.

yes, but it also works only for one screen, the first one. when i change the order, to display the settingsscreen at first, i can use the control from the settings screen but not these from the pausescreen.

Really nifty expects you to use a different controller for each screen…although without seeing more of your code I’m not sure why it wouldn’t work.



Why do you not want to use a different controller?

'cause i want to change my nifty screen inside the action and then its easier to do this in one file… i think that i’m a little bit too lazy :smiley: i’ll try it with multiple controllers; thanks

I use one controller for multiple screens all the time. It can be done… I’m not sure why it isn’t working for you.



Or maybe something changed recently and I just haven’t noticed my code is broken yet.

Okay; heres my GameRunningState:

[java]

package net.wronguniverse.src.States;



/**

*

  • @author tom

    /

    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.font.BitmapFont;

    import com.jme3.font.BitmapText;

    import com.jme3.input.FlyByCamera;

    import com.jme3.input.InputManager;

    import com.jme3.input.KeyInput;

    import com.jme3.input.controls.ActionListener;

    import com.jme3.input.controls.KeyTrigger;

    import com.jme3.material.Material;

    import com.jme3.math.ColorRGBA;

    import com.jme3.math.FastMath;

    import com.jme3.math.Quaternion;

    import com.jme3.math.Vector3f;

    import com.jme3.niftygui.NiftyJmeDisplay;

    import com.jme3.renderer.Camera;

    import com.jme3.renderer.ViewPort;

    import com.jme3.scene.Geometry;

    import com.jme3.scene.Node;

    import com.jme3.scene.shape.Box;

    import com.jme3.scene.shape.Cylinder;

    import com.jme3.ui.Picture;

    import de.lessvoid.nifty.EndNotify;

    import de.lessvoid.nifty.Nifty;

    import de.lessvoid.nifty.NiftyEvent;

    import de.lessvoid.nifty.NiftyEventSubscriber;

    import de.lessvoid.nifty.builder.EffectBuilder;

    import de.lessvoid.nifty.builder.PopupBuilder;

    import de.lessvoid.nifty.controls.Console;

    import de.lessvoid.nifty.controls.ConsoleCommands;

    import de.lessvoid.nifty.controls.ConsoleCommands.ConsoleCommand;

    import de.lessvoid.nifty.controls.ConsoleExecuteCommandEvent;

    import de.lessvoid.nifty.controls.console.builder.ConsoleBuilder;

    import de.lessvoid.nifty.elements.Element;

    import de.lessvoid.nifty.input.NiftyInputEvent;

    import de.lessvoid.nifty.input.mapping.DefaultInputMapping;

    import de.lessvoid.nifty.screen.KeyInputHandler;

    import de.lessvoid.nifty.screen.Screen;

    import de.lessvoid.nifty.screen.ScreenController;

    import java.util.Calendar;

    import java.util.Timer;

    import java.util.logging.Level;

    import net.wronguniverse.src.Core;



    import net.wronguniverse.src.Controllers.
    ;





    public class GameRunningState extends AbstractAppState implements ScreenController {



    private ViewPort viewPort;

    private ViewPort guiViewPort;

    private Node rootNode;

    private Node guiNode;

    private AssetManager assetManager;

    private AudioRenderer audioRenderer;

    private InputManager inputManager;

    private Node localRootNode = new Node(“Game Screen RootNode”);

    private Node localGuiNode = new Node(“Game Screen GuiNode”);

    private final ColorRGBA backgroundColor = ColorRGBA.Black;

    private ViewPort localGuiViewPort;



    private NiftyJmeDisplay niftyDisplay;

    public Nifty nifty;



    private FlyByCamera flyCam;



    private boolean isRunning = true;



    private long startMillis = 0;



    BitmapFont myFont;

    private Screen screen;



    private SimpleApplication app;

    private ScreenController screencontroller;



    public GameRunningState(SimpleApplication app){

    this.rootNode = app.getRootNode();

    this.viewPort = app.getViewPort();

    this.guiViewPort = app.getGuiViewPort();

    this.guiNode = app.getGuiNode();

    this.assetManager = app.getAssetManager();

    this.inputManager = app.getInputManager();

    this.audioRenderer = app.getAudioRenderer();

    this.flyCam = app.getFlyByCamera();

    this.app = app;



    //myFont = assetManager.loadFont(“Interface/Fonts/Tork.fnt”);

    }



    @Override

    public void initialize(AppStateManager stateManager, Application app) {

    super.initialize(stateManager, app);



    inputManager.setCursorVisible(false);

    Box b = new Box(Vector3f.ZERO, 1, 1, 1); // create cube shape at the origin

    Geometry geom = new Geometry(“Box”, b); // create cube geometry from the shape

    Material mat = new Material(assetManager,

    “Common/MatDefs/Misc/Unshaded.j3md”); // create a simple material

    mat.setColor(“Color”, ColorRGBA.Blue); // set color of material to blue

    geom.setMaterial(mat); // set the cube’s material

    localRootNode.attachChild(geom);



    inputManager.addMapping(“Pause”, new KeyTrigger(KeyInput.KEY_ESCAPE));

    inputManager.addListener(gameListener, “Pause”);





    niftyDisplay = new NiftyJmeDisplay(assetManager,

    inputManager,

    audioRenderer,

    guiViewPort);



    nifty = niftyDisplay.getNifty();





    nifty.registerScreenController(this);



    nifty.fromXml(“Interface/GUI/GUI_04.xml”, “pausescreen”);



    nifty.getScreen(“pausescreen”).findElementByName(“multimode”).disable();





    }



    private ActionListener gameListener = new ActionListener() {

    public void onAction(String name, boolean keyPressed, float tpf) {

    if (name.equals(“Pause”) && !keyPressed) {

    isRunning = !isRunning;



    }

    }

    };



    @Override

    public void update(float tpf) {





    if(isRunning) {

    guiViewPort.removeProcessor(niftyDisplay);

    inputManager.setCursorVisible(false);

    flyCam.setEnabled(true);



    } else {

    nifty.registerScreenController(this);

    guiViewPort.addProcessor(niftyDisplay);

    inputManager.setCursorVisible(true);

    flyCam.setEnabled(false);

    }



    rootNode.attachChild(localRootNode);

    guiNode.attachChild(localGuiNode);



    }



    public static int rand(int low, int high) {

    return (int) (Math.random() * (high - low) + low);

    }



    @Override

    public void stateAttached(AppStateManager stateManager) {

    rootNode.attachChild(localRootNode);

    guiNode.attachChild(localGuiNode);

    viewPort.setBackgroundColor(backgroundColor);

    }



    @Override

    public void stateDetached(AppStateManager stateManager) {

    rootNode.detachChild(localRootNode);

    guiNode.detachChild(localGuiNode);



    }



    public void bind(Nifty nifty, Screen screen) {

    this.nifty=nifty;

    this.screen=screen;

    }



    public void onStartScreen() {

    }



    public void onEndScreen() {

    }



    public void showSettings() {



    nifty.gotoScreen(“settingsscreen2”);



    nifty.addControls();



    }

    public void showMenu() {

    nifty.gotoScreen(“pausescreen”);

    nifty.addControls();



    }





    }

    [/java]



    and GUI_04.xml:

    [xml]<?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”>





    <useControls filename=“nifty-default-controls.xml” />

    <useStyles filename=“nifty-wronguniverse-styles.xml” />

    <!–<useStyles filename=“nifty-default-styles.xml” />–>











    <!-- +++++++++++++++++++++++++++++++++++++++ -->

    <!-- start screen -->

    <!-- +++++++++++++++++++++++++++++++++++++++ -->





    <screen id=“pausescreen” controller=“net.wronguniverse.src.States.GameRunningState” visibleToMouse=“true”> <!-- CONTROLLER: controller=“wronguniverse.Main” -->

    <layer id=“layer” childLayout=“vertical” visibleToMouse=“true”>











    <panel id=“top2” height=“10%” width=“100%” childLayout=“center” backgroundColor="#222" align=“center”>



    <text text=“Spiel pausiert” color="#fff"

    font=“Interface/Fonts/Default.fnt” align=“center” />



    </panel>



    <panel id=“middle2” height=“80%” width=“100%” childLayout=“center” backgroundColor="#00000000" >



    <text text="-- TRANZPARENTER BLICK --" color="#aaa"

    font=“Interface/Fonts/Default.fnt” align=“center” />



    </panel>



    <panel id=“bottom” height=“10%” width=“100%” childLayout=“center” backgroundColor="#222" align=“center”>



    <panel childLayout=“horizontal” width=“100%” height=“100%” visibleToMouse=“true”>



    <panel width=“5.5%” />



    <control name=“button” label=“Zurück zum Spiel” id=“singlemode” width=“20%”

    visibleToMouse=“true” align=“center” valign=“center”>

    <interact onClick=“changeMode()”/>

    </control>

    <panel width=“3%” />

    <control name=“button” label=“Erfolge + Statistik” id=“multimode” width=“20%”

    visibleToMouse=“true” align=“center” valign=“center”>

    <interact onClick=“chan()”/>

    </control>

    <panel width=“3%” />

    <control name=“button” label=“Optionen” id=“settingsmode” width=“20%”

    visibleToMouse=“true” align=“center” valign=“center”>

    <interact onClick=“showSettings()”/>

    </control>

    <panel width=“3%” />

    <control name=“button” label=“Speichern und zum Hauptmenü” id=“exits” width=“20%”

    visibleToMouse=“true” align=“center” valign=“center”>

    <interact onClick=“exitSyst()”/>

    </control>

    <panel width=“5.5%” />

    </panel>



    </panel>

















    </layer>



    </screen>



    <screen id=“settingsscreen2” controller=“net.wronguniverse.src.States.GameRunningState” visibleToMouse=“true”> <!-- CONTROLLER: controller=“wronguniverse.Main” -->

    <layer id=“layer2” childLayout=“vertical” visibleToMouse=“true”>



    <panel id=“top2” height=“10%” width=“100%” childLayout=“center” backgroundColor="#222" align=“center”>



    <text text=“Einstellungen” color="#fff"

    font=“Interface/Fonts/Default.fnt” align=“center” />



    </panel>



    <panel id=“middle2” height=“80%” width=“100%” childLayout=“center” backgroundColor="#00000000" >



    <text text="-- TRANZPARENTER BLICK – ODER BILD --" color="#aaa"

    font=“Interface/Fonts/Default.fnt” align=“center” />



    </panel>



    <panel id=“bottom2” height=“10%” width=“100%” childLayout=“center” backgroundColor="#222" align=“center”>



    <panel childLayout=“horizontal” width=“100%” height=“100%” visibleToMouse=“true”>



    <panel width=“5.5%” />



    <control name=“button” label="&lt;&lt; Zurück" id=“showmenu” width=“20%”

    visibleToMouse=“true” align=“center” valign=“center”>

    <interact onClick=“showMenu()”/>

    </control>



    <panel width=“49%” />

    <control name=“button” label=“Zurücksetzen” id=“resetsettings” width=“20%”

    visibleToMouse=“true” align=“center” valign=“center”>

    <interact onClick=“showMenu()”/>

    </control>

    <panel width=“5.5%” />

    </panel>



    </panel>

















    </layer>



    </screen>







    </nifty>

    [/xml]



    it doesn’t work for me.
@tommy5696 said:
Hey,
i'm developing my GUI in nifty with some appstates, but when i try to use the nifty gui in one appstate - the gamerunningstate - i've got the following problem:

[java]
nifty.fromXml(&quot;PATH&quot;, &quot;pausescreen&quot;);
nifty.registerScreenController(this);
[/java]
So i can use my screencontroller in the class. But when i press my button i want to change the screen:
[java]
nifty.gotoScreen(&quot;settingsscreen&quot;);
[/java]

On my settings screen i cant use my buttons: but when i use a button that were on the place from the button of the screen before and i click, i get the command from the last screen. can anyone help me?

thanks and regards,
tom


Wait... so the visuals transition to the new screen but your clicks are still in the same place as the old screen?

That sounds like there was an exception thrown during the screen transition or something. I know in the version of JME that I'm running, sometimes exceptions get swallowed and somehow show up as debug log messages (but I've turned debugging off and so never see them).

If you start on the second screen does the second screen work?

yes, i can see my screen but can’t interact.



in my output there are only logs with the level INFO…

I personally prefer using a screen controller for each XML. The reason is that the screen controller can become really bloated. Nothing wrong with it though.

@madjack said:
I personally prefer using a screen controller for each XML. The reason is that the screen controller can become really bloated. Nothing wrong with it though.


The things is... I may have 20 menu items spread across 4 screens. No reason to clutter my code with 4 classes that do almost nothing... especially since a different screen resolution might be able to use a tighter screen layout anyway.

And anyway, his (and my) multiple screens are all in the same XML file anyway.

My Options screen has more than 500 lines of code and it’s nowhere final (about 50%). Same for my HUD screen.



I simply find it much more convenient to segregate things that way. As I said, there’s nothing wrong with either way.