Moving Nifty Elements from One Screen to Another

I am constructing a quiz maker using NIfty. I begin by loading a basic question editor screen with:



nifty.fromXml(“Interface/questionEditorScreen.xml”, “questionEditor”, this);

nifty.gotoScreen(“questionEditor”);



In a previous version of my quiz maker, I successfully used the java builder code to generate my answer choice panels on the fly as needed. Recently while rewriting my application, I have gotten attached to using the Nifty-Editor v.1.0 which generates .xml files. I would like to dynamically add answer choice panels as needed by use via loading choice.xml template, giving it a unique id, then add it to my choicePanel. I tried but get NullPointerException with:



public void addChoice(){

nifty.addXml(“Interface/choice.xml”);

Element choice = nifty.getScreen(“choice”).findElementByName(“choicepanel”);

nextChoiceNum++;

choice.setId(“choice”+nextChoiceNum);

Element choicePanel = nifty.getScreen(“questionEditor”).findElementByName(“choicesPanel”);

choice.markForMove(choicePanel);

}



I also tried but get NullPointerException with:



public void addChoice(){

nifty.addXml(“Interface/choice.xml”);

Element choice = nifty.getScreen(“choice”).findElementByName(“choicepanel”);

nextChoiceNum++;

choice.setId(“choice”+nextChoiceNum);

Element choicePanel = nifty.getScreen(“questionEditor”).findElementByName(“choicesPanel”);

choice.add(choicePanel);

}



Where did I go wrong?

What is null? nifty? The screen? The element?

Thanks for the comment.



The output I get from:

public void addChoice(){

nifty.addXml(“Interface/choice.xml”);

Element choice = nifty.getScreen(“choice”).findElementByName(“choicepanel”);

nextChoiceNum++;

choice.setId(“choice”+nextChoiceNum);

Element choicePanel = nifty.getScreen(“questionEditor”).findElementByName(“choicesPanel”);

System.out.println(“The choice element is “+choice+”. The choicePanel element is “+choicePanel+”.”);

choice.markForMove(choicePanel);

}

is:

The choice element is choice1 (de.lessvoid.nifty.elements.Element@b788e5). The choicePanel element is choicesPanel (de.lessvoid.nifty.elements.Element@17caa26).

Dec 06, 2012 5:36:58 PM com.jme3.app.Application handleError

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.lang.NullPointerException

at de.lessvoid.nifty.Nifty$ElementMoveAction.perform(Nifty.java:1005)

at de.lessvoid.nifty.Nifty$EndOfFrameElementAction.perform(Nifty.java:1023)

at de.lessvoid.nifty.Nifty.executeEndOfFrameElementActions(Nifty.java:397)

at de.lessvoid.nifty.Nifty.handleDynamicElements(Nifty.java:316)

at de.lessvoid.nifty.Nifty.access$1500(Nifty.java:73)

at de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl.processEvent(Nifty.java:1371)

at de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl.processMouseEvent(Nifty.java:1329)

at com.jme3.niftygui.InputSystemJme.handleMouseEvent(InputSystemJme.java:124)

at com.jme3.niftygui.InputSystemJme.onMouseButtonEventQueued(InputSystemJme.java:196)

at com.jme3.niftygui.InputSystemJme.forwardEvents(InputSystemJme.java:260)

at de.lessvoid.nifty.Nifty.update(Nifty.java:248)

at com.jme3.niftygui.InputSystemJme.endInput(InputSystemJme.java:113)

at com.jme3.input.InputManager.processQueue(InputManager.java:821)

at com.jme3.input.InputManager.update(InputManager.java:885)

at com.jme3.app.Application.update(Application.java:606)

at com.jme3.app.SimpleApplication.update(SimpleApplication.java:230)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)

at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228)

at java.lang.Thread.run(Thread.java:722)





The nifty, the screens and elements seem to all be non-Null. I’m confused.





I called the System.out just before

do you call [java]nifty.addXml("Interface/choice.xml");[/java] more than once, and is there a screencontroller definition in the xml file?

@wezrule

do you call

nifty.addXml(“Interface/choice.xml”);

more than once, and is there a screencontroller definition in the xml file?



No, I only call it once and there is a screencontroller assigned in the xml file.



What I did notice was the program seems to be in the process of loading the choice.xml file when the markForMove is called. Here is the verbose output.






(controller => fpl.GUIManager, id => choice)

children layers: 1

[element] (backgroundColor => #5500cc, childLayout => absolute, id => choice)

()

()

children elements: 1

[element] (style => nifty-panel-simple, name => choicepanel, imageMode => resize:9,2,9,9,9,2,9,2,9,2,9,9 {nifty-panel-simple}, id => choicepanel, width => 50%, y => 0, padding => 5px {nifty-panel-simple}, backgroundImage => panel/nifty-panel-simple.png {nifty-panel-simple}, x => 0, childLayout => absolute, height => 35px)

()

()

children elements: 2

[element] (style => nifty-textfield, name => textfield, id => textfield3, width => 90%, controller => de.lessvoid.nifty.controls.textfield.TextFieldControl, inputMapping => de.lessvoid.nifty.controls.textfield.TextFieldInputMapping, y => 0, focusable => true, x => 5, childLayout => overlay {nifty-textfield#panel}, height => 23px {nifty-textfield#panel})

(onClickMouseMove => onClickMouseMove(), onClick => onClick())

()

children elements: 2

[element] (backgroundColor => #666f {nifty-textfield#field}, childClip => true {nifty-textfield#field}, style => #field, childLayout => center {nifty-textfield#field}, visibleToMouse => true, padding => 0px,2px {nifty-textfield#field}, id => textfield3#field)

()

()

(name => changeMouseCursor, id => textFieldCursor)

()

(color => #822f, name => border, post => true)

The choice element is choice1 (de.lessvoid.nifty.elements.Element@1991731). The choicePanel element is choicesPanel (de.lessvoid.nifty.elements.Element@1c192c8).

()

(inset => 1px, color => #800f, name => colorBar, post => true)

(inset => 1px, color => #222f, name => border, post => true)

(name => renderQuad, post => true, length => 150, endColor => #2220, startColor => #2228)

(name => renderQuad, post => true, length => 150, endColor => #2228, startColor => #2220)

children elements: 1

[element] (style => #text, id => textfield3#field#text, textHAlign => left {nifty-textfield#text}, font => aurulent-sans-16.fnt {base-font}, color => #000f {nifty-textfield#text}, align => left {nifty-textfield#text}, selectionColor => #f00f {nifty-textfield#text}, valign => center {nifty-textfield#text}, visibleToMouse => false {nifty-textfield#text})

()

()

(color => #cccf, name => textColor, post => false)

no children elements

[element] (style => #cursor-panel, childLayout => absolute {nifty-textfield#cursor-panel}, padding => 0px,2px {nifty-textfield#cursor-panel})

()

()

children elements: 1

[element] (filename => textfield/cursor-empty.png {nifty-textfield#cursor}, style => #cursor, id => textfield3#cursor)

()

()

(filename => textfield/cursor.png, name => imageOverlayPulsate, post => true, timeType => infinite, pulsateType => rectangle, period => 250)

no children elements

[element] (style => nifty-checkbox-style, name => checkbox, width => 23px {nifty-checkbox-style#panel}, id => checkbox1, controller => de.lessvoid.nifty.controls.checkbox.CheckboxControl, y => 0, focusable => true, x => 364, visibleToMouse => true, childLayout => center {nifty-checkbox-style#panel}, backgroundColor => #666f {nifty-checkbox-style#panel}, height => 23px {nifty-checkbox-style#panel})

(onClick => onClick())

()

(color => #822f, name => border, post => true)

()

(inset => 1px, color => #800f, name => colorBar, post => true)

(inset => 1px, color => #222f, name => border, post => true)

(name => renderQuad, post => true, length => 150, endColor => #2220, startColor => #2228)

(name => renderQuad, post => true, length => 150, endColor => #2228, startColor => #2220)

children elements: 1

[element] (height => 32px {nifty-checkbox-style#select}, valign => center {nifty-checkbox-style#select}, style => #select, width => 32px {nifty-checkbox-style#select}, id => checkbox1#select, align => center {nifty-checkbox-style#select})

()

()

(startSize => 2.0, name => imageSize, post => true, length => 250, endSize => 1.0, customKey => show)

(end => #f, name => fade, post => true, length => 250, customKey => show, start => #0)

(height => 32px, neverStopRendering => true, filename => checkbox/checkbox.png, name => imageOverlay, post => true, width => 32px, customKey => show)

(end => #0, name => fade, post => true, length => 250, customKey => hide, start => #f)

(height => 32px, filename => checkbox/checkbox.png, name => imageOverlay, post => true, width => 32px, length => 250, customKey => hide)

(end => #f, name => fade, post => false, length => 150, start => #4)

(end => #4, name => fade, post => false, length => 150, start => #f)

no children elements

Dec 06, 2012 6:11:52 PM de.lessvoid.nifty.Nifty loadFromFile

INFO: loadFromFile took [64]

Dec 06, 2012 6:11:52 PM com.jme3.app.Application handleError

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.lang.NullPointerException

at de.lessvoid.nifty.Nifty$ElementMoveAction.perform(Nifty.java:1005)

at de.lessvoid.nifty.Nifty$EndOfFrameElementAction.perform(Nifty.java:1023)

at de.lessvoid.nifty.Nifty.executeEndOfFrameElementActions(Nifty.java:397)

at de.lessvoid.nifty.Nifty.handleDynamicElements(Nifty.java:316)

at de.lessvoid.nifty.Nifty.access$1500(Nifty.java:73)

at de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl.processEvent(Nifty.java:1371)

at de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl.processMouseEvent(Nifty.java:1329)

at com.jme3.niftygui.InputSystemJme.handleMouseEvent(InputSystemJme.java:124)

at com.jme3.niftygui.InputSystemJme.onMouseButtonEventQueued(InputSystemJme.java:196)

at com.jme3.niftygui.InputSystemJme.forwardEvents(InputSystemJme.java:260)

at de.lessvoid.nifty.Nifty.update(Nifty.java:248)

at com.jme3.niftygui.InputSystemJme.endInput(InputSystemJme.java:113)

at com.jme3.input.InputManager.processQueue(InputManager.java:821)

at com.jme3.input.InputManager.update(InputManager.java:885)

at com.jme3.app.Application.update(Application.java:606)

at com.jme3.app.SimpleApplication.update(SimpleApplication.java:230)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)

at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228)

at java.lang.Thread.run(Thread.java:722)

I just moved the:

[java]nifty.addXml("Interface/choice.xml");[/java]



out from addChoice() and ran it much earlier but still have the same error. :frowning:

I guess I’ll just go back to using the java builder methods for adding GUI components on user demand. :frowning:

Nifty can break if its in the process of doing something, that’s where events/end notify can help. But when you call AddXML it will be loaded then and there, so that shouldn’t be an issue. When you call your function put a breakpoint in there and check that the state of nifty is how u expect. Current screen etc. Also do u not need a element.layout() after a move? I’ve not used it before.