Problem with trying to set Label text during runtime in nifty. [SOLVED]

Hello guys,



This is my first time trying out nifty and I’m very new to java in general so sorry for any confusion.

What I’m trying to do is to change the text of 2 label controls during runtime to represent a score and life value.

I have added the controls in the XML code I use and have ID on them which I call during runtime.



The code I’m using to change the label text is like this:



public void UpdateCurrentStats() {

Element lifeLabel = nifty.getCurrentScreen().findElementByName(“lifeLabel”);

Element scoreLabel = nifty.getCurrentScreen().findElementByName(“scoreLabel”);



lifeLabel.getRenderer(TextRenderer.class).setText("Remaining life: " + board.getPlayerBase().getHealth());

scoreLabel.getNiftyControl(Label.class).setText("Score: " + player.getCurrentScore());

}



You probably notice that I’m doing it different for the two labels that’s because I’ve been trying to solve my problems and tried both methods with no success.

At runtime no text is displayed at all. If I set a predefined text in the XML-code the text wont change during runtime.

If you are able to find out what I’m doing wrong I would be so thankful.



Best Regards.

Do you call this in the LWJGL thread?

Perhaps try a lifeLabel.getParent().layoutElements()?

Yes, I think I’m doing in the LWJGL thread. The method is called during gameUpdate and I’ve debugged to see that it does indeed call the method.

I have tried using the layoutElements() of the parent and parents but with no luck.

If the label is empty, does it have a size (width/height)?

Could you show your xml?

I have tried setting some different values inside the XML to see if that was an issue, but as I originally wrote, if I set a predefined text and use the method nothing happens and the same text is always shown.

The XML for the layer which includes the labels is like this:



I’m now using width and height 100% to max out the labels inside the panels so that shouldn’t be a problem.

I have also tried with fixed pixels but still the same. The panels are shown(because I can see their backgrounds) and if I give the labels a predifned text it will show aswell.

As you can see now the labels have text="" but I’ve tried without predifing any text at all also but still same thing.



Thank you very much for your patience.

[xml] <layer id="bottomUI" childLayout="horizontal">

<panel height="10%" width="50%" align="left" valign="bottom"

backgroundColor="#444444" childLayout="horizontal" visibleToMouse="true">

<control id="lifeLabel" type="label" name="lifeLabel" width="100%" height="100%" text=""/>

</panel>

<panel height="10%" width="50%" align="right" valign="bottom"

backgroundColor="#444444" childLayout="horizontal" visibleToMouse="true">

<control id="scoreLabel" type="label" name="scoreLabel" width="100%" height="100%" text=""/>

</panel>

</layer>[/xml]

Ah, I see the probable cause now in your xml.

I believe “type” used to be the attribute to specify the control type/name, but that it was deprecated.

You should use name=“label” instead of type=“label” to specify a label control, then it should work.

The id is the one you need for getting elements at run time, so that one is correct in your xml.

Ah I see.

So I did as you told and removed each of the type attributes but the problem still remains.

After removing type I also predefined a text to see if it would show and indeed it did, but still I am not able to change it during runtime.



I really appreciate the help so far.

Use a text element not a control and the first mechanism should then work. Take a look at the nifty manual (nifty bible link to the right) as that has more info on text elements.

Did you change name=“lifeLabel” to name=“label”?

Otherwise it’s not a label and element.getNiftyControl(Label.class) won’t find it.

Zarch:

I have tried that aswell, doing it like this:

[xml]<text id=“lifeLabel” text=“test” font=“verdana-24-shadow.fnt” width=“100” height=“100%” />[/xml]

It runs without any issues but the text wont be rendered and if I predefine a text in the XML the same thing happens like when using a label. The predefined text will just remain the same without changing.



Tumaini:

Yes, I did change the name to this:

[xml]<control id=“scoreLabel” name=“label” width=“40px” height=“40px”/>[/xml]

But the problem remains the same.



I don’t know but since I’ve tried alot of different solution with no results that I’m getting a bad reference or something.

But when I debug and break inside the method there is a valid element reference for both lifeLabel and scoreLabel, but somehow the changes wont go through :confused:

I have now also tried changing which element is focused but the same problem arises. So maybe it’s not specifically a label/text problem but something else.

When I call a certain method I want to change focus to another element using the following javacode:

[java]nifty.getCurrentScreen().findElementByName(“startWaveButton”).setFocus();[/java]

But at runtime and when I call this code nothing happens and the focus stays on the last element.

Ok, lets go back to your xml.

Could you show your whole screen and also the Java code where you instantiate your screen controller and switch to the screen in question?

Ok I found what the problem was.



I changed the call from the above to

[java]this.getNifty().getCurrentScreen().findElementByName(“startWaveButton”).setFocus();[/java]

(Changing nifty. to this.getNifty().)

When I used this to call the method the focus changed without problems. So I did the same with the labels/text and then it started working with both the text and label.



So somehow my nifty variable has a reference to an obsolete nifty instance?

I don’t really understand why this is.

This is my initGameAndGUI()

[java] input = new PlainSlickInputSystem();

nifty = new Nifty(new SlickRenderDevice(container), new SlickSoundDevice(), input, new LWJGLTimeProvider());

prepareNifty(nifty, state);

initNifty(container, state);[/java]

If someone knows how I’m getting a bad reference please do tell why. Cuz I really wanna know why I’m having this problem so I don’t run into it later on :slight_smile:

Is your nifty variable an instance variable?

Perhaps it’s being overshadowed by another local variable or something happens in your prepareNifty method that creates the problem.

Did you compare the instances to see if they are the same or separate?

As you seem to be using Slick, perhaps you should ask on their forum to see if it’s related to Slick?

I did like this

[java]nifty = new Nifty(new SlickRenderDevice(container), new SlickSoundDevice(), input, new LWJGLTimeProvider());

prepareNifty(nifty, state);

initNifty(container, state);

nifty = this.getNifty();[/java]

and when I now overwrite the nifty variable with this.getNifty() after prepareNifty and initNifty() the methods still work.

So somehow the variable is overshadowed or something like that just as you said.

The only thing i do in prepareNifty though is loading the XML like this

[java]nifty.fromXml(getResourcePath("/XMLFile1.xml"), “start”, this);[/java]



and I don’t really know how the initNifty works.



Btw Tumaini, I thank you fullheartedly for all the help you’ve given and for sticking with me.

Perhaps you could supply your full code for that class?

Do you have [java]private Nifty nifty;[/java] up top?

What does the getNifty() method look like?

Where is the initNifty method located? You don’t have the source code for it? As it doesn’t get the nifty instance as argument and going by its name, it might be that it could be part of the problem.

Btw Tumaini, I thank you fullheartedly for all the help you’ve given and for sticking with me.

No problem, I'm happy to help if I can.

I have this mechanism working but i use a text element, however i don’t retrieve a control but a textRenderer



[xml]

<text id=“achievmentTitle” text=“bla”>

[/xml]



[java]

nifty.getCurrentScreen().findElementByName(“achievmentTitle”).getRenderer(TextRenderer.class).setText(“bla bla”);

[/java]

Tumaini:

The problem was me being stupid and misunderstanding the nifty/slick implementation.

Just as you said, the initNifty() method initializes the nifty which is then used for rendering and so on.

There was never a need for me to create a new instance of Nifty myself since initNifty took care of it for me.

Therefore my own nifty instance was basically a copy of the one being used and hence the changes I did to it never showed.

So what I have now done is simply this:

[java] initNifty(container, state);

nifty = this.getNifty();

prepareNifty(nifty, state);[/java]



So I’m not creating an instance myself and just let initNifty take care of it then I get the reference and store it for further use later on.

This way everything works correctly and I don’t have an extra nifty instance just lying around :slight_smile:



So this is now 100% solved.

Thank you all for helping out, especially you Tumaini, for sticking with me through all my stupidity :stuck_out_tongue: