Почему автоматическая настройка высоты строки не работает в Jtable

Я реализовал updateRowHeights, метод для автоматической регулировки высоты строк в Jtable, но он не работает, хотя мой код до сих пор работает нормально. Я что-нибудь забыл? (см.: Автоматическая настройка высоты строк в JTable)

вот мой код:

import javax.swing.*;
import java.awt.*;

public class ExampleTable {
JTable textTable;

public JPanel createTable() {               
    JPanel totalGUI = new JPanel();

    //define titles for table
    String[] title = {"TITLE1", "TITLE2", "TITLE3"};

    //table data
    Object[][] playerdata = {       
    {new Integer(34), "Steve", "test test test"},
    {new Integer(32), "Patrick", "du hu hu hu hu hu hu hu uh u kkkkkk oooo pppp"},
    {new Integer(10), "Sarah", "xxxxxxxxxxxxx aaaaaaaaaa bbbbbbbbbbbbb dddddddddddd xxxxxxx gggewr  eeeeeeeeee ddd g fffffff zzzzzzz"},};

    //create object 'textTable'
    textTable = new JTable(playerdata,title);

    //set column width
    textTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 
    textTable.getColumnModel().getColumn(0).setPreferredWidth(45);
    textTable.getColumnModel().getColumn(1).setPreferredWidth(45);
    textTable.getColumnModel().getColumn(2).setPreferredWidth(200);
    textTable.setDefaultRenderer(String.class, new RowHeightCellRenderer());

    //adjust dynamically the Row height of each cell
    updateRowHeights();

    //put line breaks if string is longer than cell-width
    RowHeightCellRenderer dynRow = new RowHeightCellRenderer();
    textTable.getColumnModel().getColumn(2).setCellRenderer(dynRow);
    System.out.println(textTable.getPreferredSize().height);

    //scrollbar
    JScrollPane scrollPane = new JScrollPane(textTable);

    totalGUI.add(scrollPane);               
    return totalGUI;
}

private void updateRowHeights() {

    /* 
     * Auto adjust the height of rows in a JTable.
     * The only way to know the row height for sure is to render each cell 
     * to determine the rendered height. After your table is populated with 
     * data you can do:         
     *  
     */        
    for (int row = 0; row < textTable.getRowCount(); row++) {
        int rowHeight = textTable.getRowHeight();
        for (int column = 0; column < textTable.getColumnCount(); column++)
        {
            Component comp = textTable.prepareRenderer(textTable.getCellRenderer(row, column), row, column);
            System.out.println("Row: "+row+" Column: "+column+ " preferredHeight: "+comp.getPreferredSize().height);
            rowHeight = Math.max(rowHeight, comp.getPreferredSize().height);
            System.out.println("Row: "+row+" Column: "+column+ " RowHeight: "+rowHeight);
        }
        textTable.setRowHeight(row, rowHeight);
    }
}

private static void createAndShowGUI() {

    //create main frame
    JFrame mainFrame = new JFrame("");
    ExampleTable test = new ExampleTable();
    JPanel totalGUI = new JPanel();
    totalGUI = test.createTable();

    //visible mode
    mainFrame.add(totalGUI); //integrate main panel to main frame
    mainFrame.pack();
    mainFrame.setVisible(true);     
}


public static void main (String[] args) {               

    createAndShowGUI();     

}//main
}

import java.awt.*;
    import javax.swing.*;
    import javax.swing.table.*;

А вот и RowHeightCellRenderer:

    public class RowHeightCellRenderer extends JTextArea implements TableCellRenderer
    {
      /**
         * 
         */
        private static final long serialVersionUID = 1L;

    public Component getTableCellRendererComponent (JTable table, 
                                                    Object value, 
                                                    boolean isSelected, 
                                                    boolean hasFocus, 
                                                    int row, 
                                                    int column )  {
          this.setText((String)value);
          this.setLineWrap(true); //line break if String longer than the cell width
        return this;
      }
    }

Спасибо заранее!!

1 ответ

Посмотрите на свой код:

updateRowHeights();

//put line breaks if string is longer than cell-width
RowHeightCellRenderer dynRow = new RowHeightCellRenderer();
textTable.getColumnModel().getColumn(2).setCellRenderer(dynRow);

Вы обновляете высоту строки и устанавливаете средство визуализации ячейки впоследствии. Таким образом, метод обновления, очевидно, не может использовать предполагаемый визуализатор ячеек. Изменить порядок:

//put line breaks if string is longer than cell-width
RowHeightCellRenderer dynRow = new RowHeightCellRenderer();
textTable.getColumnModel().getColumn(2).setCellRenderer(dynRow);

updateRowHeights();

Вы должны убедиться, что все свойства, которые влияют на внешний вид ячеек, настроены перед вычислением и применением полученной высоты ячейки.


Другая проблема заключается в том, что концепция макета AWT, т.е. getPreferredSize(), не очень хорошо подходит для концепции переноса слов, когда вам нужно запросить "предпочтительную высоту при заданной фактической ширине". Вы должны взаимодействовать с текстовым API Swing для выполнения такого запроса:

private void updateRowHeights() {
    final TableColumnModel columnModel = textTable.getColumnModel();
    Insets i=null;
    for(int row = 0; row < textTable.getRowCount(); row++) {
        int rowHeight = textTable.getRowHeight();
        for(int column = 0; column < textTable.getColumnCount(); column++) {
            Component comp = textTable.prepareRenderer(
                textTable.getCellRenderer(row, column), row, column);
            final int height;
            if(comp instanceof JTextComponent) {
                final JTextComponent tc = (JTextComponent)comp;
                final View rootView = tc.getUI().getRootView(tc);
                i=tc.getInsets(null);
                rootView.setSize(columnModel.getColumn(column)
                    .getPreferredWidth()-i.left-i.right,
                    Integer.MAX_VALUE);
                height=(int)rootView.getPreferredSpan(View.Y_AXIS);
            }
            else height = comp.getPreferredSize().height;
            rowHeight = Math.max(rowHeight, height);
        }
        textTable.setRowHeight(row, rowHeight);
    }
}
Другие вопросы по тегам