На самом деле JTextArea уже реализует все функции, необходимые для динамического изменения высоты по ширине. Эту функциональность можно увидеть в действии, когда JTextArea используется внутри ScrollPane, где его высота автоматически настраивается в соответствии с шириной ScrollPane. Чтобы использовать эту функцию, нужно сначала установить размер JTextArea на некоторую ширину, а затем JTextArea # getPreferredSize() вернет требуемую высоту для отображения текста (если для обхода строки установлено значение true).
Таким образом, чтобы динамически изменять высоту строки JTable на основе его ширины, можно сделать следующее:
- Добавить пользовательский TableCellRenderer в таблицу, которая возвращает JTextArea в TableCellRenderer # getTableCellRendererComponent()
- Слушайте изменения размера столбцов, как описано здесь: Java JTable detect Column re-sized by user
- Обновить высоту строк столбцов, как описано здесь: Auto adjust the height of rows in a JTable
- Во время обновления высоты строки, один calcula TES требуемый размер JTextArea сначала установив новую ширину, а затем получить предпочтительную высоту, как показано в следующем фрагменте кода
Обновить функцию высоты строки:
public static void updateRowHeights(int column, int width, JTable table){
for (int row = 0; row < table.getRowCount(); row++) {
int rowHeight = table.getRowHeight();
Component comp = table.prepareRenderer(table.getCellRenderer(row, column), row, column);
Dimension d = comp.getPreferredSize();
// first set the size to the new width
comp.setSize(new Dimension(width, d.height));
// then get the preferred size
d = comp.getPreferredSize();
rowHeight = Math.max(rowHeight, d.height);
// finally set the height of the table
table.setRowHeight(row, rowHeight);
}
}
При таком подходе, дальнейшие вычисления количеств или строк не требуются.
Вот полный код примера примера OP, скорректированный на эту реализацию.
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class ExampleTable {
public class RowHeightCellRenderer extends JTextArea implements TableCellRenderer {
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column) {
setEditable(false);
setLineWrap(true);
setWrapStyleWord(true);
if (isSelected) {
setBackground(table.getSelectionBackground());
setForeground(table.getSelectionForeground());
} else {
setBackground(table.getBackground());
setForeground(table.getForeground());
}
setText(value.toString());
return this;
}
}
public static void updateRowHeights(int column, int width, JTable table){
for (int row = 0; row < table.getRowCount(); row++) {
int rowHeight = table.getRowHeight();
Component comp = table.prepareRenderer(table.getCellRenderer(row, column), row, column);
Dimension d = comp.getPreferredSize();
comp.setSize(new Dimension(width, d.height));
d = comp.getPreferredSize();
rowHeight = Math.max(rowHeight, d.height);
table.setRowHeight(row, rowHeight);
}
}
public JPanel createTable() {
JPanel totalGUI = new JPanel();
//define titles for table
final String[] columnNames = {"TITLE1", "TITLE2", "TITLE3"};
//table data
final Object[][] rowData = {
{new Integer(34), "Steve", "test test test"},
{new Integer(32), "Patrick", "dumdi dumdi dummdi dumm di di didumm"},
{new Integer(10), "Sarah", "blabla bla bla blabla bla bla blabla"},};
AbstractTableModel model = new AbstractTableModel() {
@Override
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
public String getColumnName(int column) { return columnNames[column].toString(); }
public int getRowCount() { return rowData.length; }
public int getColumnCount() { return columnNames.length; }
public Object getValueAt(int row, int col) { return rowData[row][col]; }
public boolean isCellEditable(int row, int column) { return true; }
public void setValueAt(Object value, int row, int col) {
rowData[row][col] = value;
fireTableCellUpdated(row, col);
}
};
//create object 'textTable'
final JTable textTable = new JTable();
textTable.setDefaultRenderer(String.class, new RowHeightCellRenderer());
textTable.setModel(model);
//set column width
textTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
textTable.getColumnModel().getColumn(0).setPreferredWidth(60);
textTable.getColumnModel().getColumn(1).setPreferredWidth(60);
ColumnListener cl = new ColumnListener(){
@Override
public void columnMoved(int oldLocation, int newLocation) {
}
@Override
public void columnResized(int column, int newWidth) {
updateRowHeights(column, newWidth, textTable);
}
};
textTable.getColumnModel().addColumnModelListener(cl);
textTable.getTableHeader().addMouseListener(cl);
// initial update of row heights
TableColumn c = textTable.getColumnModel().getColumn(2);
updateRowHeights(2, c.getWidth(), textTable);
//scrollbar
JScrollPane scrollPane = new JScrollPane(textTable);
totalGUI.add(scrollPane);
return totalGUI;
}
private static void createAndShowGUI() {
//create main frame
JFrame mainFrame = new JFrame("");
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ExampleTable test = new ExampleTable();
JPanel totalGUI = new JPanel();
totalGUI = test.createTable();
//visible mode
mainFrame.add(totalGUI); //integrate main panel to main frame
mainFrame.pack();
mainFrame.setVisible(true);
}
public static void main (String[] args) {
createAndShowGUI();
}//main
abstract class ColumnListener extends MouseAdapter implements TableColumnModelListener {
private int oldIndex = -1;
private int newIndex = -1;
private boolean dragging = false;
private boolean resizing = false;
private int resizingColumn = -1;
private int oldWidth = -1;
@Override
public void mousePressed(MouseEvent e) {
// capture start of resize
if(e.getSource() instanceof JTableHeader) {
JTableHeader header = (JTableHeader)e.getSource();
TableColumn tc = header.getResizingColumn();
if(tc != null) {
resizing = true;
JTable table = header.getTable();
resizingColumn = table.convertColumnIndexToView(tc.getModelIndex());
oldWidth = tc.getPreferredWidth();
} else {
resizingColumn = -1;
oldWidth = -1;
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
// column moved
if(dragging && oldIndex != newIndex) {
columnMoved(oldIndex, newIndex);
}
dragging = false;
oldIndex = -1;
newIndex = -1;
// column resized
if(resizing) {
if(e.getSource() instanceof JTableHeader) {
JTableHeader header = (JTableHeader)e.getSource();
TableColumn tc = header.getColumnModel().getColumn(resizingColumn);
if(tc != null) {
int newWidth = tc.getPreferredWidth();
if(newWidth != oldWidth) {
columnResized(resizingColumn, newWidth);
}
}
}
}
resizing = false;
resizingColumn = -1;
oldWidth = -1;
}
@Override
public void columnAdded(TableColumnModelEvent e) {
}
@Override
public void columnRemoved(TableColumnModelEvent e) {
}
@Override
public void columnMoved(TableColumnModelEvent e) {
// capture dragging
dragging = true;
if(oldIndex == -1){
oldIndex = e.getFromIndex();
}
newIndex = e.getToIndex();
}
@Override
public void columnMarginChanged(ChangeEvent e) {
}
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
}
public abstract void columnMoved(int oldLocation, int newLocation);
public abstract void columnResized(int column, int newWidth);
}
}
Обратите внимание, что я повторно и изменил часть кода из Java JTable detect Column re-sized by user и Auto adjust the height of rows in a JTable.
Я вижу «RowCellRender». Можем ли мы увидеть этот класс. Я думаю, вы можете быть на правильном пути с этим. –
спасибо, мой код - всего лишь пример, а ширина столбца имеет фиксированный размер. Поэтому Rowheight должен автоматически настраиваться – Ramses
Остерегайтесь: решение @ peeskillet ** неправильно ** в настройке таблицы rowHeight в рендерере! Вместо этого прослушайте все изменения, которые могут потребовать корректировки и изменить его там. – kleopatra