How to fill data in a JTable with database?

java, jtable, swing

Solution

I would recommend taking the following approach:

- Create a `Row` class to represent a row read from your `ResultSet`. This could be a simple wrapper around an `Object[]`.

- Create a `List<Row>` collection, and subclass `AbstractTableModel` to be backed by this collection.

- Use a `SwingWorker` to populate your `List<Row>` by reading from the underlying `ResultSet` on a background thread (i.e. within the `doInBackground()` method). Call `SwingWorker`'s `publish` method to publish `Row`s back to the Event Dispatch thread (e.g. every 100 rows).

- When the `SwingWorker`'s `process` method is called with the latest chunk of Rows read, add them to your `List<Row>` and fire appropriate `TableEvent`s to cause the display to update.

- Also, use the `ResultSetMetaData` to determine the `Class` of each column within the `TableModel` definition. This will cause them to be rendered correctly (which won't be the case if you simply use a 2D `Object[][]` array).

The advantage of this approach is that the UI will not lock up when processing large `ResultSet`s, and that the display will update incrementally as results are processed.

EDIT

Added example code below:

/**
 * 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();

Problem

I want to display a JTable that display the data from a DataBase table as it is. Up till now, I have used JTable that displays data from Object [ ][ ]. I know one way to display the data is to first convert the database table into Object [ ][ ] but Is there any other which is easy yet more powerful and flexible.

Original source