If you have a really large JTable, you might sometimes want to "freeze" the first column, or the first X columns, so that they do not scroll with the rest of the table. It is quite easy to do so. All you have to do is create a second JTable with the data you want to freeze and use it as the row header view on your scroll pane. I have wrapped this functionality up, in a class called FrozenTablePane
to which you provide a JTable and the number of columns to freeze.
/**
* A ScrollPane which "freezes" the specified number of
* columns of a JTable.
*
* @author fahdshariff
*
*/
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;
public class FrozenTablePane extends JScrollPane{
public FrozenTablePane(JTable table, int colsToFreeze){
super(table);
TableModel model = table.getModel();
//create a frozen model
TableModel frozenModel = new DefaultTableModel(
model.getRowCount(),
colsToFreeze);
//populate the frozen model
for (int i = 0; i < model.getRowCount(); i++) {
for (int j = 0; j < colsToFreeze; j++) {
String value = (String) model.getValueAt(i, j);
frozenModel.setValueAt(value, i, j);
}
}
//create frozen table
JTable frozenTable = new JTable(frozenModel);
//remove the frozen columns from the original table
for (int j = 0; j < colsToFreeze; j++) {
table.removeColumn(table.getColumnModel().getColumn(0));
}
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
//format the frozen table
JTableHeader header = table.getTableHeader();
frozenTable.setBackground(header.getBackground());
frozenTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
frozenTable.setEnabled(false);
//set frozen table as row header view
JViewport viewport = new JViewport();
viewport.setView(frozenTable);
viewport.setPreferredSize(frozenTable.getPreferredSize());
setRowHeaderView(viewport);
setCorner(JScrollPane.UPPER_LEFT_CORNER, frozenTable.getTableHeader());
}
}
Hi Fahd,
ReplyDeleteI was trying to use your class example and it works great. The only problem is that i can't get the frozen columns header.
I mean, i see the 3 columns frozen (without col header) and the rest of the columns scrolleable (just like i wanted it). Am i doing something bad?? why i can't see the frozen column's header??
Thanks in advance
Hi Fahd,
ReplyDeleteIs there anyway I can Freeze first two rows and Columns at the same time ?
I did come across a number of examples for freezing either rows or columns. I am not sure how to have both in a single table.
Thank you
Pradeep