【问题标题】:Populating jTable using database data使用数据库数据填充 jTable
【发布时间】:2013-02-27 23:53:30
【问题描述】:

我正在尝试使用我的 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 类,并为我的 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

并查看了 jTable、DefaultTableModel 和 ResultSetTableModel 的 Javadocs - 我从来没有尝试过自己通过学习等来做到这一点......

如何使用我为我的系统建模的方式来执行此操作?另外,无论如何要修复我的方法还是应该完全废弃它?

【问题讨论】:

    标签: java swing jdbc jtable defaulttablemodel


    【解决方案1】:

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

    你的例子也行不通。

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

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

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

    将这些添加到您的try-catchfinally 块中,以确保它们已关闭并尽最大努力关闭它们。

    【讨论】:

    • 非常感谢您的帮助。您在 try-catch 块中有关 finally 的其他信息非常有帮助!我将在接下来的几个小时内检查您的代码,并在我去的时候实施它并回复您。再次感谢。
    • 好的,我没有使用过这样的代码,但它的一些部分,除了最后。我不确定是否应该将其标记为正确,因为我的程序仍然无法正常工作,但这对我有帮助。这足以将其标记为正确吗?
    • 我提出了一个新问题,并实现了上面的一些代码!请看-stackoverflow.com/questions/15144715/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-23
    • 2019-03-03
    相关资源
    最近更新 更多