Java Swing Jtable не обновляется через fireXXX с использованием AbstractTableModel

У меня есть JTable в моем графическом интерфейсе, который я хочу динамически обновлять. С Jtable, конечно же, связана TableModel, где я расширил AbstractTableModel и переопределил соответствующие методы.

У меня есть четыре метода для моего JTable:

  • Добавить ряд
  • КопироватьSelectedRow
  • УдалитьSelectedRow
  • Удалить все

Когда я запускаю AddRow или CopySelectedRow, таблица «отстаёт на одно обновление»:

Если я нажму newRow один раз, визуально ничего не произойдет.

Если я дважды нажимаю newRow, первый отображается, а второй нет.

Однако использование deleteSelected или deleteAll обновляет таблицу, когда я нажимаю (т.е. не отстаю).

Выдержка из моего класса TableModel:

public class TableModel extends AbstractTableModel {

private List<String[]> data;

public TableModel() {
    data = new ArrayList<String[]>();
}

...

public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    data.get(rowIndex)[columnIndex] = aValue.toString();
    fireTableCellUpdated(rowIndex, columnIndex);
}

public void addRow(String[] aValue) {
    data.add(aValue);
    fireTableRowsInserted(data.size()-1, data.size()-1);
}

public void copyRow(int rowIndex) {
    addRow(data.get(rowIndex));
}

public void removeRow(int rowIndex) {
    data.remove(rowIndex);
    fireTableRowsDeleted(rowIndex, rowIndex);
}

И как я их называю:

JButton newRow = new JButton("New row");
    newRow.addActionListener(new ActionListener() {
        // Handling newRow event
        public void actionPerformed(ActionEvent e) {
            tableModel.addRow(new String[]{"", "", "", "", "", "", "", "", "", "", ""});
        }
    });

    JButton copyRow = new JButton("Copy selected row");
    copyRow.addActionListener(new ActionListener() {
        // Handling copyRow event
        public void actionPerformed(ActionEvent e) {
            if (table.getSelectedRow() != -1) {
                tableModel.copyRow(table.getSelectedRow());
            }
        }
    });

    JButton deleteRow = new JButton("Delete selected row");
    deleteRow.addActionListener(new ActionListener() {
        // Handling deleteRow event
        public void actionPerformed(ActionEvent e) {
            if (table.getSelectedRow() != -1) {
                tableModel.removeRow(table.getSelectedRow());
            }
        }
    });

    JButton deleteAllRows = new JButton("Delete all rows");
    deleteAllRows.addActionListener(new ActionListener() {
        // Handling deleteAllRows event
        public void actionPerformed(ActionEvent e) {
            for (int i = tableModel.getRowCount() - 1; i >= 0; i--) {
                tableModel.removeRow(i);
            }
        }
    });

РЕДАКТИРОВАТЬ:

Я решил использовать AbstractTableModel, потому что у меня была такая же проблема с DefaultTableModel (всякий раз, когда я добавлял строку, она не добавлялась до тех пор, пока не была «добавлена» следующая), а с AbstractTableModel я мог бы сам запускать события изменения. Однако это ничего не исправило. Может ли кто-нибудь пролить свет на мою проблему здесь? Я был бы рад более подробно рассказать о деле, если кому-то понадобится дополнительная информация.


person Harpunius    schedule 07.07.2014    source источник


Ответы (1)


Метод

FireTableDataChanged(); 

обнаруживает любые изменения в объекте данных таблицы и соответственно обновляет графический интерфейс, вы можете попробовать это вместо

fireTableRowsInserted();
person Haris Mehmood    schedule 07.07.2014
comment
неправильное предложение, модель воссоздания fireTableDataChanged, вы можете потерять все пользовательские настройки для рендерера и редактора - person mKorbel; 07.07.2014
comment
@mKorbel Поскольку его код показывает изменения только в строках (т.е. удаление/копирование/вставка) и не редактирует данные в столбцах, я думаю, что это будет работать нормально, поскольку предполагается структура таблицы (как в порядке столбцов). быть таким же в этом методе. docs.oracle. com/javase/7/docs/api/javax/swing/table/ Если я ошибаюсь и что-то упускаю, поправьте меня. Спасибо. - person Haris Mehmood; 07.07.2014
comment
Привет @haris, спасибо за ваш ответ. Независимо от того, изменяет ли он структуру, запуск tableDataChanged() вместо вставки не сработал. - person Harpunius; 07.07.2014
comment
1. вы ошибаетесь, 2. кстати fireTableRowsInserted(); является правильным уведомителем для addRow для новой строки, вставленной в JTable, 3. ничего не удаляет из вопроса OP, в противном случае будет дан ответ (SSCCE / MCVE, короткий, исполняемый, компилируемый, с закодированным значением для XxxTableModel в локальной переменной), потому что все в этот вопрос не завершен, просто угадаю, ... - person mKorbel; 07.07.2014
comment
Я не совсем понимаю ваш третий пункт, mKorbel, не могли бы вы уточнить? - person Harpunius; 08.07.2014