#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 . Почему-то кажется логичным связать событие обновления с фактическим обновлением ДАННЫХ, а не с редактируемым состоянием отдельных ячеек…