Issue with Horizontal Split Panel height

Hey there!

I am having an issue with the height of Horizontal Split panel. Please take a look at the following Test Application - http://test-vaadin.appspot.com/ The switch button toggles between a label and a HorizontalSplitPanel containing a table and a label in it. When the HorizontalSplitPanel is shown again its height is not set properly and only the first row of the table is visible.

There are two classes in the project which are pasted below:

package com.example.testgae;

import com.vaadin.Application;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class TestgaeApplication extends Application {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	public void init() {
		Window mainWindow = new Window("Testgae Application");
		VerticalLayout verticalLayout = new VerticalLayout();
		verticalLayout.setHeight(100, Sizeable.UNITS_PERCENTAGE);
		verticalLayout.setWidth(100, Sizeable.UNITS_PERCENTAGE);
		
		Button switchButton = new Button("Switch");
		verticalLayout.addComponent(switchButton);
		
		final Label label1 = new Label("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.");
		
		final HorizontalSplitPanel horizontalSplitPanel = new HorizontalSplitPanel();
		horizontalSplitPanel.setWidth(100, Sizeable.UNITS_PERCENTAGE);
		horizontalSplitPanel.setSplitPosition(30, Sizeable.UNITS_PERCENTAGE);
		
		BeanItemContainer<DataBean> beanItemContainer = new BeanItemContainer<DataBean>(DataBean.class);
		beanItemContainer.addBean(new DataBean("Data 1"));
		beanItemContainer.addBean(new DataBean("Data 2"));
		beanItemContainer.addBean(new DataBean("Data 3"));
		beanItemContainer.addBean(new DataBean("Data 4"));
		beanItemContainer.addBean(new DataBean("Data 5"));
		
		final Table table = new Table();
		table.setContainerDataSource(beanItemContainer);
		table.setHeight(100, Sizeable.UNITS_PERCENTAGE);
		table.setWidth(100, Sizeable.UNITS_PERCENTAGE);
		table.setPageLength(beanItemContainer.size());
		
		final Label label3 = new Label("There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.");
		
		horizontalSplitPanel.addComponent(table);
		horizontalSplitPanel.addComponent(label3);
		
		verticalLayout.addComponent(label1);
		verticalLayout.addComponent(horizontalSplitPanel);
		horizontalSplitPanel.setVisible(false);
		
		switchButton.addListener(new ClickListener() {
			
			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				if (label1.isVisible()) {
					label1.setVisible(false);
					horizontalSplitPanel.setVisible(true);
				} else {
					label1.setVisible(true);
					horizontalSplitPanel.setVisible(false);
				}
			}
		});
		
		mainWindow.addComponent(verticalLayout);
		
		setMainWindow(mainWindow);
	}
}
package com.example.testgae;

import java.io.Serializable;

public class DataBean implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String column;

	public DataBean(String column) {
		super();
		this.column = column;
	}

	public String getColumn() {
		return column;
	}

	public void setColumn(String column) {
		this.column = column;
	}
	
	
}

Is there something wrong that I am doing or its a bug in the library? Any help would be appreciated.

Thanks,
A G

Running analyze layouts for you application says, that you have only relative heights so components may not render correctly. That’s because you are adding your vertical layout to the window instead of setting it as windows content. That causes your layout having wrapped inside the default vertical layout of the window. So either define a height for the window layout or set your vertical layout as the content with Window.setContent().

Thanks Johannes! It worked like a charm.

However, if you look at the updated application http://test-vaadin.appspot.com, the vertical area is now evenly divided among the three components i.e. the button, label and horizontalSplitPanel. I want the button to take some space (its natural height) and then both the label and horizontalSplitPanel to take rest of the space depending on which one is visible.

I am new to Vaadin and still learning it. Maybe I am not using the right components for the problem that I am trying to solve. Please advise.

What you are looking for is setExpandRatio.

Try using :


verticalLayout.setExpandRatio(label1 , 1.0f);
verticalLayout.setExpandRatio(horizontalSplitPanel , 1.0f);

This will tell the components to use all available space (all components have a ratio of 0 by default so the button will use as few space as possible)

Thanks Mathias. Much appreciated.

Setting the expandRatio on the two components took away the extra space with the button. However, the rest of the space is equally divided between the two components. So, when the button is pressed, the 2nd component appears in the bottom half of the screen and the 1st one appears in the top half. I want to toggle the components and that the component which is visible should cover the whole screen (as if the other component were not there). The API for visible says - “Visible components are drawn in the user interface, while invisible ones are not.” Should it not then show just the other component with all space available to it?

Any ideas on how to best achieve that result?

When it’s time to switch, you could replace the label with your split panel by calling replaceComponent.

Or when you do a setVisible(false) also set the expand ratio to 0 and on setVisible(true) set the expand ratio back to 1

Awesome, thanks guys. Both solutions worked pretty well.

Vaadin rocks!