SWT Shell resize depending on children

GGrec picture GGrec · Nov 25, 2013 · Viewed 12.4k times · Source

I'm working on this Composite canvas on which other Composites may be added and removed.

My understanding of how the whole laying-out concept is still in the fog.

When children are added to the container, given the fact that the container has a GridData which fills in the parent, shouldn't the parent also know that the child resized? Children remain hidden after their container has been laid out, because of the shell (top parent).

If the question is too vague, do not hesitate to ask for more details. Also, try your best not pointing me to the Understanding layouts in SWT article.

/**
 * 
 * @author ggrec
 *
 */
public class SSCCE
{

    // ==================== 2. Instance Fields ============================

    private Composite componentContainer;

    private int componentCount = 0;

    // ==================== 3. Static Methods =============================

    public static void main(final String[] args)
    {
        new SSCCE();
    }

    // ==================== 4. Constructors ===============================

    private SSCCE()
    {
        final Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new GridLayout(1, false));

        createContents(shell);

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

    // ==================== 5. Creators ===================================

    private void createContents(final Composite parent)
    {
        parent.setLayout(new GridLayout());
        parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        final Button button = new Button(parent, SWT.PUSH);
        button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        button.setText("Add New Component");

        button.addSelectionListener(new SelectionAdapter()
        {
            @Override public void widgetSelected(final SelectionEvent e)
            {
                addNewComponent();

                componentContainer.layout();
            }
        });

        componentContainer = new Composite(parent, SWT.BORDER);
        componentContainer.setLayout(new GridLayout());
        componentContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    }

    // ==================== 6. Action Methods =============================

    private void addNewComponent()
    {
        final Composite component = new Composite(componentContainer, SWT.BORDER);
        component.setLayout(new FillLayout());
        component.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

        final Label label = new Label(component, SWT.NONE);
        label.setText( String.valueOf(componentCount++) );
    }
}

Fun fact: This question is veeeery related to this other one, that was posted 9 minutes ago. Someone is either psychic or stalking me.

Answer

greg-449 picture greg-449 · Nov 26, 2013

To get the Shell to resize you need to layout everything and recalculate its size:

shell.layout(true, true);

final Point newSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);  

shell.setSize(newSize);

You may be able to get away with calling layout() on a child Composite of the shell depending on what has changed.