Nifty - renderOrder problem

Hi all,
I’ve implemented a custom tab window, but somehow the renderOrder seems to be not working as intended. :frowning:

I have four different tabs. All of them initialize with the renderOrder 0 (also tested with other values). Which means they will behave normally for the nifty renderer. An example: The first two times I hit every button everything is working normally. But the third time always fails with the second tab (in this example! If I change the order of clicking the buttons, it also change the button which will not render).

Output example:

New tab window: Tab2
Old renderOrder:
10000
0
0
0
New renderOrder:
0
10000
0
0
screen.findElementByName(windowMainElement).layoutElements() have been executed!

According to the output I should see the content of tab 2, but I still see tab 1. I can only switch the viewable content of the window if I hit tab 3 or 4. If I continue hitting the tabs, this problem also appears on the other buttons randomly.

Does anyone has any clue which could case my problem?

I found one possible clue: If I switch between the tabs slowly, the bug seems to be not appearing. I am not 100% sure, but could it be that the jme renderer cannot follow this “fast” changing action of the gui?

Effectively, nifty does its own rendering so it has nothing to do with “jme renderer cannot follow this ‘fast’ changing action”. All nifty rendering is done within the nifty renderer.

Ok, this means nifty’s renderer seems to have a problem in this case, or?

I couldn’t tell you… I haven’t looked at nifty in like 3 years.

Edit: hopefully someone with nifty experience can step up.

Without seeing more code it is hard to tell. I’ve never used render order for this specific use case. My guess is that you may not be calling layoutElements on the correct element or your code for triggering the change is hitting a race condition somehow with the layout elements call. I assume the parent container has an absolute layout?

That being said, it’s probably better to just hide / show the correct element depending on which is active unless you have a specific reason to layer the tabs like that. I imagine you could get into some weird situations where one of the tabs that isn’t active is still getting input accidentally or something.

I pretty sure that I use the correct element. The parent container uses the layout “overlay” and my code itself should be fine. I also only get problems if I switch fast between the tabs, which could prove that the problem is inside nifty. What do you mean with “race condition”? Well I do have a reason to use tabs, especially I don’t want to unhide/hide tons of elements every time I am hitting on a tab.

Sure I could show you some code, but I wouldn’t think that will help. The process every time I hit a tab is: the button tab leads to execute a specific method. This method, like “openTab2”, includes the new renderOrder values of all tabs + layoutElements at the end. As I said, there shouldn’t be a problem regarding the code.

Edit: If I hit the buttons from up to down in a straight order, I get no errors (doesn’t matter how fast or how many times I go from up to down). But if I change the order, I get the problem I mentioned.

Update: Finally found one possible solution. Somehow the renderOrder only supports two elements. Which means if you want to use more than two tabs, you have to create another kind of structure to handle this.

My structur:

  • mainOverlay-panel
  • overlay-panel1
  • tab-panel a
  • tab-panel b
  • overlay-panel2
  • tab-panel c
  • tab-panel d

Thats a pretty complex solution to the problem instead of hiding / showing a tab. Hiding and showing tabs is pretty cheap performance wise. I use it for my own tab panel implementation.

What I mean by a race condition is that when you manipulate nifty elements it usually doesn’t immediately process. For example, when you switch screens it doesn’t immediately switch screens until after nifty processes the next frame. So depending on your code you may have a race condition which prevents it from working correctly if you switch quickly. So showing your code would matter.

In case of hiding/showing, wouldn’t that mean you have to hide all tabs first and then show the active tab (every time you open the tab window)? Which would mean it can happen you have to hide 500+ elements while opening the window, which could cause performance problem, or am I wrong?

Thanks for your explanation. The problem is that there’s no problem at all if I switch fast between the tabs in the same order (like (1 2 3 4) ← circular permutation). And that problem has probably something to do with the renderer of nifty itself which I cannot control or check. I could show you my code, but that would means tons of explanation from my side to make the code understandable.

I have a similar number of elements and don’t see any performance problems with hiding or showing. When you hide an element it doesn’t travel to all the children and “hide” them. Its kinda like pruning a branch of a tree where you cut it at the root and the entire branch is gone.

Thanks, I’ve tried to implement your solution but got a new problem. The 4. tab is visible instead of the 1., but according to nifty the 4. tab is not visible… and the 1. tab should be visible according to nifty… oO It’s frustrating to work with nifty on that level… I have no problems with nifty until now (and I am working with this gui system since a half year)

Method which will execute while opening tab window:

if(event.equalsIgnoreCase("open")){
        screen.findElementByName(windowName + "-Content17").hide();
        screen.findElementByName(windowName + "-Content18").hide();
        screen.findElementByName(windowName + "-Content19").hide();
        screen.findElementByName(windowName + "-Content20").hide();
        
        if(activeSubWindow.equals(SubWindow.Tab1)){
            screen.findElementByName(windowName + "-Content17").show();
        }
        else if(activeSubWindow.equals(SubWindow.Tab2)){
            screen.findElementByName(windowName + "-Content18").show();
        }
        else if(activeSubWindow.equals(SubWindow.Tab3)){
            screen.findElementByName(windowName + "-Content19").show();
        }
        else if(activeSubWindow.equals(SubWindow.Tab4)){
            screen.findElementByName(windowName + "-Content20").show();
        }
    }