Xis’ blog

Mój wirtualny schowek

Upiększanie JTable

Posted on | 11 marca, 2009 | 3 komentarze

Przy okazji moich zabaw ze Swingiem – krótko o tym jak ulepszyć JTable.

Mamy sobie JTable taką:

przed

A będziemy chcieli taką:

po1

Wzbogacimy więc naszą tabelkę o bardzo ładne oznaczenie numerów wierszy, oraz kolorowanie co drugiego rekordu.

Zabieg pierwszy: kolorowanie co drugiego wiersza

Aby używać warunkowego kolorowania wierszy, musimy wskazać naszej tabelce, by wykorzystała obiekt klasy pochodnej od DefaultTableCellRenderer, np. takiej:

class ColorCellRenderer extends DefaultTableCellRenderer {
 
    @Override
    public Component getTableCellRendererComponent( JTable table, Object val, boolean selected, boolean focused, int row, int col ) {
        Component comp = super.getTableCellRendererComponent( table, val, selected, focused, row, col );
        if( selected == false ) {
            if( ( row % 2 ) == 1 ) {
                comp.setBackground( color );
            }
            else {
                comp.setBackground( null );
            }
        }
        return comp;
    }
}

Zabieg drugi: numeracja wierszy

Na forum Suna znalazłem b. stary, ale nadal ciekawy przykład rozwiązania tego problemu. Budujemy klasę LineNumberTable, która dziedziczy po JTable:

public class LineNumberTable extends JTable {
    private JTable mainTable;
 
    public LineNumberTable( JTable table ) {
        super();
        mainTable = table;
        setAutoCreateColumnsFromModel( false );
        setModel( mainTable.getModel() );
        setSelectionModel( mainTable.getSelectionModel() );
        setAutoscrolls( false );
 
        addColumn( new TableColumn() );
        getColumnModel().getColumn( 0 ).setCellRenderer( mainTable.getTableHeader().getDefaultRenderer() );
        getColumnModel().getColumn( 0 ).setPreferredWidth( 30 );
        setPreferredScrollableViewportSize( getPreferredSize() );
    }
 
    @Override
    public boolean isCellEditable( int row, int column ) {
        return false;
    }
 
    @Override
    public Object getValueAt( int row, int column ) {
        return new Integer( row + 1 );
    }
 
    @Override
    public int getRowHeight( int row ) {
        return mainTable.getRowHeight();
    }
}

OK, teraz wystarczy wykorzystać utworzone klasy w naszej JTable:

    public MyPanel() {
        initComponents();
        // wskazujemy nowy renderer, dla obiektów wszystkich typów naszej tabelki
        jTable1.setDefaultRenderer( Object.class, new ColorCellRenderer() );
        // scrollPane, którym mamy osadzoną tabelę dekorujemy oznaczeniem numerów wierszy
        jScrollPane1.setRowHeaderView( new LineNumberTable( jTable1 ) );
    }

Gotowe. Prawda, że ładniej?

Comments

3 komentarze to “Upiększanie JTable”

  1. rzepcio
    13 grudnia, 2009 @ 19:59

    Jak dla mnie do usunięcia:
    setAutoCreateColumnsFromModel(false);
    W innym przypadku nie stworzą się kolumny z modelu:
    setModel(mainTable.getModel());
    Poza tym trzeba ustawić:
    getColumnModel().getColumn(0).setHeaderValue(„”);

    Ale to może wszystko w moim przypadku ;) Może się komuś przyda.

  2. rzepcio
    13 grudnia, 2009 @ 20:16

    I to:

    @Override
    public Object getValueAt(int row, int column) {
    if (column == 0)
    return new Integer(row + 1);
    else
    return super.getValueAt(row, column);
    }

    Inaczej zawsze dostaniemy przecież wartość wiersza+1.

  3. xis
    13 grudnia, 2009 @ 22:19

    Raczej nie do końca jest tak, jak napisałeś. Zauważ, że omawiana klasa LineNumberTable nie jest tym samym co mainTable (będącą zwykłą JTable), tylko jej… składnikiem. Pierwsza kolumna (ta z numerkami) to właśnie LineNumberTable.
    Zresztą, sprawdź sobie ten kod w praktyce i zobaczysz na czym polega „cały myk” :)

Leave a Reply