Java – multi row JTable unit with automatic height – very large first row

I am using swing to develop a java desktop application (JDK1.6) My question is about multiline cells (text wrapping) in JTable with the property of automatically adjusting cell height

I can already implement this structure in this way:

>Table has its own cellrenderer. > The cell is a jtextarea with wraptext = true > after inserting text into the cell, I calculate the row in the jtextarea and adjust the row height of the relevant row accordingly. > Cell width adjusts automatically (from preferred size)

Two questions about this structure:

1) During program execution, it can count rows and adjust the row height correctly

However, during the first initialization (the first setmodel ()), it calculates the number of rows in the "first cell" of the table, that is, (0,0), far exceeding it I debugged the code and found that it calculated the letters in the text and multiplied it by the line height of 16 (it seems that the width of the cell is 1 letter) Finally, I got a very high first row Any other line is OK

There is no problem when I do not insert any text into (0,0)

2) Row counting does not work when I disable the table auto size property and manually determine the cell width

This is my cell renderer:

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;

}

This is how I calculate the number of rows:

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;
}

————————————

I deleted the line adjustment code outside the class This is represented by a model listener The first line is not very big at this time Calling this method is valid, but the problem is about calculating the line of the package Every time I fill a cell with very long text, the row is wrapped correctly, but my counter returns 1 (the code of the wrapper line counter is above. It is the same as that in the renderer. But it works normally there)

This is my model audience:

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();

}

Print results:

Thanks in advance:)

ISIL

Solution

Just to get a solution immediately, even after a few years, it may help others You can set a fixed number of rows or use a dynamic row count appropriate to the content You should easily expand it in any way

package com.mycompany;

import java.awt.Component;
import java.util.List;

import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
import javax.swing.table.TableCellRenderer;

public class MultiLineCellRenderer extends JTextArea implements
TableCellRenderer {

    private static final long serialVersionUID = 1L;
    boolean                     limit               = false;

    public MultiLineCellRenderer() {
        setLineWrap(true);
        setWrapStyleWord(true);
        setOpaque(true);
        setBorder(new EmptyBorder(-1,2,-1,2));
        this.limit = false;
        setRows(1);
    }

    public MultiLineCellRenderer(int rows) {
        this();
        setRows(rows);
        this.limit = true;
    }

    @Override
    public Component getTableCellRendererComponent(JTable table,int column) {
        setText(value == null ? "" : value.toString());

        int dynamicHeight = getLineCount() > getRows() && this.limit ? getRows() : getLineCount();
        int newHeight = table.getRowHeight() * dynamicHeight;
        if (table.getRowHeight(row) != newHeight) {
            table.setRowHeight(row,newHeight);
        }

        if (isSelected) {
            setForeground(table.getSelectionForeground());
            setBackground(table.getSelectionBackground());
        }
        else {
            setForeground(table.getForeground());
            setBackground(table.getBackground());
        }

        return this;
    }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>