我建议采取以下方法:
创建一个Row类来表示从读取的行ResultSet。这可能是一个简单的包装Object[]。
创建一个List集合,并创建该集合AbstractTableModel支持的子类。
使用SwingWorker填充你List从底层读取ResultSet在后台线程(内即doInBackground()方法)。调用SwingWorker的publish方法将Rows 发布回事件调度线程(例如,每100行)。
当SwingWorker的process方法被调用行的最新块读取,将它们添加到您List和消防适当的TableEventS造成显示更新。
同样,使用ResultSetMetaData确定定义Class中每一列的TableModel。这将导致它们正确渲染(如果仅使用2D Object[][]数组则不会这样)。
这种方法的优点是,在处理大ResultSets时,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 rows;
public ResultSetTableModel(ResultSetMetaData rsmd) {
this.rsmd = rsmd;
this.rows = new ArrayList();
}
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() {
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();