SWT: Nested Layouts with ScrolledComposite exceeds available space
Asked Answered
S

1

6

I want to build a Master-Detail layout for one of my applications using SWT.

Container, Content, Sidebar and Part1 are Composite instances. Scrolled is a ScrolledComposite

The desired layout is something like:

+--Container-------------------------------------+
|+--Content----------------------++--Sidebar----+|
||                               ||+--Part1----+||
||                               |||           |||
||                               |||           |||
||                               |||           |||
||                               |||           |||
||                               |||           |||
||                               ||+-----------+||
||                               ||+--Scrolled-+||
||                               |||           |||
||                               |||           |||
||                               |||           |||
||                               |||           |||
||                               |||           |||
||                               ||+-----------+||
|+-------------------------------++-------------+|
+------------------------------------------------+

The Content should grab all the space horizontally and vertically that is available.

The sidebar is basically a container for Part1 and Scrolled which should be of equal height.

Scrolled is the container for a Composite containing a dynamic number of sub items which are arranged in the content composite. Because there can be a large variation of the number of sub-items, this Composite should be scrollable.

I have now implemented this in the following way:

  • Container has a GridLayout with 2 colums.

  • Inside of that the content has FILL_BOTH behaviour and grabs also all HORIZONTAL/VERTICAL space.

  • The sidebar has a FillLayout(SWT.VERTICAL) and contains the Part1 and Scrolled Childs.

Problem: When putting a lot of items into the scrolled composite and the layout just overflows the available space and there is no scrolling available where it should be.

When I use a FillLayout(SWT.HORIZONTAL) for the container the behaviour is as desired, since there is a scrolling and everything is "inside bounds".

Is there a way to achieve this behaviour also when using a GridLayout because I want the content to grab most of the space.

Attached the current test SWT snippet:

public class Scrolled {
    public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setLayout(new GridLayout(2,false));
        //shell.setLayout(new FillLayout(SWT.HORIZONTAL));

        Composite content = new Composite(shell, SWT.BORDER);
        content.setLayoutData(new GridData(SWT.LEFT,SWT.CENTER,false,false));

        Composite sidebar = new Composite(shell, SWT.BORDER);
        sidebar.setLayout(new FillLayout(SWT.VERTICAL));
        sidebar.setLayoutData(new GridData(SWT.LEFT,SWT.CENTER,false,false));

        Composite cc = new Composite(sidebar, SWT.BORDER);

        ScrolledComposite sc = new ScrolledComposite(sidebar, SWT.BORDER
                | SWT.V_SCROLL | SWT.H_SCROLL);
        sc.setLayout(new GridLayout(1,true));

        Composite c = new Composite(sc, SWT.NONE);
        c.setSize(400, 400);
        c.setLayout(new GridLayout(1, true));

        for(int i = 0; i < 1000; i++){
            new Button(c, SWT.PUSH).setText("Text");
        }

        sc.setMinSize(c.computeSize(SWT.DEFAULT, SWT.DEFAULT));
        sc.setContent(c);
        sc.setExpandHorizontal(true);
        sc.setExpandVertical(true);
        sc.setAlwaysShowScrollBars(true);

        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }
}
Stormi answered 7/6, 2009 at 8:59 Comment(0)
S
6

seems like I found the solution.

Seems to be the case that a Composite has to take GRAB_EXCESS_VERTICAL to be limited to available width. Otherwise the component gets assigned the preferred height which is the maximum height to display all at once.

The following code changes did the trick:

content.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,true));

sidebar.setLayoutData(new GridData(SWT.FILL,SWT.FILL,false,true));
Stormi answered 7/6, 2009 at 10:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.