Add ‘count #’ column to JTable
Important note first: This is mostly not my code, I was strugling with this problem for some time, I couldn’t google it at all, and one day, I’ve just found it. Now I use it in one of my projects but I cannot find the original post again, therefore I have decided to post it on my blog (slightly modified version of the original) so other people with similar problem will have a better chance of finding the solution.
So, the idea is very simple. The whole point of displaying additional column which is kind of independent from the other columns is to simply use another table. This way you can sort one table by column and the number column will not sort with it. – thats exactly what I was looking for and I guess its kind of popular problem.
Becouse you put two tables in one scroll pane the gui looks like its just one column!
I have created one simple method to apply this technique to any tables in my application (I use JXTable actually but JTable will do as well)
JTable rowTable = new RowNumberTable(table);
scp.setRowHeaderView(rowTable);
scp.setCorner(JScrollPane.UPPER_LEFT_CORNER, rowTable.getTableHeader());
scp.repaint();
}
RowNumberTable is simple one column table displaying the ‘count’ number of rows in the second table.
implements ChangeListener, PropertyChangeListener
{
private JTable main;
public RowNumberTable(JTable table)
{
main = table;
main.addPropertyChangeListener( this );
setFocusable( false );
setAutoCreateColumnsFromModel( false );
setModel( main.getModel() );
setSelectionModel( main.getSelectionModel() );
TableColumn column = new TableColumn();
column.setHeaderValue("Lp.");
addColumn( column );
column.setCellRenderer(new RowNumberRenderer());
getColumnModel().getColumn(0).setPreferredWidth(40);
setPreferredScrollableViewportSize(getPreferredSize());
}
@Override
public void addNotify()
{
super.addNotify();
Component c = getParent();
// Keep scrolling of the row table in sync with the main table.
if (c instanceof JViewport)
{
JViewport viewport = (JViewport)c;
viewport.addChangeListener( this );
}
}
/*
* Delegate method to main table
*/
@Override
public int getRowCount()
{
if(main != null)
return main.getRowCount();
else
return 0;
}
@Override
public int getRowHeight(int row)
{
return main.getRowHeight(row);
}
/*
* This table does not use any data from the main TableModel,
* so just return a value based on the row parameter.
*/
@Override
public Object getValueAt(int row, int column)
{
return Integer.toString(row + 1);
}
/*
* Don't edit data in the main TableModel by mistake
*/
@Override
public boolean isCellEditable(int row, int column)
{
return false;
}
//
// Implement the ChangeListener
//
public void stateChanged(ChangeEvent e)
{
// Keep the scrolling of the row table in sync with main table
JViewport viewport = (JViewport) e.getSource();
JScrollPane scrollPane = (JScrollPane)viewport.getParent();
scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y);
}
//
// Implement the PropertyChangeListener
//
public void propertyChange(PropertyChangeEvent e)
{
// Keep the row table in sync with the main table
if ("selectionModel".equals(e.getPropertyName()))
{
setSelectionModel( main.getSelectionModel() );
}
if ("model".equals(e.getPropertyName()))
{
setModel( main.getModel() );
}
}
/*
* Borrow the renderer from JDK1.4.2 table header
*/
private static class RowNumberRenderer extends DefaultTableCellRenderer
{
public RowNumberRenderer()
{
setHorizontalAlignment(JLabel.CENTER);
}
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
if (table != null)
{
JTableHeader header = table.getTableHeader();
if (header != null)
{
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
}
if (isSelected)
{
setFont( getFont().deriveFont(Font.BOLD) );
}
setText((value == null) ? "" : value.toString());
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
return this;
}
}
}
In my case the ‘count’ column is called ‘Lp.’ – in polish
I have created one simple method to apply this technique to any tables in my application (I use JXTable actually but JTable will do as well)
JTable rowTable = new RowNumberTable(table);
scp.setRowHeaderView(rowTable);
scp.setCorner(JScrollPane.UPPER_LEFT_CORNER, rowTable.getTableHeader());
scp.repaint();
}
where is the project for download?
Sorry mate, no project for download here