Обновление JTable по нажатию кнопки

Я работаю с JTable с пользовательской моделью таблицы, найденной здесь. Я обновил свой код предложениями, приведенными в этом посте, и столкнулся с новой проблемой. Изменение, которое я сделал в своем коде, должно было ввести ArrayList<CompletedPlayer> в мой JTable чтобы избежать проблем с потоками. После этого код для обновления моей таблицы нажатием кнопки перестал работать.

Код, используемый для инициализации JTable является следующим:

TableModel model = new PlayerTableModel(FileHandler.getCompletedPlayers());
JTable table = new JTable(model);

Код, который я использовал для обновления JTable является следующим:

JButton btnRefreshAllPlayers = new JButton("Refresh");

btnRefreshAllPlayers.addActionListener(new ActionListener() {

    public void actionPerformed(ActionEvent arg0) {

        PlayerTableModel model = (PlayerTableModel) table.getModel();
        model.fireTableDataChanged();

    }

});

Я также пытался использовать repaint() но это тоже не работает. На данный момент, единственный способ получить JTable Обновление означает закрытие и повторное открытие программы. FileHandler имеет ArrayList Я использую для JTable который увеличивается в размере, поскольку пользователь добавляет больше игроков.

Почему не fireTableDataChanged() обнаружить какие-либо изменения?

1 ответ

Решение

Я искал на stackru, и несколько человек сказали, чтобы использовать этот метод.

Нет, не стоит звонить fireTableXxx методы вне контекста TableModel Сами люди, предлагающие иное, просто неправы, и это вызовет у вас проблемы в будущем. Судя по вашему коду, ничего не изменилось. Если вы обновили TableModel в соответствии с ответом на ваш предыдущий вопрос, нет никакой связи с данными в модели с внешним источником. Вам необходимо вручную перезагрузить данные из внешнего источника, создать новый TableModel и применить его к столу

Например...

JButton btnRefreshAllPlayers = new JButton("Refresh");

btnRefreshAllPlayers.addActionListener(new ActionListener() {

    public void actionPerformed(ActionEvent arg0) {

        TableModel model = new PlayerTableModel(FileHandler.getCompletedPlayers());
        table.setModel(model);

    }

});

Я также попытался установить новую модель с обновленным ArrayList, и она работала, но не сохранила ширину строки таблицы, которую я ранее установил.

Это разумно для таблицы, потому что она не знает, имеет ли новая модель те же свойства / столбцы, что и старая, поэтому она сбрасывает их.

Вы могли бы ходить ColumnModel, сохраняя ширину столбца в List или же Map прежде чем применить модель и повторно применить ширину

Есть ли правильный способ обновить JTable?

Вы могли бы предоставить свой TableModel с методом обновления, который может загрузить сами данные и вызвать tableDataChanged событие

public class PlayerTableModel extends AbstractTableModel {
    private final List<PlayerSummary.Player> summaries;

    public PlayerTableModel(List<PlayerSummary.Player> summaries) {
        this.summaries = new ArrayList<PlayerSummary.Player>(summaries);
    }
    // Other TabelModel methods...

    public void refresh() {
        summaries = new ArrayList<>(FileHandler.getCompletedPlayers());
        fireTableDataChanged();
    }
}

Тогда вам нужно будет вызвать этот метод в вашем ActionListener...

PlayerTableModel model = (PlayerTableModel)table.getMode();
model.refresh();
Другие вопросы по тегам