Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 351933

Summary: GridLayout exclude excludes wrong component
Product: [Eclipse Project] Platform Reporter: Ludwig Moser <luke2000>
Component: SWTAssignee: Platform-SWT-Inbox <platform-swt-inbox>
Status: RESOLVED INVALID QA Contact:
Severity: normal    
Priority: P3 CC: daniel_megert, luke2000, markus.kell.r
Version: 3.7   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Ludwig Moser CLA 2011-07-13 05:37:04 EDT
Build Identifier: 20110218-0911

when you exclude a component from the layout without setting the visibility of the component to false, the wrong component gets excluded.
if you set visibility of the component you excluded in the layout data to false, then the correct one gets excluded.

Reproducible: Always

Steps to Reproduce:
i have sample code for you.
if you enable the outcommented stuff.. it works.

package listTests;

import org.eclipse.swt.SWT;

public class TestGui {

	protected Shell shell;
	private Button btn3;
	private Button btn2;
	private Button btn1;

	/**
	 * Launch the application.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			TestGui window = new TestGui();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Open the window.
	 */
	public void open() {
		Display display = Display.getDefault();
		createContents();
		shell.open();
		shell.layout();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	/**
	 * Create contents of the window.
	 */
	protected void createContents() {
		shell = new Shell();
		shell.setSize(450, 300);
		shell.setText("SWT Application");
		shell.setLayout(new GridLayout(1, false));


		btn1 = new Button(shell, SWT.NONE);
		btn1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
				1, 1));
		btn1.setText("Show ALL");
		btn1.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				GridData gd = (GridData) btn2.getLayoutData();
				gd.exclude = false;
//				btn2.setVisible(!gd.exclude);
				btn2.setLayoutData(gd);
				shell.layout();
			}
		});

		btn2 = new Button(shell, SWT.NONE);
		btn2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
				1, 1));
		btn2.setText("Press me to hide");
		btn2.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				GridData gd = (GridData) btn2.getLayoutData();
				gd.exclude = true;
//				btn2.setVisible(!gd.exclude);
				btn2.setLayoutData(gd);
				shell.layout();
			}
		});

		btn3 = new Button(shell, SWT.NONE);
		btn3.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				System.out.println("try to move");
				Object data = btn2.getData();
				Composite parent = btn2.getParent();
				int style = btn2.getStyle();
				btn2.dispose();
				btn2 = new Button(parent, style);
				btn2.setData(data);
				shell.layout();
			}
		});
		btn3.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
				1, 1));
		btn3.setText("move me above btn2");
	}
}

NOTE: i bugfixed the code in GridLayout

simply change:
for (int i=0; i<children.length; i++) {
		Control control = children [i];
		GridData data = (GridData) control.getLayoutData ();
		if (data == null || !data.exclude) {
			children [count++] = children [i];
		} 
	}

to

for (int i = 0; i < children.length; i++) {
			Control control = children[i];
			GridData data = (GridData) control.getLayoutData();
			if (data != null) {
				children[i].setVisible(!data.exclude);
				if (!data.exclude) {
					children[count++] = children[i];
				}
			}
		}
Comment 1 Markus Keller CLA 2011-07-13 06:30:18 EDT
> NOTE: i bugfixed the code in GridLayout
...
>                 children[i].setVisible(!data.exclude);

I don't expect GridLayout to change the visibility of my controls.
Comment 2 Markus Keller CLA 2011-07-13 06:36:19 EDT
GridLayout is fine. It just ignores the excluded fields. When you click "Press me to hide", your code excludes the button from the layout, so it just keeps its last position.

To see this, you can e.g. change your example to use
"new GridData(SWT.CENTER, SWT.CENTER, false, false)".