隐藏GridLayout列和剩余列间距

时间:2016-12-14 22:50:31

标签: java swt

tl; dr 有没有一种方法可以隐藏GridLayout中的列,还可以隐藏父Composite上剩余的列间距?

我在GridLayout中有一个包含多个列的合成。一列是CompositeStackLayout,因此我可以隐藏/显示Composite

例如: enter image description here

要隐藏/显示我已在excludeGridDatatopControl属性设置StackLayout属性:

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

现在,当我隐藏中间Composite时,我看到行的远端出现了额外的空间。

enter image description here

这可能是因为基础GridLayout上的Composite仍具有相同的列数,因此我们看到的是一个宽度为0且两侧都有指定列间距的列。 / p>

为了解决这个问题,我提出了几个(非理想的)解决方案:

  1. 隐藏/显示时减少/增加列数。

  2. 我们不使用exclude属性,而是使用Composite覆盖StackLayout,并将computeSize(...)函数更改为返回0,或计算实际值大小取决于我们是否希望它出现。 (这是迄今为止我最不喜欢的选择,即使写它也感觉不好)

  3. 将基座horizontalSpacing上的Composite设置为0,而是使用每列Composite内的间距来指定间距。隐藏时看起来像这样:

  4. enter image description here

    选项1 到目前为止一直是最诱人的,但是在尝试保持代码模块化时,这里有一个明显的缺点。例如,如果每个列的Composite由某个可重用组件设置,则减少/递增列数取决于该组件知道其父Composite具有GridLayout - 不安全假设!

    选项2 我不喜欢。

    选项3 并不可怕,但它仍然感觉像是误用了间距和边距。另外,回到模块化的角度,其他列组件将负责影响较大视图的间距,而不是让较大的视图决定间距。

    所以我的问题归结为:还有另外一种选择比这三种选择更好吗?

    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();
        }
    
    }
    

1 个答案:

答案 0 :(得分:1)

我想不出任何其他方式。

选项1绝对是我将使用的,并且被Eclipse代码广泛使用(例如,对话框按钮栏上的按钮)。

由于您已假设控件布局数据为GridData,因此可以安全地假设父布局为GridLayout(设置GridData,因为某些其他布局上的布局数据通常会给出运行时错误)。