5

スクロールバーのある JTable の作成に問題があります。2 つの列があり、スクロールバーが表示されない JTable が必要です。

列の 1 つを拡大すると、スクロールバーが表示され、列のサイズが変更されます。

私はこの回答に従いましたJTable both AutoResize and horizo​​ntall scrollable? 基本的には次のようになります。

JTable table = new JTable() {
  @Override
  public boolean getScrollableTracksViewportWidth() {
    return getPreferredSize().width < getParent().getWidth();
  }
};
table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );

ただし、このソリューションでは、最初の列を縮小できません。2 番目の列を拡大してスクロールバーが表示された場合にのみ、最初の列を縮小できます。

必要な動作は、2 つの列が自動的にサイズ変更可能であることです。つまり、スクロールバーがポップアップすることなく、1 列を縮小してから拡張できます。ビューが拡張されるように列の 1 つを拡張する場合にのみ、スクロールバーがポップアップする必要があります。

シナリオ:

  1. 1 列目を縮小 -> 2 列目を拡大、スクロールバーなし
  2. 1 番目の列を拡大 -> 2 番目の列は縮小、スクロールバーは表示されない
  3. 2 列目を拡大 -> 1 列はそのまま、2 列目は拡大し、スクロールバーが表示されます

これを修正するためのアイデアはありますか?

SSCCE:

import javax.swing.JDialog;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.WindowConstants;
import javax.swing.table.AbstractTableModel;
import java.awt.BorderLayout;
import java.awt.Container;

public class TableTest {
public TableTest() {

JDialog mainDialog = new JDialog();
mainDialog.setResizable( true );
mainDialog.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE );
Container contentPane = mainDialog.getContentPane();

JTable myTable = new JTable() {
  @Override
  public boolean getScrollableTracksViewportWidth() {
    return getPreferredSize().width < getParent().getWidth();
  }
};

myTable.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
myTable.setModel( new MyTableModel() );
JScrollPane scrollPane = new JScrollPane( myTable );
contentPane.add( scrollPane, BorderLayout.CENTER );

mainDialog.pack();
mainDialog.setVisible( true );
}

public static void main( String[] args ) {
new TableTest();
}

private class MyTableModel extends AbstractTableModel {

@Override public int getRowCount() {
  return 1;
}

@Override public int getColumnCount() {
  return 2;
}

@Override public Object getValueAt( int rowIndex, int columnIndex ) {
  return "ARandomValue";
}
}
}
4

2 に答える 2

7

getTracksメソッドをオーバーライドするだけでは十分ではありません。スーパーのレイアウトをだまして、正しいことを実行する必要があります。

JTable myTable = new JTable(10, 4) {
    private boolean inLayout;

    @Override
    public boolean getScrollableTracksViewportWidth() {
        return hasExcessWidth();

    }


    @Override
    public void doLayout() {
        if (hasExcessWidth()) {
            // fool super
            autoResizeMode = AUTO_RESIZE_SUBSEQUENT_COLUMNS;
        }
        inLayout = true;
        super.doLayout();
        inLayout = false;
        autoResizeMode = AUTO_RESIZE_OFF;
    }


    protected boolean hasExcessWidth() {
        return getPreferredSize().width < getParent().getWidth();
    }

    @Override
    public void columnMarginChanged(ChangeEvent e) {
        if (isEditing()) {
            // JW: darn - cleanup to terminate editing ...
            removeEditor();
        }
        TableColumn resizingColumn = getTableHeader().getResizingColumn();
        // Need to do this here, before the parent's
        // layout manager calls getPreferredSize().
        if (resizingColumn != null && autoResizeMode == AUTO_RESIZE_OFF
                && !inLayout) {
            resizingColumn.setPreferredWidth(resizingColumn.getWidth());
        }
        resizeAndRepaint();
    }

};

追加のレイアウトプロパティによってその動作をサポートする( SwingXプロジェクトの)JXTableからコピーされたcolumnMarginChangedを処理するための編集後でも、完全に完了していない可能性があります(おそらくまだ完了していません)。

xTable.setHorizontalScrollEnabled(true);
于 2013-03-20T09:32:11.360 に答える
1

@kleopatra の実装により、列のサイズを小さくしてから再度少し大きくすると、スクロールバーが表示されることに気付きました (これは偶然に頻繁に発生します)。そのため、コードを少し変更しました。

protected boolean hasExcessWidth() {
    return getPreferredSize().width - getParent().getWidth() < 50;
}

これにより、自動サイズ変更を失うことなく、列のサイズをゆっくりと大きくすることができます。

魔法の「50」が適切な測定値であるかどうかはまだわかりませんが、初期テストでは非常にうまく機能します

于 2014-04-17T14:46:29.227 に答える