簡體   English   中英

隱藏GridLayout列和剩余的列間距

[英]Hide GridLayout column and remaining column spacing

tl; dr有什么好方法可以在GridLayout隱藏列,還可以在父Composite上隱藏剩余的列間距?


我在GridLayout有幾列的復合。 一列是帶有StackLayoutComposite ,因此只要執行一些操作,我就可以隱藏/顯示Composite

例如: 在此處輸入圖片說明

為了進行隱藏/顯示,我一直在GridData上設置exclude屬性,並在topControl上設置StackLayout屬性:

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

現在,當我隱藏中間的Composite ,我看到行的遠端出現了額外的空間。

在此處輸入圖片說明

大概是因為基本Composite上的GridLayout仍然具有相同的列數,因此我們看到的是寬度為0的列,並且在任一側都具有指定的列間距。

為了解決這個問題,我提出了幾種(非理想的)解決方案:

  1. 隱藏/顯示時減少/增加列數。

  2. 而不是使用exclude屬性,我們使用StackLayout覆蓋Composite並更改computeSize(...)函數以返回0,或者根據是否希望它出現來計算實際大小。 (到目前為止,這是我最不喜歡的選項,即使編寫它,我也很難過)

  3. 將基礎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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM