javaswingsqlitejtabledefaulttablemodel

How to populate JTable from ResultSet?


I call getnPrintAllData() method after pressing OK button:

public class DatabaseSQLiteConnection {
    Connection conn = null;
    PreparedStatement statement = null;
    ResultSet res = null;
    
    public DatabaseSQLiteConnection(){
        try{
            Class.forName("org.sqlite.JDBC");
            conn = DriverManager.getConnection("jdbc:sqlite:test.sqlite");
            statement = conn.prepareStatement("SELECT * from product_info;");
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }   
    
    public void getnPrintAllData(){
        String name, supplier, id;
        DefaultTableModel dtm = new DefaultTableModel();
        Window gui = new Window(); //My JPanel class        
        try{
            res = statement.executeQuery();
            testResultSet(res);
            ResultSetMetaData meta = res.getMetaData();
            int numberOfColumns = meta.getColumnCount();
            while (res.next())
            {
                Object [] rowData = new Object[numberOfColumns];
                for (int i = 0; i < rowData.length; ++i)
                {
                    rowData[i] = res.getObject(i+1);
                }
                dtm.addRow(rowData);
            }
            gui.jTable1.setModel(dtm);
            dtm.fireTableDataChanged();
            //////////////////////////

        }
        catch(Exception e){
            System.err.println(e);
            e.printStackTrace();
        }
        finally{
            try{
                res.close();
                statement.close();
                conn.close();
            }
            catch(Exception e){
                e.printStackTrace();
            }
        }
    }    
    
    public void testResultSet(ResultSet res){
        try{
            while(res.next()){
                System.out.println("Product ID: "+ res.getInt("product_id"));
                System.out.println("Product name: "+ res.getString("product_name"));
                System.out.println("Supplier: "+ res.getString("supplier"));
            }        
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }
}

testResultSet() method is working properly. How to change my code so that it works, or what is the most simple code to make DefaultTableModel from ResultSet? I am receiving:

java.lang.IllegalStateException: SQLite JDBC: inconsistent internal state

-error.


Solution

  • I think the simplest way to build a model from an instance of ResultSet, could be as follows.

    public static void main(String[] args) throws Exception {
        // The Connection is obtained
    
        ResultSet rs = stmt.executeQuery("select * from product_info");
    
        // It creates and displays the table
        JTable table = new JTable(buildTableModel(rs));
    
        // Closes the Connection
    
        JOptionPane.showMessageDialog(null, new JScrollPane(table));
    
    }
    

    The method buildTableModel:

    public static DefaultTableModel buildTableModel(ResultSet rs)
            throws SQLException {
    
        ResultSetMetaData metaData = rs.getMetaData();
    
        // names of columns
        Vector<String> columnNames = new Vector<String>();
        int columnCount = metaData.getColumnCount();
        for (int column = 1; column <= columnCount; column++) {
            columnNames.add(metaData.getColumnName(column));
        }
    
        // data of the table
        Vector<Vector<Object>> data = new Vector<Vector<Object>>();
        while (rs.next()) {
            Vector<Object> vector = new Vector<Object>();
            for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
                vector.add(rs.getObject(columnIndex));
            }
            data.add(vector);
        }
    
        return new DefaultTableModel(data, columnNames);
    
    }
    

    UPDATE

    Do you like to use javax.swing.SwingWorker? Do you like to use the try-with-resources statement?

    public class GUI extends JFrame {
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new GUI().setVisible(true);
                }
            });
        }
    
        private final JButton button;
        private final JTable table;
        private final DefaultTableModel tableModel = new DefaultTableModel();
    
        public GUI() throws HeadlessException {
    
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    
            table = new JTable(tableModel);
            add(new JScrollPane(table), BorderLayout.CENTER);
    
            button = new JButton("Load Data");
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    new SwingWorker<Void, Void>() {
                        @Override
                        protected Void doInBackground() throws Exception {
                            loadData();
                            return null;
                        }
                    }.execute();
                }
            });
            add(button, BorderLayout.PAGE_START);
    
            setSize(640, 480);
        }
    
        private void loadData() {
            LOG.info("START loadData method");
    
            button.setEnabled(false);
    
            try (Connection conn = DriverManager.getConnection(url, usr, pwd);
                    Statement stmt = conn.createStatement()) {
    
                ResultSet rs = stmt.executeQuery("select * from customer");
                ResultSetMetaData metaData = rs.getMetaData();
    
                // Names of columns
                Vector<String> columnNames = new Vector<String>();
                int columnCount = metaData.getColumnCount();
                for (int i = 1; i <= columnCount; i++) {
                    columnNames.add(metaData.getColumnName(i));
                }
    
                // Data of the table
                Vector<Vector<Object>> data = new Vector<Vector<Object>>();
                while (rs.next()) {
                    Vector<Object> vector = new Vector<Object>();
                    for (int i = 1; i <= columnCount; i++) {
                        vector.add(rs.getObject(i));
                    }
                    data.add(vector);
                }
    
                tableModel.setDataVector(data, columnNames);
            } catch (Exception e) {
                LOG.log(Level.SEVERE, "Exception in Load Data", e);
            }
            button.setEnabled(true);
    
            LOG.info("END loadData method");
        }
    
    }