Change size of controls?

Hello,



I have a panel and inside that a scrollpanel. They have the same height. Now I want to make both higher in my Java code. I did this by calling their setHeight/setConstraintHeight methods.



But the panel(s) didn’t change the height visually. They both look like they’re as high as before the calls. Why is that?

Do I need to tell Nifty to rerender them or something? Or isn’t it possible to dynamically change the height of elements/controls?

Did you do element.getParent().layoutElements()?

I found you need to call both setHeight and setConstraint if you want it both to change immediately and stay changed. So long as you do both it’s worked for me though.



In my case there was no other layout going on (absolute positioning, for a bar chart type effect) so I didn’t need to do any relayouting.

I did this now:



[java]

outerPanel.setConstraintHeight(new SizeValue(testValue + “px”));

outerPanel.setHeight(testValue);

scrollPanel.setHeight(new SizeValue(testValue + “px”));

scrollPanel.getElement().setConstraintHeight(new SizeValue(testValue + “px”));

outerPanel.layoutElements();

outerPanel.getParent().layoutElements();

[/java]



But it doesn’t do the trick yet. Anything missing?

This is straight out of the 11-scrollpanel.xml example of the nifty-examples project:



[xml]<layer childLayout=“center”>

<panel id=“outer” childLayout=“horizontal” align=“center” valign=“center” width=“50%” height=“50%” backgroundColor="#55a5" padding=“10”>

<control id=“scrollbarPanelId” name=“scrollPanel” horizontal=“true” height=“100%” width=“100%”>

<!-- first child is the content, the area to scroll around -->

<panel id=“myScrollStuff” width=“1000px” height=“1000px” childLayout=“vertical”>

<effect>

<onActive name=“gradient” direction=“vertical”>

<value offset=“0%” color="#ffff" />

<value offset=“100%” color="#f00f" />

</onActive>

<onActive name=“gradient” direction=“horizontal”>

<value offset=“0%” color="#ffff" />

<value offset=“100%” color="#0f0f" />

</onActive>

</effect>

</panel>

</control>

</layer>[/xml]



And here is a button click handler where I change the outer panels height (which makes the scrollpanel adjust itself as well). The height is changed from “50%” to “80%”:



[java] @NiftyEventSubscriber(id=“bla”)

public void bla(final String id, final ButtonClickedEvent event) {

Element outer = screen.findElementByName(“outer”);

outer.setConstraintHeight(new SizeValue(“80%”));

outer.getParent().layoutElements();

}[/java]



This looks good for me. Changing the constraints and calling layoutElements() of the parent should be enough in the general case. When you change a lot of elements maybe screen.layoutLayers(). The actual height of the element (setHeight()) will be recalculated and changed by Nifty according to the constraints on next layout.



I’ve tried it with the latest Nifty 1.3.2-SNAPSHOT build.



This is therefore a bug in the Nifty version you’re using - also I’m not aware of one in the past that would have caused this o_O - or something strange in your Nifty screen definition or maybe it’s something else :slight_smile:

My panels etc. are:



[xml]

<panel id=“outerPanel” childLayout=“center” height="$height" width="$width" backgroundColor="#00000000">

<control name=“scrollPanel” id=“textScrollpanel” horizontal=“false” vertical="$scroll" height=“100%” width=“100%” backgroundColor="$areaColor">

<panel id=“textpanel” childLayout=“horizontal” backgroundColor="$areaColor" height=“100%” width=“100%”>

[/xml]



They’re inside a control definition. They’re being used inside a layer with center childlayout.

When I change the height constrains of outer panel nothing happens. Everything just stays the same size.

When I have this outside a control definition and change the size of outerPanel, it works.



So the problem is the control definition?

Yes, it seems to be something with the control definition. Outside a control definition everything works as intended.



Can I request a fix? :stuck_out_tongue:

This works for me even when I try it with a controlDefinition. Which makes sense because in the end you end up with the exact same elements in the screen datastructure because the contents of the controlDefinition is really only inserted into the internal element tree with the control tag. So it shouldn’t matter if you would create the elements directly or with the help of a controlDefinition.



Please don’t get me wrong, I DO believe that there is an issue for you :slight_smile: It’s just not as simple as saying the cause is the controlDefinition. There must be something else. What really would help me is when you would reproduce this issue with the jMonkeyPlattform in a simple Nifty testcase and provide everything to compile and run it.



Here is what I’ve done to try to reproduce your issue:



[xml] <controlDefinition name=“stuff”>

<panel id=“outer” childLayout=“horizontal” align=“center” valign=“center” width=“50%” height="$height" backgroundColor="#55a5" padding=“10”>

<control id=“scrollbarPanelId” name=“scrollPanel” horizontal=“true” height=“100%” width=“100%”>

<!-- first child is the content, the area to scroll around -->

<panel id=“myScrollStuff” width=“1000px” height=“1000px” childLayout=“vertical”>

<effect>

<onActive name=“gradient” direction=“vertical”>

<value offset=“0%” color="#ffff" />

<value offset=“100%” color="#f00f" />

</onActive>

<onActive name=“gradient” direction=“horizontal”>

<value offset=“0%” color="#ffff" />

<value offset=“100%” color="#0f0f" />

</onActive>

</effect>

</panel>

</control>

</panel>

</controlDefinition>



<screen id=“start” controller=“de.lessvoid.nifty.examples.defaultcontrolsxml.ScreenController”>

<layer childLayout=“vertical”>

<control name=“stuff” height=“50%”/>

<control name=“button” label=“BLA” id=“bla” />

</layer>

</screen>

[/xml]



Clicking on the BLA button will again change the height of the outer panel from “50%” to “80%” even though it’s now using a controlDefinition.

I want to use this feature in my textarea. Its old code can be found here:



http://hub.jmonkeyengine.org/groups/gui/forum/topic/textarea-with-line-wrapping-code/



I changed the control definition slightly:



[xml]

<controlDefinition name=“textarea” controller=“gui.TextareaControl”>

<panel id=“outerPanel” childLayout=“center” height="$height" width="$width" backgroundColor="#00000000">

<control name=“scrollPanel” id=“textScrollpanel” horizontal=“false” vertical="$scroll" height=“100%” width=“100%” backgroundColor="$areaColor">

<panel id=“textpanel” childLayout=“horizontal” backgroundColor="$areaColor" height=“100%” width=“100%”>

<text id=“areatext” style=“base-font” color="$textColor" width=“94%” />

</panel>

</control>

</panel>

</controlDefinition>

[/xml]



Now it has a “scroll” attribute, with which it is possible to turn on/off the vertical scrollbar. When the vertical scrollbar is turned off and the text height exceeds its display area, it should adapt its height accordingly (like the textarea from Java Swing).



This is trying to be done in this piece of code:



[java]

@Override

public void appendLine(String text) {

String[] wrappedText = this.wrapText(text.split(“n”, -1));

int oldHeight = m_textRenderer.getTextHeight();



for(String line : wrappedText) {

String originalText = m_textRenderer.getOriginalText();



if(!originalText.isEmpty()) {

m_textRenderer.setText(originalText + “n” + line);

} else {

m_textRenderer.setText(line);

}

}



if(m_textPanel.getHeight() < m_textRenderer.getTextHeight()) {

if(m_isScrollable) {

m_textPanel.setConstraintHeight(new SizeValue(m_textRenderer.getTextHeight() + “px”));

m_scrollPanel.getElement().layoutElements();



if(m_autoScroll && (m_scrollPanel.getVerticalPos() == oldHeight - m_originalHeight || oldHeight - m_originalHeight < 0))

m_scrollPanel.setVerticalPos(m_textRenderer.getTextHeight());

} else {

m_outerPanel.setConstraintHeight(new SizeValue(m_textRenderer.getTextHeight() + “px”));

m_outerPanel.getParent().layoutElements();

}

}



m_scrollPanel.getElement().layoutElements();

}

[/java]



The bind method:



[java]

@Override

public void bind(Nifty nifty, Screen screen, Element element, Properties parameter, Attributes controlDefinitionAttributes) {

super.bind(element);

m_textPanel = element.findElementByName(TEXTPANEL_NAME);

m_outerPanel = element.findElementByName(TOPPANEL_NAME);

m_text = element.findElementByName(TEXT_NAME);

m_scrollPanel = element.findNiftyControl(SCROLLPANEL_NAME, ScrollPanel.class);

m_textRenderer = m_text.getRenderer(TextRenderer.class);



m_textRenderer.setXoffsetHack(1);

m_textRenderer.setLineWrapping(true);



m_scrollPanel.setStepSizeY(12);

m_scrollPanel.setPageSizeY(50);



m_autoScroll = true;



m_originalHeight = m_scrollPanel.getHeight();



m_isScrollable = controlDefinitionAttributes.getAsBoolean(“scroll”, true);

}

[/java]



As you can see I am trying to reset the constraint in that second else from top. But it is not working like this. However, when I take the code out of the control definition, it is all fine.

Ok, I’ve downloaded the latest jMonkeyPlattform and created a simple Nifty GUI testcase. It does not contain your whole textarea control but all of the XML snippets you’ve posted above.



I’ve added a simple button that, when being clicked, will resize the outerPanel. This works for me.



Would you please do the following:



a. download this file: topic-change-size-of-controls-basic-game.zip

b. modify it to make the error reproducible (but please don’t copy your whole project into it :slight_smile: just add the parts relevant and keep it as simple as you can)

c. send back the zip



Thank you! :slight_smile:

1 Like

Fixed it. Found the problem through your example.