[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Newsgroup Home]
[news.eclipse.platform.swt] Re: Layouts, minimal height and grabExcessXXXSpace

Christophe Fondacci wrote:
Hello all,

I have a little problem with SWT.
Here it is :
- I created 2 tables vertically inside a grid composite, separated by a button. The idea is to select an item from the top table and to use the buttons to transfer this item to the bottom table.
- I would like those 2 tables to grab excess vertical space, and the buttons to always keep the minimal required height (which is the default)
- Therefore I set the grabExcessVerticalSpace to true for my 2 tables control
- I do not know the content of those tables at compile time, it depends on what i am editing...


The problem is that when, for example, my first table (the one on top) contains 100 items and the second table is empty, the topmost table takes the entire vertical space and the bottom table is nearly not visible.

I would like those 2 tables to have the same height and to grab the excess height space. I haven't found any way to do this.

This is a general problem people run into when using GridLayout with widgets that like their "preferred" size to be as big as their contents. The GridLayout algorithm wants to respect the preferred size of its children, which in the case of a table is as tall as necessary to display all the rows without scrolling. So the GridLayout is respecting that and giving your one table all the space it "asks" for.
A trick when using GridLayout to keep a widget from taking too much space is to force its "preferred" size to be tiny and then specify that it grab excess space and fill its alignment. You can use the heightHint property of the GridData to do that - just set it to 1 and the widget's "preferred" size will be 1 pixel. If the same widget's GridData also specifies that it be greedy (FILL alignment and grabExcess=true), then it will expand to fill the space its parent layout give it. This combination usually genertes the behavior you want, which is that the widget (Table in your case) expands to fill available space but does not ask for more than its fair share.
Below is a snippet that should work for you. Note that this stays with the GridLayout; I do like, however, the other recommendation to use FormLayout which is a lot more flexible but also more complex, especially if you're coding it by hand without the benefit of a WYSIWYG tool.
By the way, the snippet below was generated using the very-handy "SWT Layout Example" tool available here: http://www.eclipse.org/swt/examples.php



--- Begin included file --- import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem;

public class MyLayout {
public static void main (String [] args) {
	Display display = new Display ();
	Shell shell = new Shell (display);
	GridLayout gridLayout = new GridLayout ();
	shell.setLayout (gridLayout);

	Table table0 = new Table (shell, SWT.BORDER);
	table0.setLinesVisible (true);
	for (int i = 0; i < 20; i++) {
		new TableItem (table0, SWT.NONE).setText("Item " + i);
	}

	GridData data = new GridData ();
	data.horizontalAlignment = GridData.FILL;
	data.verticalAlignment = GridData.FILL;
	data.grabExcessHorizontalSpace = true;
	data.grabExcessVerticalSpace = true;
	data.heightHint = 1;
	table0.setLayoutData (data);

	Button button1 = new Button (shell, SWT.PUSH);
	button1.setText ("button1");
	data = new GridData ();
	data.horizontalAlignment = GridData.CENTER;
	button1.setLayoutData (data);

	Table table2 = new Table (shell, SWT.BORDER);
	table2.setLinesVisible (true);
	TableItem tableItem21 = new TableItem (table2, SWT.NONE);
	tableItem21.setText ("Item1");
	TableItem tableItem22 = new TableItem (table2, SWT.NONE);
	tableItem22.setText ("Item2");
	data = new GridData ();
	data.horizontalAlignment = GridData.FILL;
	data.verticalAlignment = GridData.FILL;
	data.grabExcessHorizontalSpace = true;
	data.grabExcessVerticalSpace = true;
	table2.setLayoutData (data);

	//shell.pack ();
	shell.setSize(500, 500);
	shell.open ();

	while (!shell.isDisposed ()) {
		if (!display.readAndDispatch ())
			display.sleep ();
	}
	display.dispose ();
}
}