Jtable automatyczna wysokość komórki

0

Witam,

Mam tabelkę, wczytuję tekst do komórek używając jTextArea ponieważ tekst musi być podzielony na linie. Mam problem z automatycznym ustawieniem wysokości komórki. Znalazłem taki kod:

private void updateRowHeights()
{
    try
    {
        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);
        }
    }
    catch(ClassCastException e) {}
}
 

Niestety nie działa najlepiej, wysokości są zbyt wielkie.

0

Zmieniłem

int rowHeight = table.getRowHeight();

na logiczniejsze moim zdaniem

int rowHeight = 0;

i działa bardzo dobrze (windows, wszystkie dostępne skórki). Oryginalny kod też działa dobrze.
Sprawdź czy w jakiejś komórce nie masz pustych wierszy na końcu, na wszelki wypadek "trimuj" w metodzie getValueAt().

0

Sytuacja wygląda tak:

Po wczytaniu danych do komórki...

user image

Po zastosowaniu metody aktualizującej wysokość..

user image

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        
DefaultTableModel model = (DefaultTableModel) jTable1.getModel();

model.addRow(new Object[]{"Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies. Curabitur et ligula. Ut molestie a, ultricies porta urna. Vestibulum commodo volutpat a, convallis ac, laoreet enim. Phasellus fermentum in, dolor. Pellentesque facilisis. Nulla imperdiet sit amet magna. Vestibulum dapibus, mauris nec malesuada fames ac turpis velit, rhoncus eu, luctus et interdum adipiscing wisi. "});

jTable1.getColumnModel().getColumn(0).setCellRenderer(new TextAreaRenderer());
        
}

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        updateRowHeights();
}
   
private void updateRowHeights()
{
    try
    {
        for (int row = 0; row < jTable1.getRowCount(); row++)
        {
            int rowHeight = 0;
 
            for (int column = 0; column < jTable1.getColumnCount(); column++)
            {
                Component comp = jTable1.prepareRenderer(jTable1.getCellRenderer(row, column), row, column);
                rowHeight = Math.max(rowHeight, comp.getPreferredSize().height);
            }
 
            jTable1.setRowHeight(row, rowHeight);
        }
    }
    catch(ClassCastException e) {}
}

public class TextAreaRenderer extends JTextArea
    implements TableCellRenderer {

  public TextAreaRenderer() {
    setLineWrap(true);
    setWrapStyleWord(true);
  }

  public Component getTableCellRendererComponent(JTable jTable,
      Object obj, boolean isSelected, boolean hasFocus, int row,
      int column) {
    setText((String)obj);
    return this;
  }
}
0

Dziwne, u Ciebie długi tekst w komórce tabeli sam się podzielił na wiersze? Ja mam troszkę inny kod. Jeśli wstawię do komórki długi tekst, to wygląda tak: user image, a jak podzielę ten tekst na wiersze, to tak: user image

0

Może tak będzie prościej namierzyć błąd.. oto mój projekt z netbeans https://www.dropbox.com/s/jtgs9rthm5oqsu6/tabelka.zip

0

Czy Twój długi tekst będzie podzielony na wiersze? Ja inaczej definiuję renderera. Mój renderer dobrze ustala rozmiar, ale nie dzieli tekstu na wiersze, Twój na odwrót.

class TextAreaRenderer implements TableCellRenderer
{
    public Component getTableCellRendererComponent(JTable t,Object value,boolean selected,boolean hasFocus,int row,int col)
    {
        String s = value.toString();
        JTextArea ta = new JTextArea(s);
        ta.setLineWrap(true);
        ta.setWrapStyleWord(true);
        return ta;
    }
}
0

Zmieniłem renderer na Twój, efekt jest teraz nieco inny ale nadal nie taki jak być powinien. https://www.dropbox.com/s/jtgs9rthm5oqsu6/tabelka.zip

0

Napisałem

Czy Twój długi tekst będzie podzielony na wiersze? Ja inaczej definiuję renderera. Mój renderer dobrze ustala rozmiar, ale nie dzieli tekstu na wiersze

0

Jak wyłączę zawijanie wierszy to działa OK, ale wiersz jest tak długi że nie mieści się cały w wąskiej komórce. Natomiast gdy wiersz się zawija to jest kicha.
Jak sam przełamię wiersz przez np. \n to działa... wysokość jest ładnie dostosowywana.

0

Jeżeli samemu się będzie tekst dzielić na wiersze po przez naciśnięcie enter'a to OK ale gdy wiersz będzie za długi na szerokość komórki to niestety się nie wyświetli w całości przy wyłączonym zawijaniu.

0

Nie ma nikt pomysłu jak sobie z tym poradzić? Może jakoś na podstawie ilości znaków oraz szerokości komórki wyliczać jej wysokość?

0

Spróbuj coś takiego ( u mnie działa dobrze).

class CellRenderer extends JTextArea implements TableCellRenderer
{
    public Component getTableCellRendererComponent(JTable t,Object value,boolean selected,boolean hasFocus,int row,int col)
    {
        String s = value.toString();
        JTextArea ta = new JTextArea(s.length()/60,10);
        ta.setText(s);
        ta.setLineWrap(true);
        ta.setWrapStyleWord(true);
        setText(s); 
        return ta;
    }
}

60 to w przybliżeniu ilość znaków, które się zmieszczą w wierszu. Druga stała (10) nie ma chyba żadnego znaczenia - trzeba ja podać. bo konstruktor wymaga podania ilości wierszy i kolumn.

0

Już prawie, jeszcze jest problem gdy zrobi się ręcznie koniec linii enterem gdzieś w tekście.

0

To może wyrzucaj entery

.replaceAll("\n","").replaceAll("\r\n","");

1 użytkowników online, w tym zalogowanych: 0, gości: 1