简体   繁体   English

隐藏GridLayout列和剩余的列间距

[英]Hide GridLayout column and remaining column spacing

tl;dr Is there a good way to hide a column in a GridLayout and also hide the remaining column spacing on the parent Composite ? tl; dr有什么好方法可以在GridLayout隐藏列,还可以在父Composite上隐藏剩余的列间距?


I have a composite with several columns in a GridLayout . 我在GridLayout有几列的复合。 One column is a Composite with a StackLayout so that given some action I can hide/show that Composite . 一列是带有StackLayoutComposite ,因此只要执行一些操作,我就可以隐藏/显示Composite

For example: 例如: 在此处输入图片说明

To do the hiding/showing I've been setting the exclude attribute on the GridData and the topControl attribute on the StackLayout : 为了进行隐藏/显示,我一直在GridData上设置exclude属性,并在topControl上设置StackLayout属性:

// To hide
stackLayout.topControl = null;
stackComposite.setVisible(false);
((GridData) stackComposite.getLayoutData()).exclude = true;

Now, when I hide the middle Composite , I see extra space appear at the far end of the row. 现在,当我隐藏中间的Composite ,我看到行的远端出现了额外的空间。

在此处输入图片说明

This is presumably because the GridLayout on the base Composite still has the same number of columns, so what we see is a column with 0 width, and the specified column spacing on either side. 大概是因为基本Composite上的GridLayout仍然具有相同的列数,因此我们看到的是宽度为0的列,并且在任一侧都具有指定的列间距。

To fix this I've come up with several (not-ideal) solutions: 为了解决这个问题,我提出了几种(非理想的)解决方案:

  1. Decrement/increment the number of columns when hiding/showing. 隐藏/显示时减少/增加列数。

  2. Instead of using the exclude attribute, we override the Composite with the StackLayout and change the computeSize(...) functions to either return 0, or compute the real size depending on whether we want it to appear or not. 而不是使用exclude属性,我们使用StackLayout覆盖Composite并更改computeSize(...)函数以返回0,或者根据是否希望它出现来计算实际大小。 (This is by far my least favorite option and I feel bad even writing it) (到目前为止,这是我最不喜欢的选项,即使编写它,我也很难过)

  3. Set the horizontalSpacing on the base Composite to 0, and instead using the spacing inside each columns Composite to dictate the spacing. 将基础Composite上的horizontalSpacing设置为0,而是使用Composite每列内的间距来指定间距。 It would look like this when hidden: 隐藏时看起来像这样:

在此处输入图片说明

Option 1 has been the most enticing so far, however there's an clear drawback here when trying to keep code modular. 到目前为止, 选项1一直是最诱人的,但是在尝试保持代码模块化时,这里存在明显的缺陷。 For example, if the Composite for each column is setup by some reusable component, decrementing/incrementing a column count depends on that component knowing that its parent Composite has a GridLayout - not a safe assumption! 例如,如果每个列的Composite由某个可重用的组件设置,则增加/减少列数取决于该组件,知道其父Composite具有GridLayout不是一个安全的假设!

Option 2 I flat-out do not like. 选项2我放心不喜欢。

Option 3 isn't horrible, however it still feels like a misuse of spacing and margins. 选项3并不可怕,但是仍然感觉像是滥用间距和边距。 Plus, back to the point of modularity, the other column components would be responsible spacing which affects the larger view, instead of letting the larger view dictate the spacing. 另外,回到模块化的角度来看,其他列组件将是负责的间距,这会影响较大的视图,而不是让较大的视图决定间距。

So my question comes down to: is there another option that's better than these three? 因此,我的问题归结为: 还有没有比这三个更好的选择了?


MCVE used to get the images above: MCVE用来获取上面的图像:

public class MCVE {

    final Display display;
    final Shell shell;

    public MCVE() {
        display = new Display();
        shell = new Shell(display);
        shell.setLayout(new GridLayout());
        shell.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        final Composite baseComposite = new Composite(shell, SWT.NONE);
        baseComposite.setLayout(new GridLayout(3, false));
        baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        baseComposite.setBackground(new Color(display, new RGB(125, 125, 255)));

        final Composite contentComposite1 = new Composite(baseComposite, SWT.NONE);
        contentComposite1.setLayout(new GridLayout());
        contentComposite1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        final Label contentLabel1 = new Label(contentComposite1, SWT.NONE);
        contentLabel1.setText("I stretch to fill available space!");

        final Composite stackComposite = new Composite(baseComposite, SWT.NONE);
        final StackLayout stackLayout = new StackLayout();
        stackComposite.setLayout(stackLayout);
        stackComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));

        final Composite stackContentComposite = new Composite(stackComposite, SWT.NONE);
        stackContentComposite.setLayout(new GridLayout());
        stackContentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        final Label stackContentLabel = new Label(stackContentComposite, SWT.NONE);
        stackContentLabel.setText("I can disappear and reappear!");

        stackLayout.topControl = stackContentComposite;

        final Composite contentComposite3 = new Composite(baseComposite, SWT.NONE);
        contentComposite3.setLayout(new GridLayout());
        contentComposite3.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
        final Label contentLabel3 = new Label(contentComposite3, SWT.NONE);
        contentLabel3.setText("I live on the end :(");

        final Button flipButton = new Button(shell, SWT.PUSH);
        flipButton.setText("Flip");
        flipButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                if (stackLayout.topControl == null) {
                    stackLayout.topControl = stackContentComposite;
                    ((GridData) stackComposite.getLayoutData()).exclude = false;
                    // ((GridLayout) baseComposite.getLayout()).numColumns++;
                    stackComposite.setVisible(true);
                    baseComposite.layout(true, true);
                } else {
                    stackLayout.topControl = null;
                    ((GridData) stackComposite.getLayoutData()).exclude = true;
                    // ((GridLayout) baseComposite.getLayout()).numColumns--;
                    stackComposite.setVisible(false);
                    baseComposite.layout(true, true);
                }
            }
        });
    }

    public void run() {
        shell.setSize(600, 115);
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        display.dispose();
    }

    public static void main(final String... args) {
        new MCVE().run();
    }

}

I can't think of any other way. 我没有其他办法了。

Option 1 is definitely what I would use and is used widely by Eclipse code (buttons on the dialog button bar for example). 选项1绝对是我要使用的选项,并且已被Eclipse代码广泛使用(例如,对话框按钮栏上的按钮)。

Since you are already assuming the control layout data is GridData it is safe to assume the parent layout is GridLayout (setting GridData as layout data on some other layout will generally give a run time error). 由于您已经假定控件布局数据是GridData因此可以安全地假定父布局是GridLayout (将GridData设置为其他布局上的布局数据通常会产生运行时错误)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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