我正在尝试使用我的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,因为我知道在GUI中执行此方法是一种不好的做法。在线上的所有教程都没有显示如何将数据发送到另一个类,它们只是在GUI类中执行数据库代码。

我有一个错误,它看不到数据和列,因为它们在我的方法的不可达部分中声明和使用。完成此操作后,我需要找到一种方法将其传递到我的GUI类中,并设置由Netbeans GUI构建器制作的jTable的模型。

我一直在这个网站上寻找答案,并且尝试了许多解决方案。但是,由于我对系统进行编码的方式,我似乎永远无法工作。我也尝试过其他网站,例如:

http://tips4java.wordpress.com/2009/03/12/table-from-database/

http://chang.advits.com/populate-data-from-database-into-jtable-in-netbeans
并查看了jTable,DefaultTableModel和ResultSetTableModel的Javadocs-我绝对没有尝试通过学习等方式来做到这一点...

如何以系统建模的方式进行操作?另外,还是要修正我的方法,还是应该完全废弃它?

最佳答案

因此,您需要某种方式“告知”模型已加载的表。您可以使用侦听器回调机制,但是使用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();
        }
    }
}


你的榜样也行不通。

Vectorcolumnsdata是在try-catch的上下文中声明的,这意味着它们对方法的其余部分不可见,因此DefaultTableModel tableModel = new DefaultTableModel(data, columns);不会编译。

至少应该转储任何异常的堆栈跟踪,这将帮助您找到实际错误的位置,因此,应使用System.out.println(e.getMessage());代替e.printStackTrace();。更好的解决方案是使用JDK或Logger之类的第三方记录器中的log4j

您也是资源,也就是说,如果打开,则应将其关闭。当您确实调用ps.close()rs.close()时,如果由于某种原因而发生异常,则不会调用它们,从而使资源保持打开状态。

将它们添加到finallytry-catch块中,以确保它们已关闭并尽一切努力关闭它们。

07-26 08:37
查看更多