Isuru
Isuru

Reputation: 31283

Values repeating when Populating a JTable

I have a JTable. And I've added the column to it within a method like this.

private void createSearchResultTable() {
    DefaultTableColumnModel columnModel = new DefaultTableColumnModel();
    String columnNames[] = {"Title", "Author", "Edition", "Availability", "Reserve"};

    for (int i = 0; i < columnNames.length; i++) {
        TableColumn column = new TableColumn();
        column.setHeaderValue(columnNames[i]);
        columnModel.addColumn(column);
    }
    tblBookSearchResults.setColumnModel(columnModel);

    ButtonColumn buttonColumn = new ButtonColumn(tblBookSearchResults, reserveBook, 4);
    buttonColumn.setMnemonic(KeyEvent.VK_ENTER);
}

enter image description here

Now I'm populating the JTable with data retrieved from a MySQL database.

private boolean populateSearchResultTable(String title, String author, String publisher) {
    con = DatabaseHandler.connectToDb();
    try {
        if (title.trim().length() != 0) {
            pst = con.prepareStatement("SELECT title, author, edition, status FROM book WHERE title LIKE ? ");
            pst.setString(1, "%" + title + "%");
        }
        else if (author.trim().length() != 0) {
                    // Say, this query is getting executed
            pst = con.prepareStatement("SELECT title, author, edition, status FROM book WHERE author LIKE ? ");
            //pst.setString(1, "%" + author + "%");
                    pst.setString(1, "Dan");
        }
        else if (publisher.trim().length() != 0) {
            pst = con.prepareStatement("SELECT title, author, edition, status FROM book WHERE publisher LIKE ? ");
            pst.setString(1, "%" + publisher + "%");
        }
        rs = pst.executeQuery();
        int rowNum = 0;
        while (rs.next()) {                
            tblBookSearchResults.setValueAt(rs.getString(1), rowNum, 1);
        }
        return true;
    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e.getLocalizedMessage());
    }
    finally {

    }
    return false;
}

The data set is retrieved without an issue but when I'm setting the values to the JTable, it looks like this.

enter image description here

The first value gets repeated in all columns. I can't figure out why this is happening? Any suggestion on how to correct this would be appreciated.

Thank you.

Upvotes: 0

Views: 1046

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347184

Don't use JTable#setValue when updating a JTable, instead, add new rows or modify existing rows through the model.

Also, you're not incrementing the rowNum value, so you're always interacting with the first row of the table

Simple example

A simple example that uses a Swing Timer to add a new row to the model...

enter image description here

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;

public class TestTableModel01 {

    public static void main(String[] args) {
        new TestTableModel01();
    }

    public TestTableModel01() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                final DefaultTableModel model = new DefaultTableModel(new Object[]{"A", "B", "C", "D", "E"}, 0);
                JTable table = new JTable(model);

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                Timer timer = new Timer(500, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (model.getRowCount() < 100) {
                            int row = model.getRowCount();
                            model.addRow(new Object[]{
                                row + "x" + 0,
                                row + "x" + 1,
                                row + "x" + 2,
                                row + "x" + 3,
                                row + "x" + 4
                            });
                        } else {
                            ((Timer)(e.getSource())).stop();
                        }
                    }
                });
                timer.start();
            }
        });
    }
}

Upvotes: 2

Related Questions