我正在使用 Swing 开发 Java 桌面应用程序 (jdk1.6)。我的问题是关于 JTable 中具有自动调整单元格高度属性的多行单元格(文本换行)。
我已经可以通过这种方式实现这个结构:
- 表有自己的单元格渲染器。
- 单元格是 wraptext=true 的 JTextArea
- 在将文本插入单元格后,我计算 JTextArea 中的行数,并相应地调整相关行的行高。
- 单元格宽度会自动调整。(从首选尺寸)
关于这个结构的2个问题:
1)在程序执行过程中,可以统计行数并适当调整行高。
但是在第一次初始化(第一次 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。(上面的代码是 Wrappedline 计数器。与渲染器中的相同。但在那里工作得很好)
这是我的模型监听器:
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();
}
打印线的结果:
- preferredHeight: 15 // 来自换行函数
- lineHeight: 15 // 来自换行函数
- 小时正常:25
- 行数:1
- value:looooooooooooooooooooooonng tessssssssssssssssssssssst // 看起来是 2 行
- 宽度:104
提前致谢 :)
伊西尔