How can the full browser height be used (without using a hard coded height)

Hi,

I am trying to avoid having to set a hard coded value for the vertical height of the top level window (I set it to 750 in the example below). If I set it to undefined, the scrollbar for the Tree panel appears on the top level window (instead of the Tree Panel) as a vertical scrollbar, and the entire application scrolls (instead of just the Tree Panel), which leaves the right hand panel behind as I scroll down.

I used the method described at the bottom of this page:

http://dev.itmill.com/wiki/DevDocs/RFC/RelativeSizes

for the Tree panel, to get it to automatically put scroll bars on the panel if the Tree did not fit in the space it was given. What I really want, is to be able to get the Tree to use as much of the available space in the browser, and only put on scrollbars when it is too big to fit, ie. auto add an horizontal scrollbar when the tree is expanded beyond 20% of the available browser width and auto add a vertical Tree Panel scrollbar when the tree is expanded beyond 100% of the available browser height.

Is there some way I can use all of the available browser vertical space, without having to explicitly call this:


window.setHeight(750, Panel.UNITS_PIXELS);

For example, something like


// If it was supported:
window.setHeight("100%", Panel.BROWSER_ACTUAL_INTERNAL_WINDOW_HEIGHT);

It seems that the Horizontal/ Width case works ok in my sample code (without having to call window.setWidth(some_hardcoded_number, Panel.UNITS_PIXELS), so I thought it must be somehow possible for the Vertical/Height case too.


package testing.layout;

import com.itmill.toolkit.Application;
import com.itmill.toolkit.ui.AbstractSelect;
import com.itmill.toolkit.ui.Component;
import com.itmill.toolkit.ui.Panel;
import com.itmill.toolkit.ui.SplitPanel;
import com.itmill.toolkit.ui.TextField;
import com.itmill.toolkit.ui.Tree;
import com.itmill.toolkit.ui.VerticalLayout;
import com.itmill.toolkit.ui.Window;

public class TestLayoutApplication extends Application
{
	private static final String NODE_CAPTION = "SomeLongCaptionName";

	private static final float MAX_HEIGHT_PIXELS = 750;

	private Window rootWindow = new Window("Main Test Window");

	public final void init()
	{
		setMainWindow(rootWindow);
		initializeComponents();
	}

	private void initializeComponents()
	{
		rootWindow.removeAllComponents();
		rootWindow.setHeight(MAX_HEIGHT_PIXELS, Panel.UNITS_PIXELS);
		rootWindow.getLayout().setHeight(MAX_HEIGHT_PIXELS, Panel.UNITS_PIXELS);

		rootWindow.setStyleName(Panel.STYLE_LIGHT);

		SplitPanel splitPanel = new SplitPanel(
				SplitPanel.ORIENTATION_HORIZONTAL);

		splitPanel.setFirstComponent(addLeftPanel());
		splitPanel.setSecondComponent(addRightPanel());
		// Left pane uses 20%
		splitPanel.setSplitPosition(20);
		rootWindow.addComponent(splitPanel);
		splitPanel.setSizeFull();
	}

	private Component addLeftPanel()
	{
		// Tree with a few items
		Tree tree = new Tree();
		tree.setDebugId("mytree");
		tree.setImmediate(true);
		tree.setItemCaptionMode(AbstractSelect.ITEM_CAPTION_MODE_EXPLICIT);

		addCaptionedItem(tree, "root", null, 0);
		tree.addItem();
		for (int i = 1; i &lt 7; i++)
		{
			addCaptionedItem(tree, NODE_CAPTION + "-1-" + i, 0, i);
			for (int j = i * 10; j &lt i * 10 + 3; j++)
			{
				addCaptionedItem(tree, NODE_CAPTION + "-2-" + j, i, j);
				for (int k = j * 10; k &lt j * 10 + 3; k++)
				{
					addCaptionedItem(tree, NODE_CAPTION + "-3-" + k, j, k);
					for (int m = k * 10; m &lt k * 10 + 3; m++)
					{
						addCaptionedItem(tree, NODE_CAPTION + "-4-" + m, k, m);
					}
				}
			}
		}
		tree.expandItemsRecursively(0);

		Panel treePanel = makePanel();
		VerticalLayout layout = new VerticalLayout();
		treePanel.setSizeFull();
		treePanel.getLayout().setSizeUndefined();
		treePanel.setStyleName(Panel.STYLE_LIGHT);
		treePanel.addComponent(tree);
		layout.addComponent(treePanel);
		layout.setExpandRatio(treePanel, 1);

		return treePanel;
	}

	private void addCaptionedItem(Tree tree, String caption, Integer parentKey,
			Integer key)
	{
		tree.addItem(key);
		tree.setChildrenAllowed(key, true);
		tree.setItemCaption(key, caption);
		if (null != parentKey)
		{
			tree.setParent(key, parentKey);
		}
	}

	private Component addRightPanel()
	{
		Panel panel1 = makePanel();

		TextField tf = new TextField("Write some text ...");
		tf.setDebugId("AreaTextField");
		tf.setColumns(15);
		tf.setRows(5);
		tf.setImmediate(true);
		panel1.addComponent(tf);

		return panel1;
	}

	private Panel makePanel()
	{
		Panel panel = new Panel();
		panel.setStyleName(Panel.STYLE_LIGHT);
		return panel;
	}
}

Hi!

Didn’t check it properly but at first sight it seems that your layout don’t have 100% height defined.

All Panel’s (including Windows) in Toolkit have a layout inside them, where all components actually end up. You have most likely not set the height of the layout like this


window.getLayout().setHeight("100%");

When one encounters layout problems it usually helps to run layout checks:

  1. enable client debug console on browser by adding ?debug parameter to url
  2. click analyze layouts
  3. Checks for warnings printed to client debug console

I hope this helps, please let me know if it didn’t.

cheers,
matti

Matti,

That worked !!!

I changed:


		rootWindow.setHeight(MAX_HEIGHT_PIXELS, Panel.UNITS_PIXELS);
		rootWindow.getLayout().setHeight(MAX_HEIGHT_PIXELS, Panel.UNITS_PIXELS);

to:


		rootWindow.getLayout().setHeight("100%");

What I don’t understand, is that at the bottom of:

http://forum.itmill.com/posts/list/523.page

Marc was saying:

“Usually, when a “setSizeFull” component mysteriously disappears, it’s because its parent does not have an appropriate size; the component is then 100% of something undefined, which is often 0px. Basically, if you put a 100% component inside a layout, but you don’t specify the size of the layout, 100% means 0px if nothing else is forcing the layout to be bigger.”

And I thought that meant I had to set an absolute value for the height via a call like rootWindow.setHeight(750, Panel.UNITS_PIXELS).

Earlier on, when I had been testing with the ?debug option and using “Analyze Layout”, I was getting 1 error, which was usually complaining that I had not set the height.

Can you explain what is the difference is between setting:
rootWindow.getLayout().setHeight(“100%”);
and
rootWindow.setHeight(“100%”);

Many Thanks
Andrew

You don’t have to set an absolute size: 100% is not undefined.
This seems to be confusing a lot of people actually - relative sizes are ‘defined’, only ‘null’ or an unset size is undefined.
Also, many components have a preset size, which is usually convenient, but sometimes confusing (e.g the layout in a Window is 100% wide by default, if I remember correctly).

The first one sets the height for the layout inside the Window, the second one sets the height for the actual Window. Sometimes (often?) you want to set both, sometimes setting one is enough. It’s actually exactly like having one layout inside another.

Window (and Panel, Window extends Panel) are a bit odd because they automatically (and always) contain a layout - they are like single-component containers. That means that both the Window and it’s layout has a size, and that size can be different. It’s just like having a layout inside another.

The reason for this is that you can change the layout inside the Window - it does not have to be a vertical layout - and if we were to automatically change the size of both when changing the size of the Window, that would be confusing too.
One ‘fix’ would be to not automatically add the default VerticalLayout to the Window, so that one would have to add a Layout to Window explicitly: more code, but not so confusing, perhaps.

Hopefully this did not confuse more than it helped… :wink:

Best Regards,
Marc

Marc,

Yes, that makes sense. Thanks for explaining. Layouts seem to be working fine now. The key to keeping things simple, seems to be to use Layouts, and keep the usage of Panels as a layout mechanism, to an absolute minimum.

Thanks
Andrew