データベーステーブルのデータをそのまま表示するJTableを表示したい。
これまで、オブジェクト[] []からのデータを表示するJTableを使用してきました。
データを表示する1つの方法は、最初にデータベーステーブルをオブジェクト[] []に変換することですが、簡単でありながらより強力で柔軟な他の方法はありますか。
私は次のアプローチを取ることをお勧めします:
Row
から読み取った行を表すResultSet
クラスを作成します。これは、Object[]
の単純なラッパーである可能性があります。List<Row>
コレクションを作成し、このコレクションを基にするAbstractTableModel
をサブクラス化します。SwingWorker
を使用して、バックグラウンドスレッド(つまり、doInBackground()
メソッド内)で基になるResultSet
から読み取ることにより、List<Row>
を入力します。 SwingWorker
のpublish
メソッドを呼び出して、Row
sを発行し、イベントディスパッチスレッドに戻します(100行ごとなど)。SwingWorker
のprocess
メソッドが呼び出されたら、それらをList<Row>
に追加し、適切なTableEvent
sを起動して表示を更新します。ResultSetMetaData
を使用して、Class
定義内の各列のTableModel
を判別します。これにより、それらが正しくレンダリングされます(2D Object[][]
配列を使用するだけの場合は当てはまりません)。このアプローチの利点は、大きなResultSet
sを処理するときにUIがロックしないこと、および結果が処理されるときに表示が段階的に更新されることです。
[〜#〜]編集[〜#〜]
以下のサンプルコードを追加しました:
/**
* Simple wrapper around Object[] representing a row from the ResultSet.
*/
private class Row {
private final Object[] values;
public Row(Object[] values) {
this.values = values;
}
public int getSize() {
return values.length;
}
public Object getValue(int i) {
return values[i];
}
}
// TableModel implementation that will be populated by SwingWorker.
public class ResultSetTableModel extends AbstractTableModel {
private final ResultSetMetaData rsmd;
private final List<Row> rows;
public ResultSetTableModel(ResultSetMetaData rsmd) {
this.rsmd = rsmd;
this.rows = new ArrayList<Row>();
}
public int getRowCount() {
return rows.size();
}
public int getColumnCount() {
return rsmd.getColumnCount();
}
public Object getValue(int row, int column) {
return rows.get(row).getValue(column);
}
public String getColumnName(int col) {
return rsmd.getColumnName(col - 1); // ResultSetMetaData columns indexed from 1, not 0.
}
public Class<?> getColumnClass(int col) {
// TODO: Convert SQL type (int) returned by ResultSetMetaData.getType(col) to Java Class.
}
}
// SwingWorker implementation
new SwingWorker<Void, Row>() {
public Void doInBackground() {
// TODO: Process ResultSet and create Rows. Call publish() for every N rows created.
}
protected void process(Row... chunks) {
// TODO: Add to ResultSetTableModel List and fire TableEvent.
}
}.execute();
データベースデータをJTableに表示するもう1つの強力で柔軟な方法は、クエリの結果データを CachedRowSet にロードし、 JTable に TableModel アダプタを使用して接続することです。 。
ジョージリースによるこの 本 は、彼のクラスRowSetModelに RowSet をTableModelとして適合させるために ソースコード を提供します。 the-box。私の唯一の変更は、クラスのより良い名前でした:RowSetTableModel。
RowSetはResultSetのサブインターフェースであり、Java 1.4で追加されました。したがって、RowSet はResultSetです。
このページの他の回答で説明されているように、Rowクラス、Rowオブジェクトのリスト、およびResultSetMetaDataを作成する代わりに、CachedRowSet実装が機能します。
Sun/OracleはCachedRowSetの リファレンス実装 を提供しています。他のベンダーまたはJDBCドライバーも実装を提供している場合があります。
すでに何をしていて、何をするつもりかにもよりますが、私はデータベース駆動型アプリのBeans Bindingサポートを備えたNetbeansを非常にうまく利用しています。 JTableをデータベースにバインドすると、自動的にJPAクエリが作成されます。
JTableをResultSetで埋める最良の方法
1)結果セット「rs」には、必要なデータが入力されています。 2)JTable "jTable1"が事前に作成されている3)テーブルヘッダーが事前に実装されている
Java.sql.ResultSet rs = datacn.executeSelectQuery(query);
//Filling JTable with Result set
// Removing Previous Data
while (jTable1.getRowCount() > 0) {
((DefaultTableModel) jTable1.getModel()).removeRow(0);
}
//Creating Object []rowData for jTable's Table Model
int columns = rs.getMetaData().getColumnCount();
while (rs.next())
{
Object[] row = new Object[columns];
for (int i = 1; i <= columns; i++)
{
row[i - 1] = rs.getObject(i); // 1
}
((DefaultTableModel) jTable1.getModel()).insertRow(rs.getRow() - 1,row);
}
カスタムを作成する必要があります TableModel ここで、データの取得元と方法を指定できます。
最初に JTable + TableModel がどのように機能するかを完全に理解してから、以前に投稿された回答の1つに従う必要があります。
私は質問が古いことを知っていますが、Adamskiの解決策に従う誰にとっても、ResultSet
とResultSetMetadata
をguiスレッドとSwingWorker
スレッドで共有する際には注意が必要です。 SQLiteでこのアプローチを使用しているときに、一貫性のない内部状態例外が発生しました。解決策は、SwingWorker
を実行する前にプライベートフィールドにメタデータをロードし、代わりにフィールドを返すゲッター関数(getColumnNameなど)を用意することです。
JTableでデータベーステーブルデータを表示するための小さなメソッドを提供しています。データベーステーブルの結果セットのみをパラメーターとして渡す必要があります。
// rs is the ResultSet of the Database table
public void displayData(ResultSet rs)
{
//jt Represents JTable
//jf represents JFrame
int i;
int count;
String a[];
String header[] = {"1","2","3","4","5"}; //Table Header Values, change, as your wish
count = header.length;
//First set the Table header
for(i = 0; i < count; i++)
{
model.addColumn(header[i]);
}
jt.setModel(model); //Represents table Model
jf.add(jt.getTableHeader(),BorderLayout.NORTH);
a = new String[count];
// Adding Database table Data in the JTable
try
{
while (rs.next())
{
for(i = 0; i < count; i++)
{
a[i] = rs.getString(i+1);
}
model.addRow(a); //Adding the row in table model
jt.setModel(model); // set the model in jtable
}
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null, "Exception : "+e, "Error", JOptionPane.ERROR_MESSAGE);
}
}