简体   繁体   中英

How to get rid of wasted space in SWT ScrolledComposite when the scrollbars are not shown

I have a horizontal ScrolledComposite holding two buttons (actually a composite with two buttons). The space for the scroll bar is allocated even if the scroll bars are hidden. (They get hidden, when the horizontal space is sufficient and scrolling is not necessary.)

在此输入图像描述

How can I get rid of this wasted space?

In the mean time I have configured the scrolled composite to always show the scrollbars ( setAlwaysShowScrollBars(true) ), but I much rather prefer to get rid of the wasted space.

在此输入图像描述

Thank you for your consideration.

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class ScrollbarSpaceIssue extends Composite
{
    public ScrollbarSpaceIssue(final Composite parent, final int style)
    {
        super(parent, style);

        setLayout(new GridLayout(1, false));

        final ScrolledComposite scrolledComposite = new ScrolledComposite(this, SWT.BORDER | SWT.H_SCROLL);
        scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        scrolledComposite.setExpandHorizontal(true);
        scrolledComposite.setExpandVertical(true);
        //scrolledComposite.setAlwaysShowScrollBars(true);
        {
            final Composite composite = new Composite(scrolledComposite, SWT.NONE);
            composite.setLayout(new GridLayout(2, false));
            {
                final Button btn1 = new Button(composite, SWT.NONE);
                btn1.setText("Button 1");

                final Button btn2 = new Button(composite, SWT.NONE);
                btn2.setText("Button 2");
            }

            scrolledComposite.setContent(composite);
            scrolledComposite.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
        }

        pack();
    }

    public static void main(final String[] args)
    {
        final Display display = new Display();

        final Shell shell = new Shell(display);
        shell.setText("Testcase");
        shell.setLayout(new FillLayout());

        new ScrollbarSpaceIssue(shell, SWT.NONE);

        shell.pack();
        shell.open();

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

The reason why there is "wasted space" is that the preferred size of a ScrolledComposite object includes room for the scrollbars, whether they are visible or not. To disable this default functionality, you can override the preferred size calculation by extending ScrolledComposite as such:

class PackedScrolledComposite extends ScrolledComposite
{
    Point scrollBarSize;  // Size of OS-specific scrollbar

    public PackedScrolledComposite(Composite parent, int style)
    {
        super(parent, style);

        Composite composite = new Composite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
        composite.setSize(1, 1);
        scrollBarSize = composite.computeSize(0, 0);
        composite.dispose();
    }

    public Point computeSize(int wHint, int hHint, boolean changed)
    {
        Point point = super.computeSize(wHint, hHint, changed);
        point.x += ((getStyle() & SWT.V_SCROLL) != 0) ? -scrollBarSize.x : 0;
        point.y += ((getStyle() & SWT.H_SCROLL) != 0) ? -scrollBarSize.y : 0;

        return point;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM