First nifty-tab of nifty-tabs not working

Hi,

I’ve got a problem (again…) and hope you can tell me how to solve this…

I have created an “option screen” for my Game using Nifty. Everything worked fine, except one little thing.

The controls in the first tab aren’t doing anything! (every following tab works fine)

I reduced the code more and more until I ended up here:



[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-default-styles.xml” />

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

<!-- start screen -->

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

<screen id=“start” controller=“controller.OptionMenuController”>

<layer id=“layer” backgroundColor="#003f" childLayout=“center”>

<panel width=“75%” height=“75%” childLayout=“center” >

<control id=“edit_tabs” name=“nifty-tabs” >

<control id=“tab_1” name=“nifty-tab” caption=“tab 1” >

<text text="foo " font=“Interface/Fonts/Default.fnt” />

<control id=“cb1” name=“checkbox” checked=“true” />

</control>

<control id=“tab_2” name=“nifty-tab” caption=“tab 2” >

<text text="baa " font=“Interface/Fonts/Default.fnt” />

<control id=“cb2” name=“checkbox” checked=“true” />

</control>

</control>

</panel>

</layer>

</screen>

</nifty>[/xml]



simpler it isn’t possible. BUT the problem is STILL there. If I hover over the checkbox in the 2nd Tab, it becomes highlightened and if I click it toggles the status as it should. On the first Tab however the checkbox doesn’t become highlightened on hover or toggled on click.



I load the screen with:



[java]

niftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, guiViewPort);

// Neues Nifty Object anlegen

nifty = niftyDisplay.getNifty();

OptionMenuController opt = new OptionMenuController(simpleApp);

nifty.fromXml(“Interface/NiftyXML/OptionsMenu.xml”, “start”, opt);

// Nifty an den View Port übergeben

guiViewPort.addProcessor(niftyDisplay);

// Cursor sichtbar machen, egal was vorher war…

inputManager.setCursorVisible(true);

nifty.gotoScreen(“start”);

[/java]



and the OptionMenuController is just “empty” (no functions implemented yet).



I also tried to:

  • wrap the label and checkbox into a panel… didn’t work,
  • delete the first panel… then the 2nd (now first) has the same problem.
  • swap the panels… then the “new” 1st has the problem, the “new” 2nd is working fine then.
  • used buttons insted of checkboxes… same problem as with checkboxes.



    I think this is a silly mistake I make, but I just don’t get it.



    Please help me,



    regards

    Markus

Heh, it’s a little strange that nifty does what it does in this case, but I believe I found your problem.

I copied your xml above and tested it with a standard basic nifty test case of mine and it worked right away.

Then I looked at your instantiation code and found you were starting the same screen twice, so I tried that and got your error.

I don’t know why you have that last “gotoScreen” at the end (I’m guessing it’s just a left over), but if you remove it, it should solve your problem. You’re already loading the screen with the fromXml method call.

1 Like

I think the answer from tumaini should help you for now.



I’d like to add that the current tabs control has several flaws. I’ve received a number of patches from mkaring which greatly improves the tabs control for the upcoming 1.3.2 Nifty release.



Besides a lot of bug fixes, a better and way more complete API it even looks a lot better as well:



http://t.co/RqwvjngN



:smiley:

1 Like

@Tumaini



Yep, that did it! Thanks.



But it would be to easy if everything would work now.

When I go from main to option Menu, everything is fine now. I switch back, everything in main is fine too. If I go into options again, the first tab isn’t displayed anymore… (but I can get it to show if i select another tab an then the fist again.).



So, I think I’m messing around with the Nifty instance.

Maybe I can tell you what I want and how I tried and maybe you can tell me a “better” way?

So here’s what I got so far:



SimpleApplication that contains a “MainMenuAppState” (implementation of AbstractAppState)



MainMenuAppState creates a Nifty instance and a “MainMenuController” (implementation of ScreenController)

Code of MainMenuAppState:

[java]



@Override

public void initialize(AppStateManager stateManager, Application app) {

super.initialize(stateManager, app);

super.setEnabled(false);

simpleApp = (SimpleApplication)app;

assetManager = app.getAssetManager();

inputManager = app.getInputManager();

audioRenderer = app.getAudioRenderer();

guiViewPort = app.getGuiViewPort();



niftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, guiViewPort);

// Neues Nifty Object anlegen

nifty = niftyDisplay.getNifty();

//nifty.fromXml(“Interface/NiftyXML/OptionsMenu.xml”, “start”, optionMenuController);

mainMenuController = new MainMenuController(simpleApp);



this.setEnabled(true);

}



@Override

public void setEnabled(boolean enabled){

if(enabled){

nifty.fromXml(“Interface/NiftyXML/MainMenu.xml”, “start”, mainMenuController);

// Nifty an den View Port übergeben

guiViewPort.addProcessor(niftyDisplay);

// Cursor sichtbar machen, egal was vorher war…

inputManager.setCursorVisible(true);

}else {

nifty.exit();

guiViewPort.removeProcessor(niftyDisplay);

}



super.setEnabled(enabled);

}



[/java]



MainMenuController creates an instance of “OptionMenuController” (implementation of ScreenController)

and contains the methods called from within the xml via [xml]<interact onClick=“options()”/>[/xml]

The “System.out.println(”…");"-s are just for debuging. They will be deletet if I get the whole thing to run.



Code of MainMenuController:

[java]



public class MainMenuController implements ScreenController{

private Nifty nifty;

private Screen screen;



private SimpleApplication app;



private OptionMenuController optionMenuController;



public MainMenuController(SimpleApplication app){

super();

if(app != null){

this.app = app;

}

}



public void bind(Nifty nifty, Screen screen) {

this.nifty = nifty;

this.screen = screen;

}



public void newGame(){

System.out.println(“newGame()”);

}



public void options(){

System.out.println(“options()”);

optionMenuController = new OptionMenuController(app);

nifty.fromXml(“Interface/NiftyXML/OptionsMenu.xml”, “options”, optionMenuController);

System.out.println("MainMenuController: # of screens: " + nifty.getAllScreensName().size());

System.out.println("MainMenuController attached: " + nifty.findScreenController(“controller.MainMenuController”).equals(this));

System.out.println(“OptionMenuController attached: " + nifty.findScreenController(“controller.OptionMenuController”).equals(optionMenuController));

}



public void help(){

System.out.println(“help()”);

}



public void quitGame(){

System.out.println(“Komm nicht von der Strasse ab! Bye!”);

app.stop();

}



public void onStartScreen() {

System.out.println(“MainMenuController.onStartScreen() called”);

}



public void onEndScreen() {

System.out.println(“MainMenuController.onEndScreen() called”);

}



}



[/java]



The OptionMenuController looks pretty much the same as the MainMenuController, just vice versa. It should send the user back to mainmenu with a click on the “back” button (call to back() method).

Code:



[java]



public class OptionMenuController implements ScreenController{

private Nifty nifty;

private Screen screen;



private SimpleApplication app;



private MainMenuController mainMenuController;



public OptionMenuController(SimpleApplication app){

super();

if(app != null){

this.app = app;

}

}



public void bind(Nifty nifty, Screen screen) {

this.nifty = nifty;

this.screen = screen;

}



public void back(){

System.out.println(“back()”);

mainMenuController = new MainMenuController(app);

nifty.fromXml(“Interface/NiftyXML/MainMenu.xml”, “start”, mainMenuController);

System.out.println(”# of screens: " + nifty.getAllScreensName().size());

System.out.println("MainMenuController attached: " + nifty.findScreenController(“controller.MainMenuController”).equals(mainMenuController));

System.out.println("OptionMenuController attached: " + nifty.findScreenController(“controller.OptionMenuController”).equals(this));

}



public void accept(){

System.out.println(“accept()”);

}



public void reset(){

System.out.println(“reset()”);

}



public void test(){

System.out.println(“test()”);

}



public void onStartScreen() {

System.out.println(“OptionMenuController.onStartScreen() called”);

}



public void onEndScreen() {

System.out.println(“OptionMenuController.onEndScreen() called”);

}



}



[/java]



So, as you might see I want the user to stay in MainMenuAppState, where he can access several submenus (e.g. options). From all these menus the user should get back to main menu (except the “start game” button, where the AppState is leaft and the “RunningAppState” starts, but this is a different storry. :slight_smile: ).



I know, I could use ONE big xml and ONE big ScreenController Class with just “gotoScreen()” calls, but I plan to have more than 1 or 2 submenus, so these files would “explode” in size and get messy. Thats why I want to split the controller and xml into matching files with less code.



So, what’s the best way of doing so? Am I on the right track or just totally wrong?

Thanks again, regards



Markus



btw. @void256 the new design looks way better! Hope this comes soon. :wink:

Keep up the good work guys!