5

テーブルが空の場合でも、SWT テーブルに垂直スクロール バーを常に表示することは可能ですか? 常に垂直スクロール バー (無効にすることも可能) を表示することで、列がレイアウトに使用されるときに最後の列が部分的に非表示になることを回避できますColumnWeightData

SWT.V_SCROLLまたはを使用してテーブルを初期化しようとしましたが、table.getVerticalBar().setVisible(true)どちらも成功しませんでした。

に方法がありsetAlwaysShowScrollBarsますScrollableComposite。私が探しているのは、 の同様の方法ですTable

更新:テーブルに十分なデータが含まれているときに表示されるスクロールバーは、Tableから継承するスクロールバーではないと思いますScrollable。デバッグScrollBar.setVisible(boolean)しましたが、テーブル レイアウトの更新時に呼び出されないようです。この観察は正しいですか?

更新 2:これは、テーブル構築のスニペットです。テーブルが空の場合でも垂直スクロール バーが表示され、テーブル データが下にスクロールされている場合でも列ヘッダーが表示されると便利です。注: このスニペットでは、ラベル プロバイダーおよび同じ親コンポジットに配置されたその他のコントロールとして、一部の詳細が省略されています。

protected void createMasterPart(final IManagedForm managedForm, Composite parentComposite)
{
  FormToolkit toolkit = managedForm.getToolkit();

  Composite contentComposite = toolkit.createComposite(parentComposite, SWT.NONE);
  contentComposite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
  toolkit.paintBordersFor(contentComposite);

  contentComposite.setLayout(new GridLayout(2, false));
  GridData gd;

  Composite tableComposite = new Composite(contentComposite, SWT.NONE);
  TableColumnLayout tableColumnLayout = new TableColumnLayout();
  tableComposite.setLayout(tableColumnLayout);
  gd = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 3);
  tableComposite.setLayoutData(gd);

  speakerTableViewer = new TableViewer(tableComposite, SWT.BORDER | SWT.FULL_SELECTION);
  speakerTableViewer.setContentProvider(ArrayContentProvider.getInstance());
  Table speakerTable = speakerTableViewer.getTable();
  speakerTable.setHeaderVisible(true);
  speakerTable.setLinesVisible(true);
  toolkit.paintBordersFor(speakerTable);

  TableViewerColumn tableViewerAudiosampleColumn = new TableViewerColumn(speakerTableViewer, SWT.NONE);
  TableColumn audiosampleColumn = tableViewerAudiosampleColumn.getColumn();
  tableColumnLayout.setColumnData(audiosampleColumn, new ColumnWeightData(60, true));
  audiosampleColumn.setText("Sample");

  TableViewerColumn tableViewerSpeakerColumn = new TableViewerColumn(speakerTableViewer, SWT.NONE);
  TableColumn speakerColumn = tableViewerSpeakerColumn.getColumn();
  tableColumnLayout.setColumnData(speakerColumn, new ColumnWeightData(60, true));
  speakerColumn.setText("Speaker");

  TableViewerColumn tableViewerRemarkColumn = new TableViewerColumn(speakerTableViewer, SWT.NONE);
  TableColumn remarkColumn = tableViewerRemarkColumn.getColumn();
  tableColumnLayout.setColumnData(remarkColumn, new ColumnWeightData(120, true));
  remarkColumn.setText("Remark");
}
4

3 に答える 3

6

Table常にスクロール バーを表示するように強制することはできません。いつ表示するかは OS が決定します。

代替案

そうです、私はこの質問に対する私の答えと非常によく似た解決策を思いつきました:

SWT リストが無効な状態のときに、垂直/水平スクロール バーを表示することはできますか?


アイデアは、ScrolledComposite(他の回答がすでに示唆しているように)スクロールを処理するために a を使用することです。Table自体はスクロールしません。ただし、ユーザーは違いを見分けることができないため、これは何の違いもありません。

ScrolledCompositesetAlwaysShowScrollBars(boolean)には、スクロール バーが必要でない場合でも、常にスクロール バーを表示するように強制できるメソッドがあります。

これは、私が今話したことを説明するサンプルコードです。

public static void main(String[] args)
{
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setLayout(new GridLayout());

    final ScrolledComposite composite = new ScrolledComposite(shell, SWT.V_SCROLL);
    composite.setLayout(new GridLayout());
    composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    final Table table = new Table(composite, SWT.NO_SCROLL | SWT.FULL_SELECTION);
    table.setHeaderVisible(true);

    composite.setContent(table);
    composite.setExpandHorizontal(true);
    composite.setExpandVertical(true);
    composite.setAlwaysShowScrollBars(true);
    composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));

    Button fillTable = new Button(shell, SWT.PUSH);
    fillTable.setText("Fill table");
    fillTable.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false));

    fillTable.addListener(SWT.Selection, new Listener()
    {
        @Override
        public void handleEvent(Event arg0)
        {
            if (table.getColumnCount() < 1)
            {
                for (int col = 0; col < 4; col++)
                {
                    TableColumn column = new TableColumn(table, SWT.NONE);
                    column.setText("Column " + col);
                }
            }

            for (int row = 0; row < 20; row++)
            {
                TableItem item = new TableItem(table, SWT.NONE);

                for (int col = 0; col < table.getColumnCount(); col++)
                {
                    item.setText(col, "Item " + row + " " + col);
                }
            }

            for (int col = 0; col < table.getColumnCount(); col++)
            {
                table.getColumn(col).pack();
            }

            composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));
        }
    });

    Button clearTable = new Button(shell, SWT.PUSH);
    clearTable.setText("Clear table");
    clearTable.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false));

    clearTable.addListener(SWT.Selection, new Listener()
    {
        @Override
        public void handleEvent(Event arg0)
        {
            table.removeAll();

            composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));
        }
    });

    shell.pack();
    shell.setSize(400, 300);
    shell.open();
    while (!shell.isDisposed())
    {
        if (!display.readAndDispatch())
            display.sleep();
    }
    display.dispose();
}

次のようになります。

ここに画像の説明を入力 ここに画像の説明を入力

ご覧のとおり、スクロール バーは常に表示されています。


アップデート

コメントで指摘されているように、このアプローチでは、Table下にスクロールしたときにヘッダーが表示されたままになりません。問題を説明する小さなコード例を投稿していただければ、別の方法 (スクロール バーの強制とは関係ありません) を思いつくかもしれません。

更新2

ここにあなたが望むことをするべきいくつかのコードがあります.トリックはの親でサイズ変更イベントをトリガーすることです,TableViewer表示される水平スクロールバーは実際には必要なく、ウィンドウのサイズを変更すると消えます:

public static void main(String[] args)
{
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setText("StackOverflow");
    shell.setLayout(new GridLayout());

    createMasterPart(shell);

    shell.pack();
    shell.setSize(400, 300);
    shell.open();

    shell.layout(true, true);

    while (!shell.isDisposed())
    {
        if (!display.readAndDispatch())
            display.sleep();
    }
    display.dispose();
}

private static void createMasterPart(Composite parentComposite)
{
    Composite composite = new Composite(parentComposite, SWT.NONE);
    composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    composite.setLayout(new GridLayout(1, false));

    Composite tableComposite = new Composite(composite, SWT.NONE);
    TableColumnLayout tableColumnLayout = new TableColumnLayout();
    tableComposite.setLayout(tableColumnLayout);
    tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    TableViewer tableViewer = new TableViewer(tableComposite, SWT.BORDER | SWT.FULL_SELECTION);
    tableViewer.setContentProvider(ArrayContentProvider.getInstance());
    Table table = tableViewer.getTable();
    table.setHeaderVisible(true);
    table.setLinesVisible(true);

    TableViewerColumn firstTableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
    TableColumn firstTableColumn = firstTableViewerColumn.getColumn();
    firstTableColumn.setText("Sample");
    firstTableViewerColumn.setLabelProvider(new ColumnLabelProvider()
    {
        @Override
        public String getText(Object element)
        {
            Dummy p = (Dummy) element;
            return p.first;
        }
    });

    TableViewerColumn secondTableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
    TableColumn secondTableColumn = secondTableViewerColumn.getColumn();
    secondTableColumn.setText("Speaker");
    secondTableViewerColumn.setLabelProvider(new ColumnLabelProvider()
    {
        @Override
        public String getText(Object element)
        {
            Dummy p = (Dummy) element;
            return p.second;
        }
    });

    TableViewerColumn thirdTableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
    TableColumn thirdTableColumn = thirdTableViewerColumn.getColumn();
    thirdTableColumn.setText("Remark");
    thirdTableViewerColumn.setLabelProvider(new ColumnLabelProvider()
    {
        @Override
        public String getText(Object element)
        {
            Dummy p = (Dummy) element;
            return p.third;
        }
    });

    List<Dummy> elements = new ArrayList<>();

    for(int i = 0; i < 20; i++)
    {
        elements.add(new Dummy("firstfirstfirst " + i, "secondsecondsecond " + i, "thirdthirdthirdthirdthirdthird " + i));
    }

    tableViewer.setInput(elements);

    tableColumnLayout.setColumnData(firstTableColumn, new ColumnWeightData(1, true));
    tableColumnLayout.setColumnData(secondTableColumn, new ColumnWeightData(1, true));
    tableColumnLayout.setColumnData(thirdTableColumn, new ColumnWeightData(2, true));
}

private static class Dummy
{
    public String first;
    public String second;
    public String third;

    public Dummy(String first, String second, String third)
    {
        this.first = first;
        this.second = second;
        this.third = third;
    }
}
于 2014-04-02T08:18:49.217 に答える
0

ScrolledComposite 内にテーブルを配置するよりも優れていると思われるソリューションを作成しました。

私の解決策:スクロールバーが表示されるまで、空のアイテムでテーブルを埋めます。

例:

// Flag that knows if the empty item was added or not
boolean addedEmptyItem = false;

// Get the table client area
Rectangle rect = table.getClientArea ();
// Get the item height 
int itemHeight = table.getItemHeight ();
// Get the header height
int headerHeight = table.getHeaderHeight ();
// Calculate how many items can be visible without scrolling
int visibleCount = (rect.height - headerHeight + itemHeight - 1) / itemHeight;

while ( visibleCount > table.getItemCount() ) {
   // Add an empty item
   new TableItem( table, SWT.NONE );

   // Set the flag
   addedEmptyItem = true;
}

// Vertical bar é disabled if an empty item was added
table.getVerticalBar().setEnabled( !addedEmptyItem );

この解決策が誰かに役立つことを願っています。

ありがとう。

于 2015-05-18T20:58:45.520 に答える
-1

これを行うことはできないと思いますが、ScrolledComposite.setAlwaysShowScrollbars() を true に呼び出してみることはできますが、両方の有効なスクロールバーが常に表示されます。

于 2013-10-15T14:44:24.467 に答える