[nifty] element.setVisible(false) not working

Hi,



I’m trying to hide the “Back to game” button in a menu if the game has not yet started. Here’s how:



[java]

void showMenu(boolean hasStarted)

{

if (hasStarted)

{

this.screen.findElementByName(“backButton”).setVisible(true);

}

else

{

this.screen.findElementByName(“backButton”).setVisible(false);

}



this.screen.findElementByName(“menuPanel”).layoutElements();

this.screen.findElementByName(“menuLayer”).setVisible(true);

}

[/java]



Here’s the menu layer:

[xml]

<layer id=“menuLayer” backgroundColor="#0007" childLayout=“center” visible=“false”>

<panel id=“menuPanel” width=“150” backgroundColor="#000C"

align=“center” valign=“center” childLayout=“vertical”>

<control id=“startNewGameButton” type=“button” label=“Start new game”

visibleToMouse=“true” width="">

<interact onClick=“onStartNewGameButton()”/>

</control>

<control id=“displaySettingsButton” type=“button” label=“Display settings”

visibleToMouse=“true” width="
">

<interact onClick=“onDisplaySettingsButton()”/>

</control>

<control id=“backButton” type=“button” label=“Back to game”

visibleToMouse=“true” width="">

<interact onClick=“onBackButton()”/>

</control>

<control id=“quitButton” type=“button” label=“Quit”

visibleToMouse=“true” width="
">

<interact onClick=“onQuitButton()”/>

</control>

</panel>

</layer>

[/xml]



It looks like this although the “Back to game” button should be invisible:





I also had the case that the button was invisible but took it’s space in the menuPanel (re-layouting didn’t work). What am I doing wrong?



Edit: If I remove the button like this …

[java]

void showMenu(boolean hasStarted)

{

if (hasStarted)

{

if (this.backButton != null)

{

this.screen.findElementByName(“menuPanel”).getElements().add(2, this.backButton);

this.backButton = null;

}

}

else

{

if (this.backButton == null)

{

this.backButton = this.screen.findElementByName(“backButton”);

this.screen.findElementByName(“menuPanel”).getElements().remove(backButton);

}

}



this.screen.resetLayout();

this.screen.layoutLayers();

this.screen.findElementByName(“menuPanel”).layoutElements();

this.screen.findElementByName(“menuLayer”).setVisible(true);

}

[/java]

…it looks like this:





I’m desperately trying to make Nifty re-layout the menuPanel, but no success so far. I’m probably not using Nifty as intended.

Are you sure the showMenu() method is reaching the line 9? Have you tried the hide() method yet?

Thanks for replying. Yes, I’ve set a breakpoint to check it.







I also made sure the other branch isn’t called afterwards by setting a breakpoint there, too. I also searched the entire project for other lines where I might access “backButton”, but found none.

try so:



[java]

screen.findControlByName(“backButton”, ButtonControl.class).getElement().hide();

[/java]



Make sure the “screen.findControlByName(“backButton”, ButtonControl.class)” isn’t returning null.

There’s no method “screen.findControlByName()”. And the other similar methods don’t return an object that has a method “hide()” or “setVisible()”. I suppose there’s some redesign going on under the hood of Nifty. Or Nifty just hates me. :frowning:

[java]

this.screen.findControl(“backButton”, ButtonControl.class); // deprecated

this.screen.findNiftyControl(“backButton”, Button.class); // new way it seems

[/java]

I forget the name, but it doesn’t matter, just do what I said, by using the getElement() from the given control then hide that.

No effect, sorry. Btw, disabling and enabling works as expected.

[java]

void showMenu(boolean hasStarted)

{

if (hasStarted)

{

//this.screen.findElementByName("backButton").setVisible(true);

this.screen.findElementByName("backButton").enable();

//this.screen.findNiftyControl("backButton", Button.class).getElement().show();

}

else

{

//this.screen.findElementByName("backButton").setVisible(false);

this.screen.findElementByName("backButton").disable();

//this.screen.findNiftyControl("backButton", Button.class).getElement().hide();

}



this.screen.findElementByName("menuLayer").setVisible(true);

this.screen.resetLayout();

this.screen.layoutLayers();

}

[/java]

btw it’s very weird, I have no problem with hiding my elements… Good luck!

Did you try to hide controls? I’ll probably shrink wrap this button with a panel and hide that. Thanks a lot though for trying to help me.

No. Controls aren’t hided, but them elements are rather via control.getElement().hide().

Hmmm. Just looked at the source code of my game, and I’m hiding my controls so:



[java]

moveBar.setHide(“true”);

moveBar.getElement().layoutElements();

[/java]



Where moveBar is a custom control of mine.

There’s no “setHide()” method in my Nifty. You might be using a different version. I’m using the version that comes with the beta of jME3. Btw, the shrink warp panel trick doesn’t work. I might simply disable the button until I find out how to hide it. I’m not keen on plugging in the source version of nifty to see what’s going on, but I fear there’s no other way. Aaaaaaaahhhh!!!111einselflegolas :slight_smile:

Sorry, the setHide() is a custom method of my control xD. By the way internally, I’m doing so:



[java]

public void setHide(String hide) {

this.hide = hide;

if (Boolean.valueOf(hide)) {

getElement().hideWithoutEffect();

} else {

getElement().showWithoutEffects();

}

}

[/java]

you have to layout elements after that of course :

[java]

myButton.getElement().hideWithoutEffect();

myButton.getElement().layoutElements();

[/java]



EDIT: Or it’s not needed xD.

Ok, I found out something. Calling “setVisible(true)” (or “show()”) on a parent element seems to cause all children to be set visible, too. If I first make the parent visible and then hide the button, it works … kind of.



[java]

void showMenu(boolean hasStarted)

{

this.screen.findElementByName(“menuLayer”).setVisible(true); // <- better



if (hasStarted)

{

this.screen.findElementByName(“backButton”).setVisible(true);

}

else

{

this.screen.findElementByName(“backButton”).setVisible(false);

}



// this.screen.findElementByName(“menuLayer”).setVisible(true); // <- bad

this.screen.resetLayout();

this.screen.layoutLayers();

}

[/java]



Now it looks like this:





Why the x isn’t Nifty re-layouting that censored panel?

Yeah, the parent visibility affects its children.


Why the x isn’t Nifty re-layouting that *censored* panel?


Because you didn't hide the menuPanel :roll:? I think you forgot to remove the mainMenu panel's background color, maybe you was debugging something.

In every GUI framework that I know, “parent.setVisible(false)” also hides it’s children, yes, but they don’t alter the visible attribute of all children. It makes no sense to do that.



The problem with the last screenshot is the gap where the hidden button is. I’d expect Nifty to close that gap and reduce the height of the menuPanel if I ask it to re-layout the entire screen (or every single element, which makes no difference).

Hmmm. OK! The problem is that the button still is there. it is hidden, but it is there. Use the markForRemoval() method instead.

That removes the button. Same effect as here (at “Edit:”). The gap is closed but the menuPanel is not packed.

You can do magics, but that gap won’t be closed automatically. You have to do it dinamically, unfortunately.