Почему мой JTable CellRenderer работает все время?
-
13-10-2019 - |
Вопрос
// вопрос новичка
У меня есть JTable с почти базовым средством визуализации ячеек (оно по-другому окрашивает строку).Я заметил, что мой инструмент визуализации ячеек постоянно работает для строк, которые отображаются на экране, даже когда я ничего не делаю с таблицей.
Неужели так и должно быть?Разве он не должен был отрисовывать каждую ячейку один раз, и все?Как я могу остановить это и пересчитывать только при изменении?
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
log.debug("Building cell : " + row + "," + column);
Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Filter filter = (Filter)table.getModel().getValueAt(row, Column.CLASSIFICATION.getIndex());
comp.setBackground(filter.getColor());
return comp;
}
Решение
Я работал много с JTables, содержащим много данных. Больше, чем 99,9% программистов Java обычно манипулируют. Есть одна вещь, которую вам нужно знать: по умолчанию есть безумное количество созданных отходов и безумное количество обычно выполняемой ненужной операции.
Если вы хотите быстро и эффективно JTables, то есть а авторитетная статья Sun по этому вопросу:
«Приложения для рождественской елки, как создавать часто обновления JTables, которые работают хорошо»
Обратите внимание на "Это хорошо работает" В названии, потому что по умолчанию Jtable Perfs действительно, действительно патетически плохие:
После внедрения двух или трех методов, предоставленных в этой статье, вы заметите удивительное ускорение в вашем рендеринге JTable, и вы заметите, что генерируется гораздо меньше мусора (и, следовательно, GC необходимо носить все реже).
Другие советы
После предложения @steve McLeod я начал создавать пример кода с той же ошибкой, и только тогда я понял, что внутри одного из моих мобильных
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
log.debug("Building a list for " + row + "," + column);
setListData(((Vector<String>)value).toArray());
setToolTipText("This is a tool tip for " + row + "," + column);
table.setRowHeight(row, Math.max(1, getPreferredSize().height));
Filter filter = (Filter)table.getModel().getValueAt(row, Column.CLASSIFICATION_RESULT.getIndex());
setBackground(filter.getColor());
return this;
}
У меня была линия:
table.setRowHeight(row, Math.max(1, getPreferredSize().height));
И он постоянно менял линию строки, в то время как другие визуализаторы в одной линии делали то же самое ... поэтому они постоянно стреляли друг в друга.
Я заметил, что вы меняете внешний вид ячейки в зависимости от значения другой ячейки.Если эта связь работает в обоих направлениях - внешний вид ячейки 1 основан на появлении ячейки 2 и наоборот, вы можете столкнуться с такой проблемой.Но на самом деле нам нужен автономный пример кода, который воспроизводит проблему, иначе мы можем снимать только в темноте.
рендер уже кэширует ваш визуализированный компонент, когда ничего не изменится
Однако, когда таблица обнаружит, что что-то могло изменить, это запрашивает повторное использование. Событие, которое запускает его больше всего, является движением мыши.
Так что да, это нормальное поведение для JTable.