NiftyGui Accessing label element

Hey!



I am getting to grips with NiftyGui and quite enjoying using it so far.



I am now trying to get access programatically to a <label name="mylabel"> element I have defined in my xml but I cannot work out how to do it.



I want to append stuff to the label programatically - but I cannot workout how.



Please help!



Andy

I think this is what you're looking for:


Element element = screen.findElementByName("labelId");
element.getRenderer(TextRenderer.class).setText("New Label Text");



All core elements of Nifty (Panel, Text, Image) have a build in Renderer to render themself. The Element class represents any element that exists on the screen and keeps a renderer for the specific Element that needs to be rendered.

So if one day you need to change an image dynamically you would get the ImageRenderer.class from the Element and call the setImage() method there :)

I’m trying to change a text over a “nifty layer” passing the new string from a java class, but I got problems at line:

“textElement.getRenderer(TextRenderer.class).setText(string);”

which results a NPE on the TextRenderer.class.

Where is my error?

Thanks a lot



[java]

public class Main extends SimpleApplication {



public static void main(String[] args) {

Main app = new Main();

app.setShowSettings(false);

app.start();

}



private NiftyJmeDisplay niftyDisplay;

private Nifty nifty;

private Screen screen;

private NiftyController niftyController;



@Override

public void simpleInitApp() {

setupNifty();

}



private void setupNifty() {

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

nifty = niftyDisplay.getNifty();

nifty.fromXmlWithoutStartScreen(“Interface/XML/file.xml”);

guiViewPort.addProcessor(niftyDisplay);

screen = nifty.getScreen(“start”);

niftyController = screen.findControl(“control-id”, NiftyController.class);

}



@Override

public void simpleUpdate(float tpf) {

niftyController.method(“new text”);

}



@Override

public void simpleRender(RenderManager rm) {}



}

[/java]

[java]

public class NiftyController implements Controller {

private Element textElement;



public void bind(Nifty nifty, Screen screen, Element element, Properties prprts, ControllerEventListener cl, Attributes atrbts) {

textElement = element.findElementByName(“text-id”);

}



public void method(String string) {

textElement.getRenderer(TextRenderer.class).setText(string);

}



public void onStartScreen() {}

public void onFocus(boolean bln) {}

public boolean inputEvent(NiftyInputEvent nie) { return false; }



}[/java]

[xml]

<?xml version=“1.0” encoding=“UTF-8”?>

<nifty xmlns=“http://nifty-gui.sourceforge.net/nifty.xsd” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://nifty-gui.sourceforge.net/nifty.xsd http://nifty-gui.sourceforge.net/nifty.xsd”>



<controlDefinition name=“niftyController” controller=“mygame.NiftyController”>

<text id=“text-id” font=“aurulent-sans-17.fnt” text=“old text” textHAlign=“center” textVAlign=“center” width=“100%” height=“100%” x=“0” y=“0” color="#f00f" />

</controlDefinition>



<screen id=“start”>

<layer id=“layer” childLayout=“center”>

<control id=“control-id” name=“niftyController” align=“center” valign=“center” width=“400px” height=“32px” />

</layer>

</screen>

</nifty>

[/xml]

What usually helps in such cases is to find out what object is null. I’m pretty sure that in your case the line:



[java]textElement = element.findElementByName(“text-id”);[/java]



will left textElement being null which later causes the getRenderer() call to be called on the now null “textElement” causing the NPE.



Actually you’ve done everything correctly :slight_smile: What’s missing is probably just the following piece of knowledge:



“When Nifty applies the <controlDefinition…> to the <control…> it is basically replacing the<control…> with the complete content of the <controlDefinition…>. This means that in the final (internal) Tree of elements the <control…> Element will be gone and it will be replaced with the very first element of the <controlDefinition…>.”



Which means in your case that the first child element of your <layer id=“layer”> will be the <text…> Element. In you NiftyController bind() method the “Element” parameter will be the element you’re looking for! It’s not necessary to use findElementByName(“text-id”) on this element because the element is already the element you’re looking for!