2009-11-23 10 views
15

In einer JTable, wie kann ich einige Zeilen automatisch die Höhe erhöhen, um den vollständigen mehrzeiligen Text darin anzuzeigen? Dies ist, wie es im Moment angezeigt:Höhe der Zeilen in einer JTable automatisch anpassen

Ich habe nicht die Höhe für alle Reihen setzen wollen, aber nur für diejenigen, die mehrzeiligen Text haben.

Antwort

32

Die einzige Möglichkeit, die Zeilenhöhe sicher zu kennen, besteht darin, jede Zelle zu rendern, um die gerenderte Höhe zu bestimmen. Nachdem Sie Ihre Tabelle mit Daten gefüllt ist, können Sie tun:

private void updateRowHeights() 
{ 
    for (int row = 0; row < table.getRowCount(); row++) 
    { 
     int rowHeight = table.getRowHeight(); 

     for (int column = 0; column < table.getColumnCount(); column++) 
     { 
      Component comp = table.prepareRenderer(table.getCellRenderer(row, column), row, column); 
      rowHeight = Math.max(rowHeight, comp.getPreferredSize().height); 
     } 

     table.setRowHeight(row, rowHeight); 
    } 
} 

Wenn nur die erste Spalte mehrzeilige enthalten können Sie nur den obigen Code für diese Spalte optimieren.

+1

Benötige ich ein Tabellenmodell dafür? – Wulf

+0

Warum ClassCastException abfangen? Es gibt keine Umwandlungen oder irgendwelche ungeprüften Operationen. –

+0

@KarlRichter, guter Punkt, nicht sicher, warum es da ist. Der Versuch/Fang wurde entfernt. – camickr

1

Sie müssen über jede Zeile iterieren, die Begrenzungsbox für jedes Element abrufen und die Höhe entsprechend anpassen. In der Standard-JTable (see this article for a solution für Java ... 1.3.1 = 8 * O) gibt es dafür keine Codeunterstützung.

1

Camickrs Lösung hat bei mir überhaupt nicht funktioniert. Mein Datenmodell war jedoch dynamisch - es änderte sich ständig. Ich denke, die erwähnte Lösung funktioniert für statische Daten, wie sie von einem Array kommen.

Ich hatte JPanel für Cell Renderer-Komponente und seine bevorzugte Größe wurde nicht korrekt nach der Verwendung von prepareRenderer (...) festgelegt. Die Größe wurde korrekt eingestellt, nachdem das umschließende Fenster bereits sichtbar war und neu gezeichnet wurde (2 Mal tatsächlich nach einer nicht spezifizierten, jedoch kurzen Zeit). Wie kann ich die updateRowHeights() -Methode aufrufen, die oben gezeigt wird und wo würde ich das tun? Wenn ich es (overrienden) Table.paint() anrief, verursachte es offensichtlich unendliche Repaints. Ich habe 2 Tage gebraucht. Buchstäblich. Die Lösung, die für mich arbeitet, ist diese (das ist der CellRenderer, den ich für meine Spalte verwendet habe):

public class GlasscubesMessagesTableCellRenderer extends MyJPanelComponent implements TableCellRenderer { 

    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, 
      int row, int column) { 
     //this method updates GUI components of my JPanel based on the model data 
     updateData(value); 
     //this sets the component's width to the column width (therwise my JPanel would not properly fill the width - I am not sure if you want this) 
     setSize(table.getColumnModel().getColumn(column).getWidth(), (int) getPreferredSize().getHeight()); 

     //I used to have revalidate() call here, but it has proven redundant 

     int height = getHeight(); 
     // the only thing that prevents infinite cell repaints is this 
     // condition 
     if (table.getRowHeight(row) != height){ 
      table.setRowHeight(row, height); 
     } 
     return this; 
    } 
} 
+1

Sie können RowHeight dynamisch wie [this] (http://stackoverflow.com/questions/21723025/how-to-set-the-rowheight-dynamically-in-a-jtable) festlegen. – GAVD

+0

Danke GAVD. Oh, das habe ich versucht;) Leider sind TableModelListeners Ereignisse Ereignisse des Tabellenmodells und nicht der Tabellen-GUI. Sie werden ausgelöst/lang/bevor sich die GUI erneut aktualisiert und GUI-Komponenten ihre Größe korrekt berechnen lassen. Sie können die Größen an diesem Punkt erzwingen (ich konnte das 2 Tage lang nicht herausfinden), aber warum sollten Sie? Das Repaint wird den Job trotzdem erledigen. Ich weiß, dass diese Lösung dreckig ist, aber nach 2 Tagen hört dein Perfektionismus auf, weißt du;) – ed22