Arv*_*dan 31 java swing jtable
我正在尝试实现本教程中描述的自定义TableRenderer .我想让渲染器换行包装给定单元格的每个文本.这个想法是,使用TextArea作为渲染器,因为它支持换行.但是,以下代码的行为不符合预期:
public class LineWrapCellRenderer extends JTextArea implements TableCellRenderer {
@Override
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
this.setText((String)value);
this.setWrapStyleWord(true);
this.setLineWrap(true);
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
我用这个渲染器设置了
table.setDefaultRenderer(String.class, new LineWrapCellRenderer());
Run Code Online (Sandbox Code Playgroud)
但是细胞条目仍未解开.如果我添加this.setBackground(Color.YELLOW)到该getTableCellRendererComponent()方法,所有单元格都按预期为黄色,但未包装.
有任何想法吗?
更新:正如Michael Borgwardt在评论中所述,问题不在于换行,而是行高:JTables行是固定大小的,所以如果单元格越来越高(因为文本现在是多行的),我们必须增加行高.但是多少钱?我会检查这是否值得另一个SO问题.如果没有,我会在这里添加此解决方案.
Update2:以下代码将确定行高(如果放入getTableCellRendererComponent()):
int fontHeight = this.getFontMetrics(this.getFont()).getHeight();
int textLength = this.getText().length();
int lines = textLength / this.getColumns() +1;//+1, cause we need at least 1 row.
int height = fontHeight * lines;
table.setRowHeight(row, height);
Run Code Online (Sandbox Code Playgroud)
Mic*_*rdt 11
问题是JTable中行的高度是固定的,所以它不仅仅是一个包装渲染器的问题; 我不确定它为什么没有,但如果确实如此,那么包装好的文字会被裁剪掉 - 或许这正是你所看到的.要调整行高,您需要单独设置它们.
您好我遇到了同样的问题,但我实施的解决方案的灵感来自Java Tutorial提供的用于绘制多行文本的示例,并使用文本API在单元格上绘制文本.
http://java.sun.com/docs/books/tutorial/2d/text/drawmulstring.html
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextLayout;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.BreakIterator;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
public class MultilineTableCell
implements TableCellRenderer {
class CellArea extends DefaultTableCellRenderer {
/**
*
*/
private static final long serialVersionUID = 1L;
private String text;
protected int rowIndex;
protected int columnIndex;
protected JTable table;
protected Font font;
private int paragraphStart,paragraphEnd;
private LineBreakMeasurer lineMeasurer;
public CellArea(String s, JTable tab, int row, int column,boolean isSelected) {
text = s;
rowIndex = row;
columnIndex = column;
table = tab;
font = table.getFont();
if (isSelected) {
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
}
}
public void paintComponent(Graphics gr) {
super.paintComponent(gr);
if ( text != null && !text.isEmpty() ) {
Graphics2D g = (Graphics2D) gr;
if (lineMeasurer == null) {
AttributedCharacterIterator paragraph = new AttributedString(text).getIterator();
paragraphStart = paragraph.getBeginIndex();
paragraphEnd = paragraph.getEndIndex();
FontRenderContext frc = g.getFontRenderContext();
lineMeasurer = new LineBreakMeasurer(paragraph,BreakIterator.getWordInstance(), frc);
}
float breakWidth = (float)table.getColumnModel().getColumn(columnIndex).getWidth();
float drawPosY = 0;
// Set position to the index of the first character in the paragraph.
lineMeasurer.setPosition(paragraphStart);
// Get lines until the entire paragraph has been displayed.
while (lineMeasurer.getPosition() < paragraphEnd) {
// Retrieve next layout. A cleverer program would also cache
// these layouts until the component is re-sized.
TextLayout layout = lineMeasurer.nextLayout(breakWidth);
// Compute pen x position. If the paragraph is right-to-left we
// will align the TextLayouts to the right edge of the panel.
// Note: this won't occur for the English text in this sample.
// Note: drawPosX is always where the LEFT of the text is placed.
float drawPosX = layout.isLeftToRight()
? 0 : breakWidth - layout.getAdvance();
// Move y-coordinate by the ascent of the layout.
drawPosY += layout.getAscent();
// Draw the TextLayout at (drawPosX, drawPosY).
layout.draw(g, drawPosX, drawPosY);
// Move y-coordinate in preparation for next layout.
drawPosY += layout.getDescent() + layout.getLeading();
}
table.setRowHeight(rowIndex,(int) drawPosY);
}
}
}
public Component getTableCellRendererComponent(
JTable table, Object value,boolean isSelected, boolean hasFocus, int row,int column
)
{
CellArea area = new CellArea(value.toString(),table,row,column,isSelected);
return area;
}
}
Run Code Online (Sandbox Code Playgroud)
它也会调整行高度,但只有当此渲染器用于单个列时才能很好地完成.
这是我以前调用它来渲染我的表的方式.
final int wordWrapColumnIndex = ...;
myTable = new JTable() {
public TableCellRenderer getCellRenderer(int row, int column) {
if (column == wordWrapColumnIndex ) {
return wordWrapRenderer;
}
else {
return super.getCellRenderer(row, column);
}
}
};
Run Code Online (Sandbox Code Playgroud)