Я разрабатываю Java-приложение для настольного компьютера (jdk1.6) с Swing. Моя проблема связана с многострочными ячейками (перенос текста) с автоматической настройкой свойства высоты ячейки в JTable.
Я уже мог реализовать эту структуру следующим образом:
- У таблицы есть свой cellrenderer.
- Ячейки являются JTextArea с wraptext = true
- Я подсчитываю строки в JTextArea после вставки текста в ячейку и соответствующим образом корректирую высоту строки связанной строки.
- Ширина ячейки регулируется автоматически. (от предпочтительного размера)
2 проблемы об этой структуре:
1) Во время выполнения программы она может считать строки и корректно регулировать высоту строк.
Но при первой инициализации (first setModel ()) он вычисляет количество строк «первой ячейки» таблицы, т. Е. (0,0), гораздо больше, чем есть. Я отладил код и обнаружил, что он считает буквы в тексте и умножается на высоту строки 16. (как будто ширина ячейки была 1 буква). В конце я получаю очень очень высокий первый ряд. Другие строки в порядке.
Когда я не вставляю текст в (0,0), никаких проблем не возникает.
2) Количество строк не работает, когда я отключаю свойство автоматического изменения размера таблицы и определяю ширину ячейки вручную.
Вот мой рендерер клеток:
public class MultiLineCellRenderer extends JTextArea implements TableCellRenderer {
private JTable DependentTable;
public MultiLineCellRenderer() {
DependentTable=null;
setLineWrap(true);
setWrapStyleWord(true);
setOpaque(true);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
(...) //some background color adjustments
setText((value == null) ? "" : value.toString());
int numOfLines = getWrappedLines(this); // Counting the lines
int height_normal = table.getRowHeight(row);// read the height of the row
if(DependentTable == null) // for this case always null
{
if (height_normal < numOfLines*16)
{
table.setRowHeight(row,numOfLines*16);
}
}
else
(...)
return this;
}
Вот как я вычисляю количество строк:
public static int getWrappedLines(JTextArea component)
{
View view = component.getUI().getRootView(component).getView(0);
int preferredHeight = (int)view.getPreferredSpan(View.Y_AXIS);
int lineHeight = component.getFontMetrics( component.getFont() ).getHeight();
return preferredHeight / lineHeight;
}
------------------------------------
Я удалил код корректировки строк снаружи класса. Теперь в таблице есть модель слушателя. Первый ряд не очень большой в это время. Вызов этого метода работает, но проблема заключается в подсчете обернутых строк. Каждый раз, когда я заполняю ячейку очень длинным текстом, строка переносится правильно, но мой счетчик возвращает 1. (код счетчика обернутой строки выше. Тот же, что и в рендерере. Но там он работал нормально)
вот мой модельный слушатель:
public class ModelListener implements TableModelListener {
JTable mainTable;
JTable depTable;
public ModelListener(JTable m, JTable d) {
mainTable = m;
depTable = d;
}
public ModelListener(JTable m){
mainTable = m;
depTable = null;
}
public void tableChanged(TableModelEvent tme) {
int fRow = tme.getFirstRow();
int col = tme.getColumn();
JTextArea cellArea = (JTextArea)mainTable.getDefaultRenderer(Object.class);
int numOfLines = getWrappedLines(cellArea); //countLines();
int height_normal = mainTable.getRowHeight(fRow);
System.out.println("h normal:"+height_normal);
System.out.println("numLines:"+numOfLines);
System.out.println("value:"+mainTable.getModel().getValueAt(fRow, col));
System.out.println("width:"+cellArea.getPreferredSize().width);
if(depTable == null)
{
if (height_normal < numOfLines*16)
{
mainTable.setRowHeight(fRow,numOfLines*16);
}
}
else
{
//(---)
}
mainTable.repaint();
}
Результат печати строк:
- предпочитаемыйВысота: 15 // из функции обернутых строк
- lineHeight: 15 // из функции обернутых строк
- ч, нормальный: 25
- numLines: 1
- value: looooooooooooooooooooooonng tesssssssssssssssssssssssst // выглядит как 2 строки
- ширина: 104
Заранее спасибо:)
Isil