2016-12-23 4 views
0

В основном: мой JTable хочет специальные высоты строк для каждой строки. Каждый используемый визуализатор записывает запрошенную высоту строки для каждой ячейки в карту в таблице, таблица имеет метод updateRowHeights, который использует карту для установки высот строк. Проблема в том, что карта с высотой строки заполняется только высотой рендерером. Следовательно, при первом отображении таблицы карта все еще пуста. Поэтому, когда таблица отображается в первый раз, когда высота строки не задана.Вызывается метод после JTable: есть ли событие onRenderFinished?

Как непродолжительное обходное решение, я добавил слушателя компонентов в таблицу, которая обновляет высоту строки. Это работает отлично в большинстве случаев, но, к примеру, он не вызывается, когда таблица живет в scrollpane внутри tabbedpane. Предпочтительно у меня был бы метод onRenderingFinished или что-то в этом роде, в котором я могу вызвать метод высот.

Я делаю что-то вроде первого ответа How to set the RowHeight dynamically in a JTable. Там упоминается, что вы не должны изменять значения столбцов таблицы в рендерере (я согласен с этим) и что «вы его установили (вызов updateRowHeight) после завершения инициализации и всякий раз, когда какое-либо из состояний, от которых оно зависит, изменилось «.

Так что мой вопрос: где/когда я звоню updateRowHeight?

Есть ли событие, которое сообщает мне, что средство визуализации закончено?

ответ

2

Если вы хотите обновить высоту строки таблицы, зависящую от самой высокой высоты ячейки, вам нужно будет вызвать этот метод только после того, как будет установлено содержимое таблицы.

public static void updateRowHeight(JTable table, int margin) { 
    final int rowCount = table.getRowCount(); 
    final int colCount = table.getColumnCount(); 
    for (int i = 0; i < rowCount; i++) { 
     int maxHeight = 0; 
     for (int j = 0; j < colCount; j++) { 
      final TableCellRenderer renderer = table.getCellRenderer(i, j); 
      maxHeight = Math.max(maxHeight, table.prepareRenderer(renderer, i, j).getPreferredSize().height); 
     } 
     table.setRowHeight(i, maxHeight + margin); 
    } 
} 

Margin - необязательный параметр, обеспечивающий дополнительное пространство для каждой строки (может быть 0 или положительным).

Обратите внимание: этот метод может вызвать проблемы с производительностью, когда таблица очень большая и/или содержит много строк HTML.

+0

Это прекрасное обходное решение. Однако, работая с JTextArea в качестве базы (вместо JLabel), метод getPreferredSize() работает не так, как ожидалось, и метод, который я использую вместо этого, не очень быстрый (в таблице строк 20000 разница составляет несколько секунд). Во-вторых, метод updateRowHeight также должен вызываться после сортировки таблицы другим столбцом. В моем случае обновление строк в некоторых компонентах и ​​предварительное вычисление высот в рендерере быстрее _much_. (это уродливо, хотя ... и когда ячейки меняются, способ componentEvent становится непригодным). –

+0

Кроме того, существует так много мест, где это нужно вызывать, если это не естественно после рендеринга (например, когда строки добавляются, удаляются, изменяются , сортировка). Поскольку это решение не очень эффективно по времени, оно, к сожалению, не решает мою проблему (даже в случае, когда нет ячейки JTextArea). –

+0

Пожалуйста, предоставьте [SSCCE] (http://sscce.org), чтобы я мог понять вашу проблему. И, конечно же, с JTextArea этот подход не может работать, потому что JTextArea требует, по крайней мере, фиксированной ширины, чтобы определить его высоту. Вы можете использовать метки HTML для небольших таблиц или панелей с составом простых текстовых меток для больших таблиц. –