Upiększanie JTable
Kategoria Programowanie dn. 11 mar, 2009
Przy okazji moich zabaw ze Swingiem – krótko o tym jak ulepszyć JTable.
Mamy sobie JTable taką:

A będziemy chcieli taką:

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?
13 grudnia, 2009 o 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.
13 grudnia, 2009 o 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.
13 grudnia, 2009 o 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” :)