Populating Nifty 'dropDown' before showing screen

Hi guys, I’m struggling with an issue with populating drop down menus at start up for multiple screens. I made a clean project to demonstrate this problem. This is my (simplified) situation:

  • I have two screens defined in a NiftyGUI XML file, both containing a drop down control
  • I want to populate the drop down controls at start up, since the screens will be swapped a lot and the contents of the drop down control will not change

Here is my XML file:
[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” />

&lt;screen id="myScreen1"&gt;
    &lt;layer childLayout="center"&gt;
        &lt;panel width="100px" height="100px" childLayout="vertical"&gt;
            &lt;control name="label" text="MyScreen1" /&gt;
            &lt;control id="myDropDown1" name="dropDown" /&gt;
        &lt;/panel&gt;
    &lt;/layer&gt;
&lt;/screen&gt;

&lt;screen id="myScreen2"&gt;
    &lt;layer childLayout="center"&gt;
        &lt;panel width="100px" height="100px" childLayout="vertical"&gt;
            &lt;control name="label" text="MyScreen2" /&gt;
            &lt;control id="myDropDown2" name="dropDown" /&gt;
        &lt;/panel&gt;
    &lt;/layer&gt;
&lt;/screen&gt;

</nifty>
[/java]

I have succeeded in loading one screen and populating it, in the following way:
[java]
nifty.fromXml(“Interface/myNifty.xml”, “myScreen1”);
DropDown<MyEnum> dd1 = nifty.getScreen(“myScreen1”).findNiftyControl(“myDropDown1”, DropDown.class);
for (MyEnum e : MyEnum.values()) {
dd1.addItem(e);
}
[/java]

I have tested the same for the second screen, so loading one screen and populating its drop down menu works, as long as the screen ID was passed as the initial screen ID when calling fromXML(). Now I would like to populate the drop down menu’s of both screens, even if one isn’t being shown. Here is my attempt:
[java]
nifty.fromXmlWithoutStartScreen(“Interface/myNifty.xml”);

// findNiftyControl finds “DropDownNull”, because the screens have not been initialized
DropDown<MyEnum> dd1 = nifty.getScreen(“myScreen1”).findNiftyControl(“myDropDown1”, DropDown.class);
DropDown<MyEnum> dd2 = nifty.getScreen(“myScreen2”).findNiftyControl(“myDropDown2”, DropDown.class);
for (MyEnum e : MyEnum.values()) {
// Crashes here: Cannot add items to a DropDownNull
dd1.addItem(e);
dd2.addItem(e);
}

nifty.gotoScreen(“myScreen1”);
[/java]

This doesn’t work because Nifty cannot find the controls. I think this is because the screens have not been initialized. My question now is: how can I setup drop down menus for a screen that has not been loaded before? I have tried calling gotoScreen() before accessing the drop down menu, but this also fails because there is a frame delay before the screen is activated. A ZIP with my test project is available here (300 kb, you need JME3 installed): https://dl.dropboxusercontent.com/u/333770/MyExample.zip

Hey guys, I found a way to work around this issue: you can initialize a screen “instantly” by calling nifty.gotoScreen() followed by nifty.update(). Here is the final code:

[java]
nifty.fromXmlWithoutStartScreen(“Interface/myNifty.xml”);

// findNiftyControl finds “DropDownNull”, because calling gotoScreen has one frame delay
nifty.gotoScreen(screenNames[0]);
nifty.update();
DropDown<MyEnum> dd1 = nifty.getScreen(screenNames[0]).findNiftyControl(“myDropDown1”, DropDown.class);
for (MyEnum e : MyEnum.values()) {
dd1.addItem(e);
}

nifty.gotoScreen(screenNames[1]);
nifty.update();
DropDown<MyEnum> dd2 = nifty.getScreen(screenNames[1]).findNiftyControl(“myDropDown2”, DropDown.class);
for (MyEnum e : MyEnum.values()) {
dd2.addItem(e);
}
[/java]

I think this only works as long as your current screen does not have an exit animation.

EDIT: If anyone knows how to initialize a screen without using gotoScreen, I would still like to know that. :slight_smile:

There’s a much easier way to do this. Go to your ScreenController class, and in the “bind()” method, do something like this:
[java]
DropDownControl dropdown = screen.findNiftyControl(“DropDownIDHere”);
dropdown.add(myObject);
dropdown.addAll(myObjectArray);
[/java]

It says the DropDownControl, ListBoxControl, etc. are depricated but they work just fine for me and it’s honestly not too complicated. There’s very few tutorials out there for Nifty but I highly recommend the NIfty Bible, its reference manual. I’ve found it extremely helpful in my time with it.