2016-12-14 277 views
0

tl; dr有沒有一種很好的方法來隱藏GridLayout中的列,並且還隱藏父Composite上的剩餘列間距?隱藏GridLayout列和剩餘列間距


我有一個在GridLayout幾列合成。一列是CompositeStackLayout,所以給予一些行動,我可以隱藏/顯示Composite

例如: enter image description here

要做到隱藏/顯示我已經設置在GridDataexclude屬性和topControl屬性上StackLayout

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

現在,當我躲中間Composite,我看到額外的空間出現在行的最遠端。

enter image description here

推測這是因爲基CompositeGridLayout仍具有相同的列數,所以我們所看到的是與0的寬度,並在任一側指定列間距的柱。

爲了解決這個問題,我提出了幾個(不理想)解決方案:

  1. 遞減/隱藏/顯示當遞增列數。

  2. 除了使用exclude屬性,我們覆蓋了CompositeStackLayout,改變computeSize(...)功能,要麼返回0,或計算取決於我們是否希望它出現或者不是真正的大小。 (這是迄今爲止我最不喜歡的選項,我覺得不好甚至寫吧)

  3. 設置在底座上horizontalSpacingComposite爲0,而是採用每列Composite內的間距決定了空間。它應該是這樣的時隱時現:

enter image description here

選項1一直是最誘人的,到目前爲止,但有試圖保持代碼的模塊化時是一個明顯的缺點在這裏。例如,如果每個列的Composite由某個可重用組件設置,則遞減/遞增列計數取決於該組件,因爲知道其父項Composite有 - 這不是一個安全的假設!

選項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

我想不出任何其他方式。

選項1絕對是我會用到的,並被Eclipse代碼廣泛使用(例如對話框按鈕欄上的按鈕)。

既然你已經假定控制佈局數據是GridData它是安全的假設父佈局GridLayout(一些其他的版面設置GridData作爲佈局數據一般會給出一個運行時錯誤)。

+0

好點 - 我沒有想過明確檢查Eclipse代碼是如何處理的(快速搜索發現了這個['ViewSettingsDialog'](http://www.javadocexamples.com/java_source/org/eclipse/ ui/preferences/ViewSettingsDialog.java.html)代碼,它做的事情非常相似)。感謝提醒與父母的關係,這使我困惑最長的時間:) – avojak