Какой идиоматический способ (если есть) обновить (перерисовать) строку в JTable?

#java #swing #jtable

#java #swing #jtable

Вопрос:

У меня есть экземпляры JTable, которые прослушивают некоторые удаленные события, и в зависимости от типа события я хочу заблокировать / разблокировать строку с индексом модели N. Под блокировкой строки я подразумеваю установку редактируемого флага для всех ее ячеек на false. Это обрабатывается моей табличной моделью.

На данный момент я звоню repaint() , потому что я не хотел, чтобы моя табличная модель запускала событие updated, что является другой альтернативой, но у меня сложная логика, которая возникает при изменении фактических данных в строке, и я не хотел запускать эту логику.

Есть ли другой способ?

Комментарии:

1. кому нужно знать, изменена ли редактируемость? Или наоборот: зачем вам перерисовка? И где / почему / как вы вызываете перерисовку? Основная проблема (как вы уже обнаружили) заключается в том, что уведомление об изменениях в метаданных вообще не поддерживается.

2. Ну, пользователям нужно «видеть», что строка заблокирована, поэтому они не пытаются изменить какую-либо ячейку и расстраиваются, увидев, что она недоступна для редактирования. 🙂 Мне нужно перерисовать после изменения флага редактируемости для всех ячеек в «заблокированной» строке. В данный момент я пытаюсь запустить функцию fireTableChanged() с помощью TableModelEvent типа 7 и посмотрю, смогу ли я заставить таблицу реагировать на нее так, как мне нужно.

3. да, это то, что я предположил — но вы все еще не ответили, где вы вызываете перерисовку 🙂 В любом случае, в SwingX я бы заставил пользовательскую табличную модель запускать какое-то пользовательское событие, какой-то слушатель этого пользовательского события, который обновляет highlightпредикат Highlighter для включения / выключения визуальной подсказки для возможности редактирования. Поскольку JXTable прослушивает свои маркеры, он автоматически обновляется по мере необходимости 🙂

4. Ах, извините… Я вызываю перерисовку в обработчике событий. Когда мой наблюдатель получает уведомление о том, что запись должна быть заблокирована, я устанавливаю флаги так, чтобы MyTableModel.isCellEditable() возвращал false , и после этого я вызываю repaint() . Все это работает хорошо, но у меня есть внутреннее ощущение, что это не лучший способ сделать это… Я имею в виду очень похожий подход к тому, что вы описали выше! 🙂

Ответ №1:

Изменения должны быть внесены непосредственно в TableModel . Затем TableModel вызовет соответствующий fireXXX() метод, и таблица автоматически перерисует затронутые строки.

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

Комментарии:

1. Это именно то, что я делаю. Проблема в том, что единственное событие, которое я могу запустить (что имеет смысл), — это событие update . Почему-то кажется логичным связать событие обновления с фактическим обновлением ДАННЫХ, а не с редактируемым состоянием отдельных ячеек…