Заголовок JTable с пользовательским рендерером по умолчанию не прокручивается внутри JScrollPane
У меня есть JTable внутри JScrollPane, внутри JTabbedPane. Заголовок таблицы прекрасно прокручивается, пока я не установлю для него пользовательский рендерер по умолчанию, который динамически изменяет ширину и высоту ячеек заголовка, т.е.
table.getTableHeader().setDefaultRenderer(new MyHeaderRenderer());
... где MyHeaderRenderer расширяет JLabel, а его метод getTableCellRendererComponent() устанавливает предпочтительный размер следующим образом:
table.getTableHeader().setPreferredSize(new Dimension(width, height));
После настройки пользовательского средства визуализации тело таблицы продолжает правильно прокручиваться, но заголовок остается зафиксированным в верхнем левом углу JScrollPane. Я считаю, что средство визуализации постоянно перерисовывает заголовок в этой позиции.
Как я мог это исправить?
Благодарю.
2 ответа
Моя проблема заключалась в том, что у меня было много столбцов с длинными текстами заголовков, поэтому я создал средство визуализации заголовков, чтобы установить высоту и ширину ячеек заголовка в соответствии с длиной текста ячейки.
Как выясняется, вы не можете изменить размер ячеек заголовка, установив предпочтительный размер самого заголовка таблицы, иначе у вас будет заголовок, всегда прикрепленный к верхнему левому углу таблицы.
По этому вопросу я не нашел решения. Я попытался установить предпочитаемый размер вне рендерера: он не работал, что означает, что проблема не в непрерывном рендеринге. Я попытался использовать JTextArea вместо JLabel: это не имело никакого значения. Я попытался переопределить метод doLayout() JTable: он не работал.
Я исправил проблему, удалив:
table.getTableHeader().setPreferredSize(new Dimension(width, height));
... и добавление этих строк кода в метод getTableCellRendererComponent():
table.getColumnModel().getColumn(column).setPreferredWidth(width); //sets the width
setPreferredSize(new Dimension(width, height)); //sets the height of the JLabel returned by the renderer
Это было лучшее, что я мог придумать. Если кто-то найдет лучшее решение, пожалуйста, поделитесь им:-)
Я столкнулся с той же проблемой и нашел обходной путь. Заголовок JTable - это отдельный компонент, который хранится в родительском JScrollPane ColumnHeader. Таким образом, вместо переопределения предпочтительного размера заголовка мы можем установить предпочтительный размер JScrollPane ColumnHeader.
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.getColumnHeader().setPreferredSize(new Dimension(0, height));
К счастью, JScrollPane игнорирует ширину заголовка столбца, поэтому вы можете смело устанавливать здесь ноль.