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的列,并且在任一侧具有指定的列间距。为了解决这个问题,我提出了几种(非理想的)解决方案:
隐藏/显示时减少/增加列数。
代替使用
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();
}
}
最佳答案
我没有其他办法了。
选项1绝对是我要使用的选项,并且已被Eclipse代码广泛使用(例如,对话框按钮栏上的按钮)。
由于您已经假定控件布局数据为GridData
,因此可以安全地假定父布局为GridLayout
(将GridData
设置为其他布局上的布局数据通常会给出运行时错误)。
关于java - 隐藏GridLayout列和剩余的列间距,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41153597/