10

水平スクロールに関係なく、最初の列が常に画面上で同じ位置にあり、下を通過する列と重なるように、JScrollPaneでテーブルを設定するための最良の方法は何ですか?

スクロールバーが左端にある場合、列は正常に見えますが、ユーザーが右にスクロールすると、ビューポートの右端に最後の列が表示されるまで、2番目の列(2以降)が最初の列の下に移動しますか?

Ecksteinの「JavaSwing」の本から抜粋したサンプルを見つけましたが、これは一種のことですが、最初の列のサイズを変更することはできません。1つのJPanelが水平構造体と2次列を保持するテーブルを保持し、別のJPanelがそれらの上に浮かぶ(スクロールに関係なく固定される)スキームを考えていました。構造体は、最初の列が浮かんでいるときにビューポートの範囲を一定に保つことです。理想的には、同じモデルを使用して2つのテーブルでそれを行うことができますが、アイデア全体が単純な解決策であるかどうかはわかりません。

理想的には、複数のテーブルが同じスクロールペインに垂直に配置され、最初の列がすべて整列して一緒に移動し、個々のテーブル間に水平方向のギャップがほとんどないセットアップが必要です。

4

4 に答える 4

12

固定列テーブルは、必要なことのほとんどを実行します。

固定列のサイズ変更はサポートされていないため、次のようなコードを追加する必要があります。

MouseAdapter ma = new MouseAdapter()
{
    TableColumn column;
    int columnWidth;
    int pressedX;

    public void mousePressed(MouseEvent e)
    {
        JTableHeader header = (JTableHeader)e.getComponent();
        TableColumnModel tcm = header.getColumnModel();
        int columnIndex = tcm.getColumnIndexAtX( e.getX() );
        Cursor cursor = header.getCursor();

        if (columnIndex == tcm.getColumnCount() - 1
        &&  cursor == Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR))
        {
            column = tcm.getColumn( columnIndex );
            columnWidth = column.getWidth();
            pressedX = e.getX();
            header.addMouseMotionListener( this );
        }
    }

    public void mouseReleased(MouseEvent e)
    {
        JTableHeader header = (JTableHeader)e.getComponent();
        header.removeMouseMotionListener( this );
    }

    public void mouseDragged(MouseEvent e)
    {
        int width = columnWidth - pressedX + e.getX();
        column.setPreferredWidth( width );
        JTableHeader header = (JTableHeader)e.getComponent();
        JTable table = header.getTable();
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = (JScrollPane)table.getParent().getParent();
        scrollPane.revalidate();
    }
};

JTable fixed = fixedColumnTable.getFixedTable();
fixed.getTableHeader().addMouseListener( ma );
于 2010-03-30T21:27:10.830 に答える
5

JScrollPaneには、このための特別な領域である行ヘッダーがあります(APIの図を参照してください:)

必要なのは次のとおりです。-この固定領域用に追加のJTableを作成します-データモデルの最初の列に接続します-行ヘッダーとして設定します-メインテーブルでデータの最初の列を省略または削除します。

スクロールペインが上下にスクロールすると、両方のテーブルがコードを追加せずに同期してスクロールします。スクロールペインが水平方向にスクロールすると、行ヘッダーは常に表示されたままになり、メインテーブルのみがスクロールします。

ほとんどの場合、必要な追加コードは、camickrの例のように、列のサイズ変更のみです。

于 2010-03-30T21:52:13.270 に答える
2

http://fahdshariff.blogspot.sg/2010/02/freezing-columns-in-jtable.htmlから抽出されたこのクラスを確認してください

import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.JViewport; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.JTableHeader; 
import javax.swing.table.TableModel;   
public class FrozenTablePane extends JScrollPane{     
    public FrozenTablePane(JTable table, int colsToFreeze){     
        super(table);       
        TableModel model = table.getModel();       
        //create a frozen model     
        TableModel frozenModel = new DefaultTableModel(                                 
                model.getRowCount(),                                 
                colsToFreeze);       
        //populate the frozen model     
        for (int i = 0; i < model.getRowCount(); i++) {       
            for (int j = 0; j < colsToFreeze; j++) {         
                String value = (String) model.getValueAt(i, j);         
                frozenModel.setValueAt(value, i, j);       
            }     
        }
    //create frozen table
    JTable frozenTable = new JTable(frozenModel);
    //remove the frozen columns from the original table
    for (int j = 0; j < colsToFreeze; j++) {
    table.removeColumn(table.getColumnModel().getColumn(0));
    }     table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    //format the frozen table     
    JTableHeader header = table.getTableHeader();     
    frozenTable.setBackground(header.getBackground());     
    frozenTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);    
    frozenTable.setEnabled(false);     
    //set frozen table as row header view   
    JViewport viewport = new JViewport();    
    viewport.setView(frozenTable); 
    viewport.setPreferredSize(frozenTable.getPreferredSize());   
    setRowHeaderView(viewport);   
    setCorner(JScrollPane.UPPER_LEFT_CORNER, 
            frozenTable.getTableHeader()); 
    }
}

その後、コンストラクターメソッドを呼び出すだけです。

JTable table = new JTable( <yourData>, <yourColumns> );
FrozenTablePane frozenPane = new FrozenTablePane(table,1);//where 1 is the number of freezed column(s)
于 2015-03-11T08:17:10.283 に答える
1

あなたは正しい方向に進んでいると思います。概念的には、各行に「ヘッダー列」があるテーブルがあります。2つのテーブルを使用します。1つには「左端」の列があり、もう1つには他のすべての列があります。次に、これらをJSplitPaneに表示し、左側に「左端の列」テーブル、右側に残りのテーブルを表示します。両方のテーブルのyオフセットを制御する単一の垂直スクロールバーと、右側のペインを制御する単一の水平スクロールバー(のみ)があります。

JScrollPaneの高度な機能を使用して、メインスクロール領域の左側に「ヘッダー」コンポーネントを設定することもできます。私はそれをしたことがありませんが、あなたはそれをあなたの行の「ヘッダー」として使うことができるかもしれません。

于 2010-03-30T20:10:51.173 に答える