views:

560

answers:

2

I'm trying to create an Eclipse Form that has three foldable sections, one fixed size and two others that should grab all the remaining vertical space in the editor window so, that when one of the bottom sections is folded, the other one would fill all the available space.

I have read the forms article, tried many variations of grabExcessVerticalSpace and SWT.FILL's and pretty much everything the GridData for the sections has to offer, but with no luck. I've also tried to nest the section clients in composites that would grabExcess...Space, but that does not help either. Calling layout() does not help, the form reflows when the sections are folded, and folding the first section works fine.

Here's the code for a form with three sections, but in which the two bottom sections only give up a tiny part of their space when folded, not all of it as I would like:

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

public class SectionFormPage extends FormPage {
    private IManagedForm managedForm;

    public SectionFormPage(FormEditor editor) {
        super(editor, "sectionEditor", "title");
    }

    protected void createFormContent(IManagedForm managedForm) {
        this.managedForm = managedForm;
        FormToolkit toolkit = managedForm.getToolkit();
        Composite body = managedForm.getForm().getBody();

        body.setLayout(new GridLayout());

        createSectionWithButton(toolkit, body, new GridData(SWT.FILL, SWT.FILL, true, false));
        createSectionWithButton(toolkit, body, new GridData(SWT.FILL, SWT.FILL, true, true));
        createSectionWithButton(toolkit, body, new GridData(SWT.FILL, SWT.FILL, true, true));

        body.layout();
    }

    private void createSectionWithButton(FormToolkit toolkit, final Composite body, final GridData layoutData) {
        Section section = createSection(toolkit, body, "Section");
        section.setLayoutData(layoutData);
        section.setClient(toolkit.createButton(section, "button", SWT.NONE));
    }

    private Section createSection(final FormToolkit toolkit, final Composite body, String title) {
        Section section = toolkit.createSection(body, Section.TITLE_BAR | Section.TWISTIE | Section.EXPANDED);
        section.setText(title);
        managedForm.addPart(new SectionPart(section));
        section.addExpansionListener(new ExpansionAdapter() {
            public void expansionStateChanged(ExpansionEvent e) {
                managedForm.reflow(true);
            }
        });
        return section;
    }
}

Any pointers? Where should that layout even be specified, for the Sections or to their parents, or Clients? Thanks beforehand!

+2  A: 

I finally got a colleague to look at this and together we found a solution immediately, the trick was to simply modify the GridData to not grabExcessVerticalSpace when the section is folded:

private void createSectionWithButton(FormToolkit toolkit, final Composite body, final GridData layoutData) {
    final Section section = createSection(toolkit, body, "Section", layoutData.grabExcessVerticalSpace);
    section.setLayoutData(layoutData);
    section.setClient(toolkit.createButton(section, "button", SWT.NONE));
}

private Section createSection(final FormToolkit toolkit, final Composite body, String title,
        boolean shouldGiveUpVerticalSpaceWhenFolded) {
    final Section section = toolkit.createSection(body, Section.TITLE_BAR | Section.TWISTIE | Section.EXPANDED);
    section.setText(title);
    managedForm.addPart(new SectionPart(section));
    if (shouldGiveUpVerticalSpaceWhenFolded) {
        section.addExpansionListener(new ExpansionAdapter() {
            public void expansionStateChanged(ExpansionEvent e) {
                GridData gridData = (GridData) section.getLayoutData();
                gridData.grabExcessVerticalSpace = e.getState();
            }
        });
    }
    section.addExpansionListener(new ExpansionAdapter() {
        public void expansionStateChanged(ExpansionEvent e) {
            managedForm.reflow(true);
        }
    });
    return section;
}

I was just stuck with my idea that it must be possible to define this with the layout somehow. I'd still be interested to know if it is.

hvrauhal
A: 

For the application I'm working on we have created a custom layout class that checks if it is an ExpandableComposite or we've modified the layout data as you did.

Kire Haglin
Ok, thanks for the confirmation!
hvrauhal