Значения повторяются при заполнении JTable

У меня есть JTable. И я добавил к нему столбец с помощью такого метода.

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);
}

введите здесь описание изображения

Теперь я заполняю JTable данными, полученными из базы данных MySQL.

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

Набор данных извлекается без проблем, но когда я устанавливаю значения для JTable, это выглядит так.

введите здесь описание изображения

Первое значение повторяется во всех столбцах. Я не могу понять, почему это происходит? Любое предложение о том, как исправить это, будет оценено по достоинству.

Спасибо.


person Isuru    schedule 11.05.2013    source источник
comment
Чтобы быстрее получить помощь, опубликуйте SSCCE. Жесткий код некоторых данных.   -  person Andrew Thompson    schedule 11.05.2013


Ответы (1)


Не используйте JTable#setValue при обновлении JTable, вместо этого добавляйте новые строки или изменяйте существующие строки через модель.

Кроме того, вы не увеличиваете значение rowNum, поэтому вы всегда взаимодействуете с первой строкой таблицы.

Простой пример

Простой пример, в котором используется Swing Timer для добавления новой строки в модель...

введите здесь описание изображения

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();
            }
        });
    }
}
person MadProgrammer    schedule 11.05.2013
comment
Я очень новичок в Java, поэтому я не совсем знаком с использованием этой модели, которую вы упомянули. Не могли бы вы немного уточнить? И спасибо, что указали на возрастающую ошибку. Я исправил это, но теперь это выглядит как это - person Isuru; 11.05.2013
comment
Взгляните на Как использовать таблицы. Swing принимает форму парадигмы MVC (модель, управление, представление), отделяя представление/управление от модели. - person MadProgrammer; 11.05.2013
comment
Привет! Попробовал на вашем примере. Данные загружаются, за исключением одной проблемы с добавлением таблицы в часть JFrame. В приведенном выше примере кода создается совершенно новый JFrame, верно? Я не хочу добавлять таблицу в существующий JFrame. Вот код, который у меня есть. В настоящее время отображается только форма без таблицы. - person Isuru; 13.05.2013
comment
В примере кода нет ничего, что указывало бы на какие-либо проблемы. Если где-то еще вы не добавляете другие компоненты в кадр... - person MadProgrammer; 14.05.2013
comment
хм ... Я не добавляю никаких других элементов управления. Только JFrame создается из конструктора. - person Isuru; 14.05.2013
comment
Хорошо, я понял. Я пропустил строку frame.setLayout(new BorderLayout());. Большое спасибо :) - person Isuru; 14.05.2013