Заполнение jTable с использованием данных базы данных

Я пытаюсь заполнить jTable для построения графического интерфейса Netbeans, используя данные моей базы данных Derby.

Я использую следующий код в своем классе 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 с данными параметров и столбцами внутри, поскольку я понимаю, что использование этого метода в моем графическом интерфейсе является плохой практикой. Все учебные пособия в Интернете не показывают, как отправлять данные в другой класс, они просто выполняют код базы данных в классах графического интерфейса.

У меня есть ошибка, когда он не может видеть данные и столбцы, потому что они объявлены и используются в недоступной части моего метода. После того, как я это сделал, мне нужно найти способ передать это моему классу графического интерфейса и установить модель для моей таблицы jTable, созданную построителем графического интерфейса Netbeans.

Я искал этот сайт для ответов, и я пробовал много решений. Тем не менее, я никогда не заставляю что-либо работать из-за того, как я закодировал свою систему. Я также пробовал другие сайты, такие как:

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

http://chang.advits.com/populate-data-from-database-into-jtable-in-netbeans ‹ это было бы идеально, но не сработало. Я следовал за ним до тройника!

и просмотрел Javadocs для jTable, DefaultTableModel и ResultSetTableModel - я ни в коем случае не пытался сделать это сам, изучая и т. д.

Как я могу сделать это с тем, как я смоделировал свою систему? Кроме того, в любом случае исправить мой метод или я должен полностью отказаться от него?


person John Vasiliou    schedule 27.02.2013    source источник


Ответы (1)


Итак, вам нужен какой-то способ «сообщить» таблице, что модель была загружена. Вы можете использовать механизм обратного вызова слушателя, но вместо этого может быть проще использовать SwingWorker.

Это позволит вам сделать вызов базы данных в фоновом потоке и, когда он будет завершен, обновить пользовательский интерфейс из EDT.

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 columns и 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, чтобы убедиться, что они закрыты, и приложите все усилия, чтобы закрыть их.

person MadProgrammer    schedule 28.02.2013
comment
Большое спасибо за помощь. Ваша другая информация о finally в блоке try-catch чрезвычайно полезна! Я пройдусь по вашему коду в ближайшие пару часов и реализую его, когда вернусь к вам. Еще раз спасибо. - person John Vasiliou; 28.02.2013
comment
Хорошо, я использовал не код как таковой, а его фрагменты, за исключением наконец. Я не уверен, должен ли я отметить это как правильное, поскольку моя программа все еще не работает, но это помогло мне. Этого достаточно, чтобы отметить его как правильный? - person John Vasiliou; 28.02.2013
comment
Я задал новый вопрос и реализовал часть приведенного выше кода! См. - stackoverflow.com/questions/15144715/ - person John Vasiliou; 01.03.2013