2012-03-24 69 views
4

我想顯示一個表格部分內的SWT表,但我有列調整大小和滾動的問題。SWT分段表&滾動

我附加了一些示例代碼,可以放在Eclipse插件的ViewPart中(3.7是我使用的版本)。如果你運行代碼,並調整列的權利,該表獲得一個水平滾動條(這是我想要的)。

現在,如果我摺疊該部分(單擊「部分標題」左側的箭頭),該視圖將獲得一個水平滾動條(我不想)。再次展開該部分,視圖滾動仍然存在,現在表格不再有一個。

我正在尋找一種方法(可能是嵌套複合材料的一些可怕的組合)來停止表比視圖更廣泛,並會感謝任何建議。

public class ExampleView extends ViewPart { 
    /** Note: other fields/methods removed to condense snippet */ 

    private FormToolkit toolkit; 
    private ScrolledForm scrolledForm; 

    public void createPartControl(Composite parent) { 
      parent.setLayout(new FillLayout()); 

    toolkit = new FormToolkit(parent.getDisplay()); 
    scrolledForm = toolkit.createScrolledForm(parent); 
    scrolledForm.setExpandHorizontal(true); 
    scrolledForm.setText("Form Title"); 

    scrolledForm.getBody().setLayout(new FillLayout()); 
    // here's the modification for the solution 
    scrolledForm.getBody().setLayout(
      new BoundedLayout(new FillLayout(), true)); 

    final Section section = toolkit.createSection(scrolledForm.getBody(), 
      Section.DESCRIPTION | Section.TITLE_BAR | Section.TWISTIE 
        | Section.EXPANDED); 

    section.addExpansionListener(new ExpansionAdapter() { 
     public void expansionStateChanged(ExpansionEvent e) { 
      scrolledForm.reflow(true); 
     } 
    }); 
    section.setText("Section Title"); 

    final Table table = toolkit.createTable(section, SWT.FULL_SELECTION); 
    TableViewer viewer = new TableViewer(table); 

    table.setLinesVisible(true); 
    table.setHeaderVisible(true); 
    table.setItemCount(10); 

    TableColumn col = new TableColumn(table, SWT.NONE); 
    col.setText("Column A"); 
    col.setWidth(150); 
    col.setResizable(true); 
    col.setMoveable(true); 

    TableColumn col2 = new TableColumn(table, SWT.NONE); 
    col2.setText("Column B"); 
    col2.setWidth(150); 
    col2.setResizable(true); 
    col2.setMoveable(true); 

    section.setClient(table); 
    } 
} 
+0

次要更新一些討厭的上下的反思黑客 - 我從源頭上看到,調用'section.setLayout(新FillLayout的());第 – 2012-03-29 14:03:41

回答

1

所以這裏有一個解決方案,我想出了使用自定義佈局。它包裝另一個佈局,但可以將computeSize綁定到父組合的寬度或高度 - 基本上只允許向一個方向滾動(如果有更簡單的方法來強制ScrolledForm這樣做,請讓我知道!)。

有需要被應用爲computeSizelayout方法protected

import java.lang.reflect.Method; 

import org.eclipse.swt.graphics.Point; 
import org.eclipse.swt.widgets.Composite; 
import org.eclipse.swt.widgets.Layout; 

public class BoundedLayout extends Layout { 
    protected Layout delegateLayout; 

    protected Method computeSizeMethod; 
    protected Method layoutMethod; 

    protected boolean widthBound; 

    public BoundedLayout(Layout delegateLayout, boolean widthBound) { 
     setDelegateLayout(delegateLayout); 
     this.widthBound = widthBound; 
    } 

    public Layout getDelegateLayout() { 
     return delegateLayout; 
    } 

    public void setDelegateLayout(Layout delegateLayout) { 
     this.delegateLayout = delegateLayout; 

     try { 
      computeSizeMethod = delegateLayout.getClass().getDeclaredMethod(
       "computeSize", Composite.class, int.class, int.class, 
       boolean.class); 
      computeSizeMethod.setAccessible(true); 

      layoutMethod = delegateLayout.getClass().getDeclaredMethod(
       "layout", Composite.class, boolean.class); 
      layoutMethod.setAccessible(true); 
     } catch (Exception e) { 
     throw new RuntimeException(e); 
     } 
    } 

    @Override 
    protected Point computeSize(Composite composite, int wHint, int hHint, 
     boolean flushCache) { 
    // get comp size to make sure we don't let any children exceed it 
    Point compSize = composite.getSize(); 

    try { 
     Point layoutComputedSize = (Point) computeSizeMethod.invoke(
       delegateLayout, composite, wHint, hHint, flushCache); 

     if (widthBound) { 
      layoutComputedSize.x = Math.min(compSize.x, 
        layoutComputedSize.x); 
     } else { 
      layoutComputedSize.y = Math.min(compSize.y, 
        layoutComputedSize.y); 
     } 

     return layoutComputedSize; 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
    } 

    @Override 
    protected void layout(Composite composite, boolean flushCache) { 
    try { 
     layoutMethod.invoke(delegateLayout, composite, flushCache); 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
    } 
} 
+0

我有同樣的問題,我真的沒有調查細節但有些時候,當我在桌面上定義一些LayoutData並給它們一個0的widthHint,一切工作正常: GridData tableLayoutData = new GridData(GridData.FILL_BOTH); tableLayoutData.widthHint = 0; table.setLayoutData(tableLayoutData); – Mathias 2014-08-01 13:04:12

+0

當然你也需要一個heightHint – Mathias 2014-08-01 13:29:52

0

如果你Section.COMPACT樣式添加到您的段,然後將部分的寬度將只在擴展狀態下被調整。在摺疊狀態下,它將恢復到正常大小。

如果您不希望部分在再次展開後增加寬度,我認爲您必須在ExpansionAdapter中使用解決方法。摺疊時手動存儲寬度,並在展開時將其重新放回。

順便說一下,我建議使用WindowBuilder來構建GUI,以便更容易地調整和移動東西。

+0

節將忽略'感謝您花時間回答。 'Section.COMPACT'風格完全符合你所說的,我也研究過'ExpansionAdapter',但它似乎仍取決於佈局(它覆蓋了我的手動設置大小的任何嘗試)。我想我基本上會寫我自己的佈局,類似於'FillLayout',但'computeSize'方法中會有一些魔術來忽略表格的首選大小 – 2012-03-31 20:09:52