ScrolledComposite中的SWT GridLayout搞乱了组件的大小

时间:2017-09-16 18:42:39

标签: java swt

我有一个窗口,必须显示彼此相邻的按钮列表。 所有按钮必须是特定尺寸的正方形(运行时尺寸可能会改变)。

这个简单的例子就像它显示了所有按钮一样。

public class Main
{
    public static void main(String[] args)
    {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());

        val scrollPanel = new ScrolledComposite(shell, SWT.V_SCROLL);
        scrollPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        scrollPanel.setLayout(new FillLayout());

        val gridPanel = new Composite(scrollPanel, SWT.NONE);
        val gridLayout = new GridLayout(1, false);
        gridPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        gridPanel.setLayout(gridLayout);
        scrollPanel.setContent(gridPanel);

        val blue = display.getSystemColor(SWT.COLOR_BLUE);
        val red = display.getSystemColor(SWT.COLOR_RED);
        scrollPanel.setBackground(blue);
        gridPanel.setBackground(red);

        val exitButton = new Button(gridPanel, SWT.PUSH);
        exitButton.setText("Exit");
        exitButton.addListener(SWT.Selection, touchEvent -> shell.dispose());

        for (int i = 1; i <= 10; i++)
        {
            val button = new Button(gridPanel, SWT.PUSH);
            button.setText("Item: " + i);
            button.setSize(60, 60);
            gridPanel.setSize(gridPanel.computeSize(SWT.DEFAULT, SWT.DEFAULT));
        }

        shell.setSize(100, 700);

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

但是,每当我执行gridPanel.computeSize()时,按钮都会丢失由button.setSize()设置的大小。

当我在添加按钮后删除gridPanel.setSize()时,大小将为0,而gridPanel根本不会显示。

当我在scrollPanel上设置gridLayout并将按钮添加到该面板时,只显示一个按钮。 (如果我使用setContent()那么最后一个按钮和第二个按钮(无论出于何种原因)如果我不使用setContent()并且只依赖于按钮的构造函数。)

此时此刻,我完全没有选择,所以如果有人能够清除这种情况,那么请继续。

2 个答案:

答案 0 :(得分:2)

如果您使用布局(您应该使用),则不得使用setSize()或以其他方式干扰布局。

使用widthHint的{​​{1}}和heightHint来控制按钮的大小。

例如:

GridData

答案 1 :(得分:1)

首先,setSize只有在不使用布局(绝对定位)时才能正常工作。

如果您使用布局,它将根据布局本身以及如何定义组件的布局数据自动设置组件大小。

通常,强烈建议使用布局而非绝对定位。

如果是GridLayout,您可以在widthHint中通过heightHintGridData指定组件大小,例如:

Button button = new Button(gridPanel, SWT.PUSH);
button.setText("Item: " + i);
GridData buttonLayoutData = new GridData();
buttonLayoutData.widthHint = 60;
buttonLayoutData.heightHint = 60;
button.setLayoutData(buttonLayoutData);

其他观察:

  • 要使ScrollComposite正常工作,您应该添加以下行:

    scrollPanel.setExpandHorizontal(true);
    scrollPanel.setExpandVertical(true);
    scrollPanel.setMinSize(gridPanel.computeSize(SWT.DEFAULT, SWT.DEFAULT));
    

    特别是,setMinSize会告诉ScrollComposite滚动条应显示的大小。

  • 如果父布局是FillLayout,则不应在其子项上设置布局数据。它没有做任何事情,因为它没有预料到。因此,您应该从setLayoutDatascrollPanel移除gridPanel

  • 如果您想稍后更改按钮大小,只需获取其布局数据,修改提示并要求组件进行布局(也不要忘记通过滚动条通知滚动条setMinSize):

    GridData buttonLayoutData = (GridData) button.getLayoutData();
    buttonLayoutData.widthHint = 40;
    buttonLayoutData.heightHint = 40;
    button.requestLayout();
    scrollPanel.setMinSize(gridPanel.computeSize(SWT.DEFAULT, SWT.DEFAULT));