Layout height on 5.3RC3

Hello,

We just adopted 5.3RC3 into our project, and I am struggling with layouts.

I am trying to set layouts to use whole visible area, but so far only thing I get is layouts totally disappearing. If I don’t touch height at all, layouts use whole width nicely (part of what I want). But if I try to set anything as height (tried px and %), result is disappearing layouts.

According to release notes, layouts were changed quite a bit - to me it seem like job is half way done.

So, my question is: is this height issue bug with RC3? or is there something magical I need to know about how to deal with height?

there’s no actual bug with the height, the toolkit is just very picky when it comes to specifying some certain heights. A little code would help to figure out the problem. You get some console output of what the problem might be by adding this to your web.xml under <web-app>

 
 &lt;context-param&gt;
	&lt;param-name&gt;Debug&lt;/param-name&gt;
	&lt;param-value&gt;true&lt;/param-value&gt;
  &lt;/context-param&gt;

The issue has been acknowledged and will be fixed asap (probably by friday):
http://dev.itmill.com/ticket/2319

We hope that this is the last major issue (except one disturbing linux -related GWT-issue #2299).

or then I’m just wrong and it is a bug :stuck_out_tongue:

Bug, no bug – that depends on the specification, and that is the issue we have been struggling with for the past 6 months, getting the right specification for the layouts.

But as Jens suggested, adding the web.xml init-parameter should provide hints to what may be “wrong” in your layout.
Note
, thought, that the init-parameter name will change from “Debug” to “productionMode” in the next release candidate, so be ready to change that next time you update Toolkit (see the ticket Joonas mentioned earlier).

I hope you can continue working with 5.3.0, even though the layouts are “a bit” harder to understand currently. There’s a wiki page that explains the new specification at least partly. I encourage everyone upgrading to 5.3.0 to ready it with thought:
Relative Sizes in Toolkit 5

Just to open up the issue a bit more. The question was simply: how to calculate (pixel) height of a 100% tall component that resides inside layout that calculates its height from its children?

We first decided that the answer is 0. Unfortunately this was a wrong decision as it turned out to be fairly easy to create such cases and no-one really wants 0-sized components in their applications. After some re-designed, we decided to redefine this case. The new answer is: the height of the (100% tall) component is calculated from it’s children or if it has no children, set to naturally fit its contents.

In order to set height to be 100% for a component, please assure that the parent has some height set.

For more info, see the #2319

Hi!

You’ve probably had enough of hints to find it out, but if something is not working with relative sizes (“%”) the issue is most likely in missing parent size (or the chain up if having a relative sized parent). Remember that Panels (and Windows as Panel’s sub class) usually have layout that must be sized too. By default VerticalLayout is “100%” width so that’s why everything is working for you horizontally.

You also said that you had some problems with pixel height? Can you provide a test case about this?

cheers,
matti

Hi,

I have used debug parameter on web.xml before posting this issue - fixing layouts debug output suggested and still coming up with disappearing components made me post here.

Below is some sort of demonstration on how to get this issue reproduced…
I did a lot of tests, changing values from 100% to different px values(not just 100px), and was getting disappearing components on both firefox and on IE… Although sometimes IE was able to show something more than firefox.

Sorry, I don’t have any testing log to provide, so please try to play a bit with values at points which are marked with “//switch here …” - also check output on both firefox and on IE.


public class Application extends Application implements ClickListener{
	
    Window main = new Window("Layout test");

	private VerticalLayout mainLayout;
	private CaptionLayout captionLayout;
	private Button button;

	public init() {

	        setMainWindow(main);
		mainLayout = new VerticalLayout();
		mainLayout.setHeight("100%"); //1. switch here (100% => 100px)
		mainLayout.setWidth("100%");
		mainLayout.addStyleName("mainLayout");

		captionLayout = new CaptionLayout("Caption");
		captionLayout.setHeight("100%"); //2. switch here (100% => 100px)
		captionLayout.setWidth("100%");

		mainLayout.addComponent(captionLayout);
		
		button = new Button("Button");
		mainLayout.addComponent(button);
		button.addListener(this);

		main.setLayout(mainLayout);
	}
	
	public void buttonClick(ClickEvent event) {
		if(event.getButton() == button) {
			MyComponent comp = new MyComponent();
			captionLayout.setInfoView(comp);
		}
	}

	public class CaptionLayout extends VerticalLayout {
		
		private VerticalLayout infoArea;

		public CaptionLayout(String title){
			addComponent(new Label(title));
			infoArea = new VerticalLayout();
			infoArea.setHeight("100%"); //3. switch here (100% => 100px)
			infoArea.setWidth("100%");
			addComponent(infoArea);
		}
		
		public void setInfoView(AbstractComponent info){
			infoArea.removeAllComponents();
			infoArea.addComponent(info);
		}
	}
	
	public class MyComponent extends CustomComponent{
		private VerticalLayout layout = new VerticalLayout();
		private Label titleLabel = new Label("Info");
		private Label nameLabel = new Label("Some name");
		public MyComponent(){
			layout.setHeight("100%"); //4. switch here (100% => 100px)
			layout.setWidth("100%");
			layout.addComponent(titleLabel);
			layout.addComponent(nameLabel);
			setCompositionRoot(layout);
		}
	}
}

You get rid of the toolkit debug message by putting in MyComponent() constructor (line 74 for me) setHeight(“100%”). You had 100% height for the layout in the component, but the component itself didn’t have an height. alternatively use comp.setHeight(“100%”) (row 46 for me).

When i switched 1, 2 and 3 into 100px, the button dissapeared. This was because the main layout was 100px, and had two compoents, which of the first one (captionLayout) took 100px of the height. This means that there is no more space left for the button. By making mainLayout bigger, or better yet, removing the height parameter altogether, the button appeared again. The height will be counted from the components when it is not specified.

Everything seems to be working fine now. I hope i didn’t miss something. I checked with both browsers and their debuggers (Firebug and Developer Tools) that the heights are correct. Drop a comment if you want some more testing.

Ok, so my mistake was that I didn’t set dimensions into container which had layout…

Yet, shouldn’t debug output show this container which has undefined dimensions(?)

I need to be able to set components to use all available screen area, also in vertical direction. Its very hard for me to give reasons to our customer why there should be empty space on bottom of screen, and bottom button bar jumping up/down on every different page.

I guess login timed out - it’s my reply above.

I got this when i run your code directly:


IT MILL Toolkit DEBUG
- CaptionLayout/9d5793 (height: RELATIVE, 100.0 %)
  - VerticalLayout/4b2b75 (height: RELATIVE, 100.0 %)
    - MyComponent/1570c24 (height: UNDEFINED)
      - VerticalLayout/1de4376 (height: RELATIVE, 100.0 %)
Invalid layout detected. Relative height component's parent should not have undefined height.
Components may be invisible or not render as expected. Relative sizes were replaced by undefined sizes.

That tipped me that the component itself was the one to blame. Nothing above an relative size (as in %) can be undefined, and MyComponent is set to ‘undifined’.

The “remove the height parameter” -comment was meant for the case where you had 100px in every height, not 100%, and it was only an example. Everything should work correctly in that case when you just put the setHeight(100%). It will split the space 50/50 between captionLayout and button. If you want captionLayout to take as much space as possible of the whole window, add this to the end of your init()


mainLayout.setExpandRatio(captionLayout, 1L);

Hi again,

With full confident that it was all my fault, I went through whole layer/component stack making sure I call setSizeFull() for all parts, just to end up with disappearing components again.

So, I rewrote example application, correcting all short cuts I took earlier (only difference now is that layout template is provided with inpustream, in “real” application layout templates name is given as String parameter).

  1. If you run example application below, you should see “Hello!”.
  2. Commenting in “expand 1” and “expand 2” will give nice error print.
  3. Commenting in “expand 1”, “expand 2” and “expand 3” results with disapperaring “Hello!” - and no error prints.

This is case with firefox and “real” application behaves just like example.
In IE, “Hello!” is shown in case 1 and 3 (but in similarily structured “real” application only small portion of layout, which “Hello!” represents, is shown).


public class MyApplication extends Application {

	public init() {

		try{
			//setTheme("testtheme");
			
			Window main = new Window("Layout test");
			setMainWindow(main);

			byte[] bytes = layoutTemp.getBytes("UTF-8");
			InputStream input = new ByteArrayInputStream(bytes);
			MyAppLayout myAppLayout = new MyAppLayout(input);

			main.setLayout(myAppLayout);

		}catch(Exception e){
			e.printStackTrace();
		}
	}

	public class MyAppLayout extends CustomLayout {
		public MyAppLayout(InputStream layout) throws IOException{
			super(layout);
			//this.setSizeFull(); // expand 1

			MyComponent myComponent = new MyComponent();
			this.addComponent(myComponent, "caption");
		}
	}

	public class MyComponent extends CustomComponent{
		private VerticalLayout layout = new VerticalLayout();

		public MyComponent(){
			//this.setSizeFull(); // expand 2
			//layout.setSizeFull(); // expand 3
			this.setCompositionRoot(layout);

			layout.addComponent(new Label("Hello!"));
		}
	}
	
	public static final String layoutTemp = "<div class=\"border\">" +
												"<div location=\"caption\"></div>"+
											"</div>";
}

Those div’s doesn’t have enough height.

Try with this layout:

public static final String layoutTemp = "<div style=\"height:100%;\">"
			+ "<div style=\"height:100%;\" location=\"caption\"></div>"
			+ "</div>";

No guarantees that it works with all browsers. To use CustomLayout as base for relative-sized components, you might have to make your own javascript height+width calculation for that CustomLayout.

Yes! Now it finally works… Setting values for height in layout template did it.

Thanks for help :slight_smile: