tl; dr 有没有一种方法可以隐藏GridLayout
中的列,还可以隐藏父Composite
上剩余的列间距?
我在GridLayout
中有一个包含多个列的合成。一列是Composite
,StackLayout
,因此我可以隐藏/显示Composite
。
要隐藏/显示我已在exclude
上GridData
和topControl
属性设置StackLayout
属性:
// To hide
stackLayout.topControl = null;
stackComposite.setVisible(false);
((GridData) stackComposite.getLayoutData()).exclude = true;
现在,当我隐藏中间Composite
时,我看到行的远端出现了额外的空间。
这可能是因为基础GridLayout
上的Composite
仍具有相同的列数,因此我们看到的是一个宽度为0且两侧都有指定列间距的列。 / p>
为了解决这个问题,我提出了几个(非理想的)解决方案:
隐藏/显示时减少/增加列数。
我们不使用exclude
属性,而是使用Composite
覆盖StackLayout
,并将computeSize(...)
函数更改为返回0,或计算实际值大小取决于我们是否希望它出现。 (这是迄今为止我最不喜欢的选择,即使写它也感觉不好)
将基座horizontalSpacing
上的Composite
设置为0,而是使用每列Composite
内的间距来指定间距。隐藏时看起来像这样:
选项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();
}
}
答案 0 :(得分:1)
我想不出任何其他方式。
选项1绝对是我将使用的,并且被Eclipse代码广泛使用(例如,对话框按钮栏上的按钮)。
由于您已假设控件布局数据为GridData
,因此可以安全地假设父布局为GridLayout
(设置GridData
,因为某些其他布局上的布局数据通常会给出运行时错误)。