JTable не будет перерисовывать/обновлять при вставке данных в mysql

Я не уверен, что я делаю неправильно, но я получаю данные из базы данных MySQL и заполняю JTable с помощью DefaultTableModel. Затем я показываю это на экране. После добавления данных из текстовых полей в базу данных JTable не обновляется. Я проверил БД и вставил данные. Я пробовал использовать table.repaint() или dTableModel.fireTableDataChanged() в прослушивателе событий для кнопки добавления, и все равно ничего. Вот код:

public class DbTable {

    private JLabel lFirstName, lLastName, lState, lBirthDate;
    private JTextField fFirstName, tLastName, tState, tBirthDate;
    private JButton btnAdd;
    private Object[][] databaseResults;
    private Object[] columns = { "Col 1", "Col 2", "Col 3", "Col 4",
            "Col 5", "ЈCol 6", "Col 7" };
    private ResultSet rows;
    private ResultSet rowsCb;

    private JComboBox combobox;


    private DefaultTableModel dTableModel = new DefaultTableModel(
            databaseResults, columns) {
        public Class getColumnClass(int column) {
            Class returnValue; 

            if ((column >= 0) && (column < getColumnCount())) {
                returnValue = getValueAt(0, column).getClass();
            } else { 
                returnValue = Object.class;
            }
            return returnValue;
        }
    };

    private JTable table = new JTable(dTableModel);
    Connection conn = null;
    public static void main(String[] args) {
        DbTable dbTable = new DbTable();

        dbTable.getTable();
    }

    public void getTable() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);



        try {
            Class.forName("com.mysql.jdbc.Driver");

            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost/database", "root", "");

            Statement sqlState = conn.createStatement(
                    ResultSet.TYPE_SCROLL_SENSITIVE,
                    ResultSet.CONCUR_UPDATABLE);

            String selectStuff = "SELECT  `invoice`.`id` ,  `client`, `date`, `project`, `amount`,`unitPrice`, `total`"
                    + "FROM  `invoice` ,  `clients`"
                    + "WHERE  `invoice`.`clientID` =  `clients`.`id`"
                    + "ORDER BY  `invoice`.`id` ASC ";

            rows = sqlState.executeQuery(selectStuff);

            Object[] tempRow;

            while (rows.next()) {
                tempRow = new Object[] { rows.getInt(1), rows.getString(2),
                        rows.getString(3), rows.getString(4), rows.getInt(5),
                        rows.getInt(6), rows.getDouble(7) };
                dTableModel.addRow(tempRow);

            }

        } catch (SQLException e) {
            e.getMessage();
        } catch (ClassNotFoundException e) {
            e.getMessage();
        }

        table.setFont(new Font("Tahoma", Font.PLAIN, 14));
        table.setAutoCreateRowSorter(true);

        JScrollPane scrollPane = new JScrollPane(table);
        // frame.add(combobox, BorderLayout.NORTH);

        frame.add(scrollPane, BorderLayout.NORTH);
        // Define values for my labels
        lFirstName = new JLabel("Klijent ID: ");
        lLastName = new JLabel("Datum: ");
        lState = new JLabel("Projekat: ");
        lBirthDate = new JLabel("Ukupno"); // Define the size of text fields
        fFirstName = new JTextField(10);
        tLastName = new JTextField(10);
        tBirthDate = new JTextField(10);
        tState = new JTextField(10);
        btnAdd = new JButton("Add");

        btnAdd.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                String sDatum = "", sProjekat = "";
                int sKlijenId;
                double sUkupno = 0.00;
                sKlijenId = Integer.parseInt(fFirstName.getText());
                sDatum = tLastName.getText();
                sProjekat = tState.getText();
                sUkupno = Double.parseDouble(tBirthDate.getText());

                try {
                    Class.forName("com.mysql.jdbc.Driver");

                    conn = DriverManager.getConnection(
                            "jdbc:mysql://localhost/sjajplusz", "root", "");

                    Statement sqlState = conn.createStatement(
                            ResultSet.TYPE_SCROLL_SENSITIVE,
                            ResultSet.CONCUR_UPDATABLE);

                    String selectStuff = "SELECT * FROM invoice";

                    rows = sqlState.executeQuery(selectStuff);

                    rows.moveToInsertRow();
                    rows.updateInt("clientID", sKlijenId);
                    rows.updateString("date", sDatum);
                    rows.updateString("project", sProjekat);
                    rows.updateDouble("total", sUkupno);

                    rows.insertRow();
                    rows.updateRow();

                } catch (SQLException e1) {
                    e1.getMessage();
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                int invoiceId = 0;

                try {
                    rows.last();
                    invoiceId = rows.getInt(1);
                } catch (SQLException e) {
                    e.getMessage();
                }


//              Object[] invoice = {invoiceId, sKlijenId, sDatum, sProjekat, "", "", sUkupno};
//              
//              dTableModel.addRow(invoice);

                dTableModel.fireTableDataChanged();

            }
        });

        JPanel inputPanel = new JPanel(); // Put components in the panel
        inputPanel.add(lFirstName);
        inputPanel.add(fFirstName);
        inputPanel.add(lLastName);
        inputPanel.add(tLastName);
        inputPanel.add(lState);
        inputPanel.add(tState);
        inputPanel.add(lBirthDate);
        inputPanel.add(tBirthDate);
        inputPanel.add(btnAdd);

        frame.add(inputPanel, BorderLayout.SOUTH);

        // frame.add(scrollPane, BorderLayout.CENTER);
        frame.setSize(500, 400);
        frame.setVisible(true);

        try {
            conn.close();
        } catch (SQLException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
}

По сути, это продолжение этой серии YouTube Java JTable 38.


person Lord Zed    schedule 26.02.2014    source источник


Ответы (1)


Вы не перезагружаете данные из базы данных. После того, как вы добавили его в базу данных, вы должны перезагрузить данные, обновить DefaultTableModel и затем вызвать fireTableDataChanged(). Вы делаете это только изначально в своем методе getTable(). Вы должны извлечь этот код, который загружает ваши данные, и вызвать его в своем прослушивателе действий.

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

person Kai    schedule 26.02.2014
comment
Код является продолжением серии руководств по yt. Как обновить DefaultTableModel? - person Lord Zed; 26.02.2014
comment
DefaultTableModel предоставляет метод setDataVector() для передачи новых данных. - person Kai; 26.02.2014
comment
Итак, у меня это работает так: dTableModel.setNumRows(0); table.setModel(dTableModel); table.setModel(getData()); , а затем getData() — это отдельный метод, который захватывает свежие данные из базы данных. Есть лучший способ это сделать? - person Lord Zed; 26.02.2014
comment
Если это работает, ваш вопрос кажется ответом. Возможно, есть лучший способ, но сейчас важно, чтобы вы понимали каждую написанную вами строку кода, чтобы понимать концепции, лежащие в основе JTable и TableModel. - person Kai; 26.02.2014
comment
-1, `обновите вашу DefaultTableModel, а затем вызовите fireTableDataChanged().` - вызов любого из методов fireXXX() должен выполняться TableModel, а не кодом приложения. DefaultTableModel вызывает соответствующий метод. - person camickr; 26.02.2014
comment
@LordZed, почему вы дважды вызываете метод setModel () и почему вы устанавливаете количество строк равным 0, если планируете заменить всю модель. Просто вызовите метод setModel(...) один раз с данными, которые вы хотите отобразить. - person camickr; 26.02.2014
comment
@camickr Я думаю, что архитектурные проблемы здесь не рассматриваются. OP использует DefaultTableModel, а не собственную реализацию. - person Kai; 26.02.2014
comment
The OP is using a DefaultTableModel - именно, нет необходимости вызывать fireTableDataChanged, так как DefaultTableModel это уже делает. - person camickr; 26.02.2014
comment
@camick dTableModel = getData(); просто добавляет данные к существующим данным в JTable. Вот почему я установил dTableModel.setNumRows(0) до того, как табличная модель получит новые данные. И, пожалуйста, не стесняйтесь отсылать меня к дополнительной литературе по ООП, или если у вас есть предложения по улучшению существующего кода, дайте мне знать. - person Lord Zed; 26.02.2014