How to handle nifty at runtime

Is there a way to handle nifty at runtime, e.g. to make gui elements visible and invisible if necessary?

For my problem i want to use nifty for all gui elements and show them context related. The only way i see at the moment is to adding and removing the postprocessor and load the nifty-gui at runtime.

Actually I didn't use nifty in jME3 yet, but what you need is the nifty-object or the

current screen object. e.g. inside the controller you get those. E.g. if you want to

set an element invisible you can access it with


Element a = screen.findElementByName("...")



and make is invisible with:

a.setVisible(false)



let's say you have an label with id=text you can change the text like this:

TextRenderer text = screen.findElementByName("text").getRenderer(TextRenderer.class);
text.setText("Fortuna95");



PS: I wrote the code blind  without testing it, so there might be some typos
pps: have a look at the nifty-examples (from the nifty-svn)
ppps: maybe that question  should be asked in the nifty-forum

Ok, thanks for reply,

i need to switch between scenes and a way to have not only one nifty gui for different scenes.



ps:perhaps i should ask it on nifty forum, i only thought jme is the first real life usage for nifty and that the community is bigger to get answers.

void, the Nifty author, frequently checks the jME forum for updates. He probably won’t mind a simple nudge by PM :slight_smile:

I'M WATCHING YOU ALL! muhahaha



I - again - don't understand the question of Lutherion! Sorry, must be my fault :stuck_out_tongue:



You can hide Nifty elements like ttrocha explained. But I'm not sure if this is what you want/need:


For my problem i want to use nifty for all gui elements and show them context related.


Can you explain this problem a bit more? I don't get it!  :(

Sure.

The thing is,

i have one scene with a gui. I add it as a processor with loading the nifty from xml.

On runtime i switch to another scene which has another gui. So my question in this case is: What is the best suggested behavior?

Do i have to load all gui's for all my scenes and make them visible and invisible when it's needed or can i change the nifty in another way.


NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,
            inputManager, audioRenderer, guiViewPort);
guiViewPort.addProcessor(niftyDisplay);
Nifty nifty = niftyDisplay.getNifty();
nifty.fromXml("uihud.xml", "start");



to something like nifty.destroyOldLoadedGui();
nifty.fromXml("contextRelated.xml","start");

To load the nifty at runtime for different scenes without having memory and performance waste.

Well, I think I understand the problem now.



I'm not an expert of JME3 or the JME3-Nifty integration. I think momoko_fan would be the expert to answer this :smiley:



From what I understand, the NiftyJmeDisplay creates the Nifty instance in its constructor. So when you have a NiftyJmeDisplay instance you'll have a Nifty. I don't know if you can share a single NiftyJmeDisplay instance with different viewports as you've suggested in your first post tho. But if this is possible: remove and add the processor to the guiViewport when you switch your scenes there shouldn't be a problem right? You can simply call nifty.fromXml() when you switch the scenes to prepare the (internal) Nifty instance with the new nifty.xml for your second GUI. You won't need two NiftyJmeDisplay instances then, don't you?



There is even a cleanup() method on the NiftyJmeDisplay which calls nifty.exit(). This Nifty method does not yet cleanup all resources that Nifty allocated but it will be the perfect place to do that kind of cleanup in a later version of Nifty.



Does that help?  ://

Yes, i think this is the way i (also) thought of.



So on scene switch i have to call :



niftyDisplay.cleanUp();

niftDisplay.getNifty().loadFromXml("newGui");





Is that right?

You could call it like this but when you're using the same NiftyJmeDisplay (and therefore the same Nifty) instance there is no need to call cleanUp() at all I suppose? loadFromXml() will end and dispose the last loaded Nifty GUI and simply loads a new one.



That's the same mechanism you would use when you have only a single Nifty instance. There is no need to call cleanUp() then.

I have a problem with loading nifty multithreaded.



I always get concurrent modification exception if i try to load nifty in an extern thread. I also tried to remove the sceneprocessor from viewport befor

Yes, thanks.

I will search that queue cause it seems to be a general problem not only nifty related to attach/detach things out of external threads.

Yes,… have a look at this: http://www.jmonkeyengine.com/wiki/doku.php#concurrency_threading



Even it is jme2-related it is more or less the same problem.

Is there a way to include a snippet of nifty to have a layer or a component which exists in all screens, like the main menu of a game. I want not to load a different screen and have the current screen get disappeared. I want to show an element by setting the visible state. And that element must be in all my screens.

Good question,



I had the same problem and I solved it by using one screen with 5 or 6 layers that I activate as I

need them. The HUD-layer is visibile all the time. I don't think that is the optimal way.



Now I would create a ControlDefintion that includes a layer (if that is possible) or at least the panel with the hud having its own controll-class. That could be added to every screen where the HUD is need. I'm not sure if that is really working, and I don't have an example for that :smiley:

I tried defining my own control to include that everywhere i need, but it didn't work for me.

I think defining all hud layers in one file for all scenes and having all elements in RAM all the time is not a good solution for me, but it would work for now, that's right.

yes, you can use a <controlDefinition> to define a xml snippet and later use <control> to use it. I know its a bit odd that you would call that "control" tho.



the tutorial/demo you find in the nifty-examples project is a perfect example for this. each "screen" is defined as a <controlDefinition> and at runtime each one is replaced from java.



I'd suggest looking at the code of the tutorial to see how this works. It's really not that hard.

Yes, that Back Button issue is because your layer is set to childLayout="center". The center layout only supports exactly one child element. Two or more child elements are not supported.



To fix this issue in your xml example you need to add another panel right below the layer that acts as the parent for all of the other elements you have. That way this panel will be centered according to the layer and everything else below it will parent correctly.



The tutorial/demo says this: "The "center" Layout currently only supports one child element. It takes this first and only child element and centeres it in its area."



I agree that an error message or an xml validation error is needed in that case.



Besides that I'm not sure how your latest response relates to your initial request about including snippets in mutiple xml screens:


Is there a way to include a snippet of nifty to have a layer or a component which exists in all screens, like the main menu of a game. I want not to load a different screen and have the current screen get disappeared. I want to show an element by setting the visible state. And that element must be in all my screens.



And that problem really is solvable by using a <controlDefinition> on your own and looking at the nifty-examples project, especially the tutorial/tutorial.xml file will help in that case.

Ok thanks, it's really hard to get all info's in little time.

Lutherion said:

Ok thanks, it's really hard to get all info's in little time.

So make some tutorials of what you've learned for the next guy in your situation when you have time ;) Some copy&paste of these posts will do as a start.

Yes, i can do it. I'll make it in pdf an post it on contribution thread.