我正在尝试使用我的Derby数据库数据填充Netbeans GUI-builder jTable。
我在我的Account.java类中使用以下代码:
public DefaultTableModel getData() {
try {
String stmt = "SELECT * FROM APP.DATAVAULT";
PreparedStatement ps = Main.getPreparedStatement(stmt);
ResultSet rs = ps.executeQuery();
ResultSetMetaData md = rs.getMetaData();
int columnCount = md.getColumnCount();
Vector columns = new Vector(columnCount);
//store column names
for (int i = 1; i <= columnCount; i++) {
columns.add(md.getColumnName(i));
}
Vector data = new Vector();
Vector row;
while (rs.next()) {
row = new Vector(columnCount);
for (int i = 1; i <= columnCount; i++) {
row.add(rs.getString(i));
}
data.add(row);
//Debugging
}
// List.setModel(tableModel);
ps.close();
rs.close();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
DefaultTableModel tableModel = new DefaultTableModel(data, columns);
return tableModel;
}
理想情况下,我希望能够返回tableModel,其中包含参数data和columns,因为我知道在我的GUI中执行此方法是不好的做法。所有在线教程都没有展示如何将数据发送到另一个类,他们只是在GUI类中执行数据库代码。
我有一个错误,它无法查看数据和列,因为它们是在我方法的无法访问的部分中声明和使用的。在我完成这个之后,我需要找到一种方法将它传递到我的GUI类并为我的jTable设置模型,这是由Netbeans GUI builder制作的。
我一直在搜索这个网站寻找答案,我尝试了很多解决方案。但是,由于我编写系统的方式,我似乎从未得到任何工作。我也尝试过其他网站,如:
http://tips4java.wordpress.com/2009/03/12/table-from-database/
http://chang.advits.com/populate-data-from-database-into-jtable-in-netbeans&lt;这本来是理想的,但它不起作用。我跟着它去了一个发球台!
并查看了javadocs的jTad,DefaultTableModel和ResultSetTableModel - 我绝对没有尝试通过学习等方式自己做这个...
我如何通过建模系统的方式来实现这一目标?另外,无论如何修复我的方法或者我应该完全废弃它?
答案 0 :(得分:4)
因此,您需要某种方法来“告诉”表格已加载模型。您可以使用侦听器回调机制,但可能更容易使用SwingWorker
。
这将允许您在后台线程中调用数据库,当它完成时,从EDT中更新UI。
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Vector;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import sun.applet.Main;
public class DataLoadWorker extends SwingWorker<TableModel, TableModel> {
private final JTable table;
public DataLoadWorker(JTable table) {
this.table = table;
}
@Override
protected TableModel doInBackground() throws Exception {
Vector data = new Vector();
Vector columns = new Vector();
PreparedStatement ps = null;
ResultSet rs = null;
try {
String stmt = "SELECT * FROM APP.DATAVAULT";
ps = Main.getPreparedStatement(stmt);
rs = ps.executeQuery();
ResultSetMetaData md = rs.getMetaData();
int columnCount = md.getColumnCount();
//store column names
for (int i = 1; i <= columnCount; i++) {
columns.add(md.getColumnName(i));
}
columns.ensureCapacity(columnCount);
Vector row;
while (rs.next()) {
row = new Vector(columnCount);
for (int i = 1; i <= columnCount; i++) {
row.add(rs.getString(i));
}
data.add(row);
//Debugging
}
// List.setModel(tableModel);
} finally {
try {
ps.close();
} catch (Exception e) {
}
try {
rs.close();
} catch (Exception e) {
}
}
DefaultTableModel tableModel = new DefaultTableModel(data, columns);
return tableModel;
}
@Override
protected void done() {
try {
TableModel model = get();
table.setModel(model);
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
}
}
你的榜样也无效。
使用Vector
的上下文声明columns
s data
和try-catch
,这意味着它们对方法的其余部分不可见,因此DefaultTableModel tableModel = new DefaultTableModel(data, columns);
将无法编译。
您至少应该转储任何异常的堆栈跟踪,它将帮助您找到实际错误的位置,因此您应该使用System.out.println(e.getMessage());
而不是e.printStackTrace();
而不是Logger
。更好的解决方案是使用JDK中的log4j
或ps.close()
等第三方记录器。
您也是资源,也就是说,如果您打开,则应关闭它。当你打电话给rs.close()
和finally
时,如果出于某种原因发生异常,则不会调用它们,而是打开资源。
将这些内容添加到try-catch
的{{1}}块中,以确保它们已关闭并尽最大努力关闭它们。