2

以下のモックアップのような JTable を作成しようとしています。

カスタム JTable

緑色のコーナーは基本的に、赤色の列と行のヘッダー用のバッファー スペースです。セルは、図の色でレンダリングする必要はありません。ただし、表の残りの「白い」セルと区別できる必要があります。

このテーブルも編集または選択できません。更新中にユーザーが表示するだけです。

これは、行 1,2 && 列 1,2 のカスタム レンダリングを備えた DefaultTableModel を使用し、テーブル値を設定および取得するときに +2 を追加することで実現できることを知っています (ヘッダーとして使用されている行と列を考慮して)。

私の質問は次のとおりです。

  1. ヘッダーで使用されるこれらの静的な値でテーブル モデルを汚染することなく、これを行うよりクリーンな方法はありますか?
  2. テーブル モデルの拡張について読んだことがありますが、どのクラスを拡張する必要があるか (DefaultTableModel、AbstractTableModel)、およびどのメソッドをオーバーライドする必要があるかわかりません。
4

2 に答える 2

6

入力は 20x20 に制限されているため、22x22 のヘッダーを含めます。

また、22x22 のインスタンスを含むインスタンス、または適切なサブクラスをJScrollPane含むJPanelことも検討してください。これは、数千のセルに簡単に拡張できます。GridLayoutJLabel

補遺: 必要に応じて、ここでCellRendererPane提案されているように、適切なフライウェイトレンダラーを作成します。

JTableレンダリングのスケーラビリティを重視するなら、

  1. これは悪用ではありません。それはまさに がどのようTableModelに使用されることを意図しているかです。TableModelあなたが決めたものの矩形行列をモデル化します。JTableそのモデルの(効率的にレンダリングされた)単なるビューです。

  2. ここAbstractTableModelに示されている が望ましいデータ構造であることはめったにないため、私は を好みます。インデックス作成が最も便利になるコンテナを使用してください。は便利で、拡張のガイドとして役立ちます。特に、.VectorDefaultTableModelAbstractTableModelsetValueAt()

    @Override
    public void setValueAt(Object aValue, int row, int col) {
        ... // update your data structure
        this.fireTableCellUpdated(row, col); // notify the view
    }
    
于 2012-04-21T21:56:15.590 に答える
5

より長いコメント、すべてが依存します

1) 可能な場合Columns

  • サイズ変更

  • 並べ替え

2) 可能な場合Columns

  • フィルタリング

  • 並べ替え

a. 次に、2 つの JTable を確認します。最初の JTable は TableHeader のみで、行が削除されたシンプルな JTable と、2 番目の JTable は TableHeader と列と行を含むフル サイズです。

b. 2 つの JTableHeader 間の相互作用のために、
TableColumnModelListener#columnMarginChanged(ChangeEvent e)columnMoved(TableColumnModelEvent e)

c. JPanelすべてがJScrollPane 内で 1 つにまとめられます

d. 行数または列数(またはフィルタリング/ソート)を変更する場合は、サイズ変更+ JPanelontopのみを通知する必要がありますJTable#getPreferredScrollableViewportSize()DimensionJTableTableHeader

そこと非常によく似た方法(必要なものはすべてあります)

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

(ロブへの無限の称賛)

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

public class TableFilterRow extends JFrame implements TableColumnModelListener {
    private static final long serialVersionUID = 1L;

    private JTable table;
    private JPanel filterRow;

    public TableFilterRow() {
        table = new JTable(3, 5);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane(table);
        getContentPane().add(scrollPane);
        table.getColumnModel().addColumnModelListener(this);
        //  Panel for text fields
        filterRow = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
        for (int i = 0; i < table.getColumnCount(); i++) {
            filterRow.add(new JTextField(" Sum at - " + i));
        }
        columnMarginChanged(new ChangeEvent(table.getColumnModel()));
        getContentPane().add(filterRow, BorderLayout.SOUTH);
    }

    //  Implement TableColumnModelListener methods
    //  (Note: instead of implementing a listener you should be able to
    //  override the columnMarginChanged and columMoved methods of JTable)
    @Override
    public void columnMarginChanged(ChangeEvent e) {
        TableColumnModel tcm = table.getColumnModel();
        int columns = tcm.getColumnCount();

        for (int i = 0; i < columns; i++) {
            JTextField textField = (JTextField) filterRow.getComponent(i);
            Dimension d = textField.getPreferredSize();
            d.width = tcm.getColumn(i).getWidth();
            textField.setPreferredSize(d);
        }

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                filterRow.revalidate();
            }
        });
    }

    @Override
    public void columnMoved(TableColumnModelEvent e) {
        Component moved = filterRow.getComponent(e.getFromIndex());
        filterRow.remove(e.getFromIndex());
        filterRow.add(moved, e.getToIndex());
        filterRow.validate();
    }

    @Override
    public void columnAdded(TableColumnModelEvent e) {
    }

    @Override
    public void columnRemoved(TableColumnModelEvent e) {
    }

    @Override
    public void columnSelectionChanged(ListSelectionEvent e) {
    }

    public static void main(String[] args) {
        JFrame frame = new TableFilterRow();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

3)それ以外の場合は、prepareRederer

4)この質問はのタイプとは何の関係もありませんTableModel

于 2012-04-21T21:02:58.773 に答える