2012-03-24 48 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ことをソースから見ます()); 'はセクション –

答えて

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を定義してwidthHintに0を指定すると、すべて正常に動作する。 GridData tableLayoutData = new GridData(GridData.FILL_BOTH); tableLayoutData.widthHint = 0; table.setLayoutData(tableLayoutData); – Mathias

+0

もちろんheightHintも必要です – Mathias

0

あなたのセクションにSection.COMPACTスタイルを追加する場合は、セクションの幅は拡大した状態にリサイズされます。折りたたまれた状態では、通常のサイズに戻ります。

さらに拡大してセクションの幅を広げたくない場合は、ExpansionAdapterの回避策を使用する必要があります。折りたたむときに手動で幅を格納し、展開するときに幅を戻します。

Btw、私はWindowBuilderを使用してGUIを構築して、簡単に調整したり移動したりすることをお勧めします。

+0

によって無視されます。時間をとっていただきありがとうございます。 'Section.COMPACT'スタイルは、あなたが言ったことを正確に行い、' ExpansionAdapter'も見ましたが、Layout(手動でサイズを設定しようとする試みを上書きします)に依然として左右されているようです。私は基本的に 'FillLayout'に似た独自のレイアウトを書くつもりだと思うが、' computeSize'メソッドではテーブルの望ましいサイズを無視するいくつかの魔法があるだろう。 –