Compilable source can be found at: http://www.splashcd.com/jtable.tar
I\'m new to the language, so I\'m not sure if this is acceptable behavior or not.
I cre
The problem seems to stem from having JTable's setRowHeight() inside the custom cell renderer, as it calls the custom cell renderer, throwing it into an infinite loop.
I had to add in a check to see if the current row height matched the calculated word wrapped row height. If it did, I didnt try to setRowHeight() again.
Corrected Code:
import java.awt.Component;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.table.TableCellRenderer;
//custom cell renderer for word wrapping, but if you use, you have to
//implement zebra striping functionality which the default renderer has
public class LineWrapCellRenderer extends JTextArea implements TableCellRenderer
{
private int numOfTimesCalled;
@Override
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column)
{
System.out.println("Line Wrap Cell Renderer Called: " + numOfTimesCalled++);
System.out.println("row:"+ row + ", col:" + column);
//set up the row size based on the number of newlines in the text in the cell
int fontHeight = this.getFontMetrics(this.getFont()).getHeight();
int numWraps = value.toString().split("\r\n|\r|\n").length;
int rowHeight = fontHeight * numWraps;
//if the calculated rowHeight is the same as the row height of row,
// then don't call setRowHeight again, as doing so will throw us into
// an infinite loop
if(rowHeight != table.getRowHeight(row))
{
table.setRowHeight(row, rowHeight);
//configure word wrapping
setWrapStyleWord(true);
setLineWrap(true);
//use the table's font
setFont(table.getFont());
}
//zebra striping, because whatever cell uses this renderer loses the
//default cell renderer zebra striping
if(isSelected)
{
setBackground(table.getSelectionBackground());
}
else
{
if(row%2 == 1)
{
setBackground(UIManager.getColor("Table.alternateRowColor"));
}
else
{
setBackground(table.getBackground());
}
}
this.setText(value.toString());
return this;
}
}
To get the most performance out of a TableCellRenderer
, make sure you're not creating a new instance of a component every time getTableCellRenderer
is called. Make the components once and save them as fields of the class.
Also, you'll want to make sure each of the Components you use have the following methods overridden to do nothing:
(and you probably want to hard code isOpaque
).
For more information see: http://docs.oracle.com/javase/6/docs/api/javax/swing/tree/DefaultTreeCellRenderer.html
aaaaach
you need doLayout()
,
next level :-), then there you can to set Maximum visible row
s for JTextComponents
too, with little effort
doLayout()
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.*;
//http://tips4java.wordpress.com/2008/10/26/text-utilities/
public class AutoWrapTest {
public JComponent makeUI() {
String[] columnNames = {" Text Area Cell Renderer "};
Object[][] data = {
{"123456789012345678901234567890"},
{"ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdx"},
{"----------------------------------------------0"},
{">>>>>>>>>>>>>ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffffffd"
+ "ffffdffffddxffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdd"
+ "ffffdffffdffffffffdx>>>>>>>>>>>>>>>>>>>>>>>>>|"},
{">>>>>>>>>>>>ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffd"
+ "ffffdffffdx>>>>>>>>>>>>>>>>>>>>>>>>>>|"},
{"a|"},
{">>>>>>>>bbbb>>>>>>>>>>>>>>>>>>>|"},
{">>>>>>>>>>>>>>>>>>|"},
{">>>>>>>>>>>>>ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffffffd"
+ "ffffdffffddxffffdffffdffffdffffffffd123456789012345678901234567890ffffdffffd"
+ "ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffddx>>>>>>>>>>>>>>>>>>>>"
+ ">>>>>|"},
{">>>>>>>>>>>>>ffffdffffdffffdffffffffd123456789012345678901234567890ffffdffffd"
+ "ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffddxffffdffffdffffdffffffffd123456"
+ "789012345678901234567890ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdd"
+ "ffffffffd123456789012345678901234567890ffffddx>>>>>>>>>>>>>>>>>>"
+ ">>>>>>>|"},};
TableModel model = new DefaultTableModel(data, columnNames) {
private static final long serialVersionUID = 1L;
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
JTable table = new JTable(model) {
private static final long serialVersionUID = 1L;
@Override
public void doLayout() {
TableColumn col = getColumnModel().getColumn(0);
for (int row = 0; row < getRowCount(); row++) {
Component c = prepareRenderer(col.getCellRenderer(), row, 0);
if (c instanceof JTextArea) {
JTextArea a = (JTextArea) c;
int h = getPreferredHeight(a) + getIntercellSpacing().height;
if (getRowHeight(row) != h) {
setRowHeight(row, h);
}
}
}
super.doLayout();
}
private int getPreferredHeight(JTextComponent c) {
Insets insets = c.getInsets();
View view = c.getUI().getRootView(c).getView(0);
int preferredHeight = (int) view.getPreferredSpan(View.Y_AXIS);
return preferredHeight + insets.top + insets.bottom;
}
};
table.setEnabled(false);
table.setShowGrid(false);
table.setTableHeader(null);
table.getColumnModel().getColumn(0).setCellRenderer(new TextAreaCellRenderer());
//table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane sp = new JScrollPane(table);
sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
sp.setPreferredSize(new Dimension(250, 533));
JPanel p = new JPanel(new BorderLayout());
p.add(sp);
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new AutoWrapTest().makeUI());
f.setLocation(100, 100);
f.pack();
f.setVisible(true);
}
}
class TextAreaCellRenderer extends JTextArea implements TableCellRenderer {
private static final long serialVersionUID = 1L;
private final Color evenColor = new Color(230, 240, 255);
public TextAreaCellRenderer() {
super();
setLineWrap(true);
setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (isSelected) {
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
} else {
setForeground(table.getForeground());
setBackground(table.getBackground());
setBackground((row % 2 == 0) ? evenColor : getBackground());
}
setFont(table.getFont());
setText((value == null) ? "" : value.toString());
return this;
}
}