Java 具有自动高度的多行JTable单元格-超大第一行
我正在用Swing开发一个Java桌面应用程序(jdk1.6)。我的问题是关于JTable中具有自动调整单元格高度属性的多行单元格(文本换行) 我已经可以通过以下方式实现此结构:Java 具有自动高度的多行JTable单元格-超大第一行,java,swing,jtable,multiline,tablecellrenderer,Java,Swing,Jtable,Multiline,Tablecellrenderer,我正在用Swing开发一个Java桌面应用程序(jdk1.6)。我的问题是关于JTable中具有自动调整单元格高度属性的多行单元格(文本换行) 我已经可以通过以下方式实现此结构: 表有自己的cellrenderer 单元格为JTextArea,wraptext=true 在将文本插入单元格后,我计算JTextArea中的行数,并相应地调整相关行的行高 单元格宽度将自动调整。(来自首选尺寸) 关于这一结构的2个问题: 1) 在程序执行过程中,它可以正确地计算行数和调整行高 但在第一次初始化(f
- 表有自己的cellrenderer
- 单元格为JTextArea,wraptext=true
- 在将文本插入单元格后,我计算JTextArea中的行数,并相应地调整相关行的行高
- 单元格宽度将自动调整。(来自首选尺寸)
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;
------------------------------------
我将行调整代码移到了类的外部。该表现在有一个模型侦听器。第一排在这个时候不是很大。调用此方法是可行的,但问题是如何计算包裹的行。每次我用很长的文本填充单元格时,行被正确包装,但我的计数器返回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();
公共类ModelListener实现TableModelListener{
JTable主表;
JTable-depTable;
公共模型侦听器(JTable m,JTable d){
主表=m;
depTable=d;
}
公共模型侦听器(JTM表){
主表=m;
depTable=null;
}
公共作废表已更改(TableModelEvent tme){
int fRow=tme.getFirstRow();
int col=tme.getColumn();
JTextArea=(JTextArea)mainTable.getDefaultRenderer(Object.class);
int numOfLines=getWrappedLines(cerellea);//countLines();
int height_normal=mainTable.getRowHeight(fRow);
System.out.println(“h正常:+高度正常”);
System.out.println(“numLines:+numOfLines”);
System.out.println(“值:”+mainTable.getModel().getValueAt(fRow,col));
System.out.println(“宽度:+ceralea.getPreferredSize().width”);
if(depTable==null)
{
如果(高度_正常值
}
打印行的结果:
- preferredHeight:15//来自换行函数
- 线宽:15//from wrapped lines函数
- h正常值:25
- 数字:1
- 值:loooooooooooooooooooooong tesssssssssssssssst//似乎是两行
- 宽度:104
Isil现在就有解决方案在手,即使几年后,它可能会帮助其他一些人。您可以设置固定的行数或使用适合内容的动态行数。您可以以任何方式扩展它
package.com.mycompany;
导入java.awt.Component;
导入java.util.List;
导入javax.swing.JTable;
导入javax.swing.JTextArea;
导入javax.swing.border.EmptyBorder;
导入javax.swing.table.TableCellRenderer;
公共类MultilecellRenderer扩展了JTextArea实现
TableCell渲染器{
私有静态最终长serialVersionUID=1L;
布尔极限=假;
公共多容器渲染器(){
setLineWrap(真);
setWrapStyleWord(true);
set不透明(true);
新订单(新的空订单(-1,2,-1,2));
此.limit=false;
设置行(1);
}
公共多行渲染器(int行){
这个();
设置行(行);
this.limit=true;
}
@凌驾
公共组件GetTableCellRenderComponent(JTable表、对象值、,
布尔值(已选择,布尔值为焦点,整数行,整数列){
setText(value==null?“:value.toString());
int dynamicHeight=getLineCount()>getRows()&&this.limit?getRows():getLineCount();
int newHeight=table.getRowHeight()*动态灯光;
if(table.getRowHeight(row)!=newHeight){
表.setRowHeight(行,新高度);
}
如果(当选){
setForeground(table.getSelectionForeground());
挫折背景(table.getSelectionBackground());
}
否则{
set前台(table.get前台());
挫折背景(table.getBackground());
}
归还这个;
}
}
没有调查你的问题,只是:不要(就像“从来没有”一样)从渲染器内部更改表的状态。相反,将大小调整逻辑移到其他位置:循环表的行,使用值准备渲染器,查询其首选大小/换行线,并根据设置行高JTextArea是否认为它只有一行高,而不设置J的宽度TextArea,您将永远无法确定它应该有多高。但是宽度是自动设置的,并且这个问题只发生在相关表的(0,0)索引中,尽管所有单元格都派生自具有相同属性的相同类。我还记得将单元格宽度设置为固定值(很抱歉,该项目不再开发)没有任何帮助。@kleopatra您介意解释一下原因吗?@isilpekel我一直在测试您的代码,当您遵循时问题就消失了
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();