2016-12-14 274 views
0

tl; dr有没有一种很好的方法来隐藏GridLayout中的列,并且还隐藏父Composite上的剩余列间距?隐藏GridLayout列和剩余列间距


我有一个在GridLayout几列合成。一列是CompositeStackLayout,所以给予一些行动,我可以隐藏/显示Composite

例如: enter image description here

要做到隐藏/显示我已经设置在GridDataexclude属性和topControl属性上StackLayout

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

现在,当我躲中间Composite,我看到额外的空间出现在行的最远端。

enter image description here

推测这是因为基CompositeGridLayout仍具有相同的列数,所以我们所看到的是与0的宽度,并在任一侧指定列间距的柱。

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

  1. 递减/隐藏/显示当递增列数。

  2. 除了使用exclude属性,我们覆盖了CompositeStackLayout,改变computeSize(...)功能,要么返回0,或计算取决于我们是否希望它出现或者不是真正的大小。 (这是迄今为止我最不喜欢的选项,我觉得不好甚至写吧)

  3. 设置在底座上horizontalSpacingComposite为0,而是采用每列Composite内的间距决定了空间。它应该是这样的时隐时现:

enter image description here

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

选项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

我想不出任何其他方式。

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

既然你已经假定控制布局数据是GridData它是安全的假设父布局GridLayout(一些其他的版面设置GridData作为布局数据一般会给出一个运行时错误)。

+0

好点 - 我没有想过明确检查Eclipse代码是如何处理的(快速搜索发现了这个['ViewSettingsDialog'](http://www.javadocexamples.com/java_source/org/eclipse/ ui/preferences/ViewSettingsDialog.java.html)代码,它做的事情非常相似)。感谢提醒与父母的关系,这使我困惑最长的时间:) – avojak