[英]Hide GridLayout column and remaining column spacing
tl; dr有什么好方法可以在GridLayout
隱藏列,還可以在父Composite
上隱藏剩余的列間距?
我在GridLayout
有幾列的復合。 一列是帶有StackLayout
的Composite
,因此只要執行一些操作,我就可以隱藏/顯示Composite
。
為了進行隱藏/顯示,我一直在GridData
上設置exclude
屬性,並在topControl
上設置StackLayout
屬性:
// To hide
stackLayout.topControl = null;
stackComposite.setVisible(false);
((GridData) stackComposite.getLayoutData()).exclude = true;
現在,當我隱藏中間的Composite
,我看到行的遠端出現了額外的空間。
大概是因為基本Composite
上的GridLayout
仍然具有相同的列數,因此我們看到的是寬度為0的列,並且在任一側都具有指定的列間距。
為了解決這個問題,我提出了幾種(非理想的)解決方案:
隱藏/顯示時減少/增加列數。
而不是使用exclude
屬性,我們使用StackLayout
覆蓋Composite
並更改computeSize(...)
函數以返回0,或者根據是否希望它出現來計算實際大小。 (到目前為止,這是我最不喜歡的選項,即使編寫它,我也很難過)
將基礎Composite
上的horizontalSpacing
設置為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
設置為其他布局上的布局數據通常會產生運行時錯誤)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.