【问题标题】:Create GridLayout With Rows of Equal Height创建具有等高行的 GridLayout
【发布时间】:2017-09-16 18:56:50
【问题描述】:

我想要一个带有一些标签的组合,所有标签应该有相同的高度,但它们应该垂直居中。

到目前为止,我有以下内容:

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

    final Composite composite = new Composite(shell, SWT.VERTICAL);
    composite.setLayout(GridLayoutFactory.fillDefaults().numColumns(1).equalWidth(true).spacing(0, 0).create());
    for (int i = 0; i < 10; i++) {
        final Label label = new Label(composite, SWT.WRAP);
        label.setAlignment(SWT.CENTER);
        label.setText(i < 5 ? "small " + i : "a very big text for the row that is named " + i);
        label.setToolTipText(label.getText());
        label.setLayoutData(GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(true, true).create());
    }

    shell.setSize(100, 600);
    shell.open();

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

如您所见,标签在其行中垂直居中,但环绕的标签比其他标签占用更多空间。

如果我将hint(SWT.DEFAULT, 60) 添加到GridData,我可以强制标签具有相同的高度,但它们将不再垂直居中。

我可以将所有标签包装在复合材料中,在复合材料上设置高度提示并将标签居中,但让我们先看看还有另一个选项。

如何创建垂直居中的等高行?

【问题讨论】:

    标签: java layout eclipse-plugin swt


    【解决方案1】:

    由于您尝试统一排列可能大小不同的小部件,我认为一个不错的选择是将每个Label 放入Composite。这样每个Composite 可以具有相同的大小,并且Label 将居中。

    通过将ControlListener添加到父Composite,您可以检查每个孩子Composite的大小,然后将每个孩子的高度提示设置为最大孩子的高度:

    public static void main(final String[] args) {
        final Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
    
        final Composite composite = new Composite(shell, SWT.VERTICAL);
        composite.setLayout(GridLayoutFactory.fillDefaults().numColumns(1).equalWidth(true).spacing(0, 0).create());
    
        final List<Composite> children = new ArrayList<Composite>();
        for (int i = 0; i < 10; i++) {
            final Composite c = new Composite(composite, SWT.BORDER);
            c.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
            c.setLayout(new GridLayout());
    
            final Label label = new Label(c, SWT.WRAP);
            label.setAlignment(SWT.CENTER);
            label.setText(i < 5 ? "small " + i : "a very big text for the row that is named " + i);
            label.setToolTipText(label.getText());
            label.setLayoutData(GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(true, true).create());
    
            children.add(c);
        }
    
        composite.addControlListener(new ControlAdapter() {
            @Override
            public void controlResized(final ControlEvent e) {
                int maxHeight = 0;
                for (final Composite c : children) {
                    if (c.getClientArea().height > maxHeight) {
                        maxHeight = c.getClientArea().height;
                    }
                }
                for (final Composite c : children) {
                    ((GridData) c.getLayoutData()).heightHint = maxHeight;
                }
            }
        });
    
        shell.setSize(100, 600);
        shell.open();
    
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }
    

    结果:

    调整大小后:

    【讨论】:

    • 这似乎只是巧合。 Composite.getClientArea().y 是它的 y 坐标,而不是它的高度。你需要要么getClientArea().height要么getSize().y
    • 另外,对我来说,getClientArea().heightgetSize().y 始终为 0。
    • @mapeters 很好 - 绝对应该是 getClientArea().height。我已经更新了代码,谢谢! getClientArea() 返回的 Rectangle 是 0x0,直到第一次调整大小。然后它会被正确计算,如果你在ControlListener 中抛出一个打印语句,你会看到它发生了变化。
    猜你喜欢
    • 1970-01-01
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多