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.