java 使用数据库数据填充 jTable

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15124904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 18:33:59  来源:igfitidea点击:

Populating jTable using database data

javaswingjdbcjtabledefaulttablemodel

提问by John Vasiliou

I am trying to populate a Netbeans GUI-builder jTable using my Derby database data.

我正在尝试使用我的 Derby 数据库数据填充 Netbeans GUI-builder jTable。

I am using the following code, in my Account.java class:

我在 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;
}

Ideally, I want to be able to return the tableModel with the parameters data and columns inside, as I understand doing this method within my GUI is bad practice. All tutorials online do not show how to send the data across to another class, they just do the database code within the GUI classes.

理想情况下,我希望能够返回包含参数数据和列的 tableModel,因为我理解在我的 GUI 中执行此方法是不好的做法。所有在线教程都没有展示如何将数据发送到另一个类,它们只是在 GUI 类中执行数据库代码。

I have an error where it cannot see data and columns because they are declared and used in an unreachable part of my method. After I've done this, I need to find a way of getting this across to my GUI class and setting the model for my jTable which was made by Netbeans GUI builder.

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

I have been searching this website for answers and I have tried many solutions. However, I never seem to get anything to work due to the way I have coded my system. I have also tried other websites such as:

我一直在这个网站上搜索答案,并尝试了很多解决方案。然而,由于我对系统进行编码的方式,我似乎从来没有得到任何工作。我也尝试过其他网站,例如:

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

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

http://chang.advits.com/populate-data-from-database-into-jtable-in-netbeans< this would have been ideal but it did not work. I followed it to a tee!

http://chang.advits.com/populate-data-from-database-into-jtable-in-netbeans< 这本来是理想的,但它不起作用。我跟着它到了一个发球台!

and have looked at the Javadocs for jTable, DefaultTableModel and ResultSetTableModel - I have by no means not tried doing this myself by learning etc...

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

How can I go about doing this with the way I have modelled my system? Also, anyway of fixing my method or should I scrap it altogether?

我怎样才能用我对系统建模的方式来做到这一点?另外,无论如何修复我的方法还是应该完全废弃它?

回答by MadProgrammer

So, you need some way to "tell" the table that the model has been loaded. You could use a listener call back mechanism, but it might be easier to use a SwingWorkerinstead.

因此,您需要某种方式来“告诉”表模型已加载。您可以使用侦听器回调机制,但使用 a 可能更容易SwingWorker

This will allow you to make a call to the database in a background thread and when it's finished, update the UI from within the EDT.

这将允许您在后台线程中调用数据库,并在调用完成后从 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();
        }
    }
}

You're example won't work either.

你的例子也行不通。

The Vectors columnsand dataare declared withing the context of the try-catch, which means they won't be visible to the remainder of the method, so DefaultTableModel tableModel = new DefaultTableModel(data, columns);won't compile.

Vector小号columnsdata声明withing的背景下try-catch,这意味着他们将不会给该方法的其余部分可见的,所以DefaultTableModel tableModel = new DefaultTableModel(data, columns);不会编译。

You should be, at the very least, dumping the stack trace of any exceptions, it will help you find where the actually error is, so instead of System.out.println(e.getMessage());, you should use e.printStackTrace();. A better solution is to use the Loggereither from the JDK or a third party logger like log4j.

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

You are also resources, that is, if you open, you should close it. While you do call ps.close()and rs.close(), if, for what ever reason, an exception occurs, they will not be called, leaving resources open.

你也是资源,就是打开就应该关闭。当您调用ps.close()and 时rs.close(),如果由于任何原因发生异常,它们将不会被调用,从而使资源保持打开状态。

Add these to the finallyblock of your try-catchto ensure that they are closed and make all best efforts to close them.

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