2012-07-05 57 views
7

我想有一個ScrolledComposite它有一個父母GridLayout但滾動條不顯示,除非我使用FillLayout。我與FillLayout的問題在於,它的子女佔用了可用空間的相等部分。ScrolledComposite父GridLayout

在我的情況下,有兩個小部件,頂部的部件應該不超過窗口的1/4,ScrolledComposite應占用剩餘空間。但是,他們都拿走了一半。

有沒有辦法將GridLayout用於ScrolledComposite或者是否可以修改FillLayout的行爲?

這裏是我的代碼:

private void initContent() { 

    //GridLayout shellLayout = new GridLayout(); 
    //shellLayout.numColumns = 1; 
    //shellLayout.verticalSpacing = 10; 
    //shell.setLayout(shellLayout); 
    shell.setLayout(new FillLayout(SWT.VERTICAL)); 

    searchComposite = new SearchComposite(shell, SWT.NONE); 
    searchComposite.getSearchButton().addListener(SWT.Selection, this); 

    ScrolledComposite scroll = new ScrolledComposite(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER); 
    scroll.setLayout(new GridLayout(1, true)); 

    Composite scrollContent = new Composite(scroll, SWT.NONE); 
    scrollContent.setLayout(new GridLayout(1, true)); 

    for (ChangeDescription description : getChanges(false)) { 
     ChangesComposite cc = new ChangesComposite(scrollContent, description); 
    } 

    scroll.setMinSize(scrollContent.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 
    scroll.setContent(scrollContent); 
    scroll.setExpandVertical(true); 
    scroll.setExpandHorizontal(true); 
    scroll.setAlwaysShowScrollBars(true); 

} 
+3

我有同樣的問題,你有沒有找到解決方案? –

回答

1

我想你錯過了什麼這裏是定義GridData爲孩子。

佈局控制兒童的位置和大小。並且每個佈局類都有一個對應的佈局數據類,允許在佈局中配置每個特定的子項,如果它們填滿整個空間,它們佔用了多少個單元格等。

我猜你的網格佈局可能有4行,上面的小部件只佔用一個小區,另一個小孩佔據其餘部分(3)。這是通過GridData.verticalSpan屬性實現的。

看看Understanding Layouts in SWT並嘗試不同的佈局數據屬性,看看他們做了什麼。

+0

對不起,我覺得我還不夠清楚。主要問題是ScrolledComposite不顯示它的滾動條,如果我把它放在一個GridLayout中,它只適用於FillLayout - 但它不符合我的需要。我會編輯原始文章以清楚說明。 – gombost

+0

'FillLayout'強制控件的大小相同。最初,控制將與最高控制一樣高,最寬。看起來,這種佈局會使您的控件足夠大,以便「ScrolledComposite」顯示滾動條。但是當你有一個'GridLayout'時,你必須通過'GridData'對象指定控件在每個單元格中的佈局方式。這決定了它們的大小。如果你不這樣做,可能內容不夠大。只是猜測O :) –

2

除了setLayout()之外,還需要調用setLayoutData()。在下面的代碼示例中,查看GridData對象是如何構造並傳遞給兩個setLayoutData()調用中的每一個的。

private void initContent(Shell shell) 
{ 
    // Configure shell 
    shell.setLayout(new GridLayout()); 

    // Configure standard composite 
    Composite standardComposite = new Composite(shell, SWT.NONE); 
    standardComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); 

    // Configure scrolled composite 
    ScrolledComposite scrolledComposite = new ScrolledComposite(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER); 
    scrolledComposite.setLayout(new GridLayout()); 
    scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 
    scrolledComposite.setExpandVertical(true); 
    scrolledComposite.setExpandHorizontal(true); 
    scrolledComposite.setAlwaysShowScrollBars(true); 

    // Add content to scrolled composite 
    Composite scrolledContent = new Composite(scrolledComposite, SWT.NONE); 
    scrolledContent.setLayout(new GridLayout()); 
    scrolledComposite.setContent(scrolledContent); 
} 
+1

調用'scrolledComposite.setLayout(...)'什麼都不做。 'ScrolledComposite'覆蓋了方法,並且沒有設置佈局,因爲默認情況下它已經有一個'ScrolledCompositeLayout'。所以不知道在其子節點上調用'.setLayoutData'會發生什麼。 –

2

注意!這個答案基於Eclipse RAP,它的行爲可能不同於普通的SWT。

幾天前我還在爲同樣的問題而苦苦掙扎。我在同一頁面上有兩個ScrolledComposite s,我需要左邊的那個不需要更多空間(即使空間可用)。

雖然嘗試了不同的解決方案,我發現一個ScrolledComposite的行爲取決於其LayoutData如下:

  • 如果layoutData設置爲new GridData(SWT.LEFT, SWT.TOP, false, true),那麼ScrolledComposite將保持它的預期大小,而不管父Composite的尺寸變化。
  • 如果layoutData設置爲new GridData(SWT.LEFT, SWT.TOP, true, true),那麼ScrolledComposite將根據父Composite的大小更改收縮/展開。這也包括擴展到所需的更大寬度(意味着列保持相等)。

基於這種行爲我能加入一個調整大小監聽器來改變左ScrolledComposite的基於父Composite sizelayoutDataComposite來解決這個問題。

這種做法說明了下面的例子:

public class LayoutingScrolledComposites extends AbstractEntryPoint { 
    public void createContents(Composite parent) {  
     parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 
     parent.setLayout(new GridLayout(2, false)); 

     ScrolledComposite sc1 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL); 
     Composite c1 = new Composite(sc1, SWT.BORDER); 
     sc1.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true)); 
     c1.setLayout(new GridLayout(3, false)); 
     sc1.setContent(c1); 
     Label l1 = new Label (c1, SWT.BORDER); 
     l1.setText("Some text"); 
     l1 = new Label (c1, SWT.BORDER); 
     l1.setText("Some text"); 
     l1 = new Label (c1, SWT.BORDER); 
     l1.setText("Some text"); 
     c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 

     ScrolledComposite sc2 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL); 
     sc2.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true)); 
     Composite c2 = new Composite(sc1, SWT.BORDER); 
     c2.setLayout(new GridLayout(3, false)); 
     sc2.setContent(c2); 
     Label l2 = new Label (c2, SWT.BORDER); 
     l2.setText("Some text"); 
     l2 = new Label (c2, SWT.BORDER); 
     l2.setText("Some text"); 
     l2 = new Label (c2, SWT.BORDER); 
     l2.setText("Some text"); 
     c2.setSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 

     parent.addListener(SWT.Resize, new Listener() { 
      public void handleEvent(Event e) { 
       int sc1_x = sc1.getContent().getSize().x; 
       int sc2_x = sc2.getContent().getSize().x; 

       //Enable/Disable grabExcessHorizontalSpace based on whether both sc's would fit in the shell 
       if (LayoutingScrolledComposites.this.getShell().getSize().x > sc1_x+sc2_x) { 
        if (((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace) { 
         //sc1 does not change width in this mode 
         ((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace=false;       
        } 
       } else { 
        if (!((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace) { 
         //sc1 changes width in this mode 
         ((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace=true;      
        } 
       } 
       parent.layout(); //Needed so that the layout change would take effect during the same event 
      } 
     }); 
    } 
} 

但是這種方法似乎對我來說有點「hackish的」解決方案。因此,我很樂意看到更好的方法。