JTable не обновляется в fireTableChanged - PullRequest
0 голосов
/ 30 января 2019

У нас довольно сложная модель в JTable.В новой разработке я заметил, что GUI не обновляется, когда я вызываю fireTableChanged (...) для отдельных ячеек.
Итак, мой вопрос:
Что я помещаю в TableModelEvent - идентификатор или представление строки моделиидентификатор строки?

Просмотр кода JTable (у меня есть jdk1.8.0_202):

public class JTable extends JComponent implements TableModelListener, Scrollable,
...
    public void tableChanged(TableModelEvent e) {
...
        int modelColumn = e.getColumn();
        int start = e.getFirstRow();
        int end = e.getLastRow();

        Rectangle dirtyRegion;
        if (modelColumn == TableModelEvent.ALL_COLUMNS) {
            // 1 or more rows changed
            dirtyRegion = new Rectangle(0, start * getRowHeight(),
                                        getColumnModel().getTotalColumnWidth(), 0);
        }
        else {
            // A cell or column of cells has changed.
            // Unlike the rest of the methods in the JTable, the TableModelEvent
            // uses the coordinate system of the model instead of the view.
            // This is the only place in the JTable where this "reverse mapping"
            // is used.
            int column = convertColumnIndexToView(modelColumn);
            dirtyRegion = getCellRect(start, column, false);
        }

Я вижу, что для вычисления грязной области она преобразует столбециндекс, но не делает то же самое для строки.
Что означает комментарий "обратное отображение"?
Похоже, ошибка в Swing для меня.
Что вы думаете?

ОБНОВЛЕНИЕ
Мой код прост:

model.fireTableChanged(new TableModelEvent(model, rowNumber, rowNumber, columnNumber));

GUI НЕ обновляет ячейку.

ОБНОВЛЕНИЕ2
Проблема вмоя модель, которая слишком сложна, чтобы разместить ее здесь.: (

Я не могу винить JTable. Он спроектирован таким образом. Единственное возможное дополнение к нему - RowSorter, и там он делает правильное преобразование:

    private void repaintSortedRows(ModelChange change) {
...
        int modelIndex = change.startModelIndex;
        while (modelIndex <= change.endModelIndex) {
            int viewIndex = convertRowIndexToView(modelIndex++);
            if (viewIndex != -1) {
                Rectangle dirty = getCellRect(viewIndex, columnViewIndex,
                                              false);
                int x = dirty.x;
                int w = dirty.width;
                if (eventColumn == TableModelEvent.ALL_COLUMNS) {
                    x = 0;
                    w = getWidth();
                }
                repaint(x, dirty.y, w, dirty.height);
            }
        }
    }

Спасибо всемИзвините за беспокойство.

1 Ответ

0 голосов
/ 30 января 2019

Мой код прост:

model.fireTableChanged(new TableModelEvent(model, rowNumber, rowNumber, columnNumber));

Это не то, как вы меняете данные в JTable.Вы НЕ должны вызывать этот метод напрямую.TableModel отвечает за вызов этого метода при изменении данных.

Смысл использования TableModelListener заключается в прослушивании изменений в TableModel.Вам нужно реализовать прослушиватель, только если вы хотите выполнить специальную обработку ПОСЛЕ того, как изменились данные, как я продемонстрировал по ссылке, указанной в моем комментарии.

Если у вас есть данные в существующей ячейке, и вы хотите изменитьтогда его значение может сделать что-то вроде:

model.setValueAt("new value", 0, 0);

Если вы хотите добавить новую строку данных, которую вы используете:

model.addRow(...);

Дело в том, что все изменения должны быть сделаны через TableModel.

Обратите внимание, что JTable также имеет удобный метод setValueAt (...), который вызовет модель для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...