[英]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
. 一列是带有
StackLayout
的Composite
,因此只要执行一些操作,我就可以隐藏/显示Composite
。
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: 为了解决这个问题,我提出了几种(非理想的)解决方案:
Decrement/increment the number of columns when hiding/showing. 隐藏/显示时减少/增加列数。
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) (到目前为止,这是我最不喜欢的选项,即使编写它,我也很难过)
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.