You create a component and add the component to the JScrollPane
using the setRowHeaderView(...)
method.
So you might use a JList
as the component containing the values for each row.
You would also need a custom renderer so the row header is rendered like the column header.
Here is a basic example that just uses a number for each row:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class TableRowHeader extends JList implements TableModelListener
{
private JTable table;
@SuppressWarnings("unchecked")
public TableRowHeader(JTable table)
{
this.table = table;
setAutoscrolls( false );
setCellRenderer(new RowHeaderRenderer());
setFixedCellHeight(table.getRowHeight());
setFixedCellWidth(50);
setFocusable( false );
setModel( new TableListModel() );
setOpaque( false );
setSelectionModel( table.getSelectionModel() );
table.getModel().addTableModelListener( this );
}
public void tableChanged(TableModelEvent e)
{
if (e.getType() == TableModelEvent.INSERT
|| e.getType() == TableModelEvent.DELETE)
{
repaint();
}
}
/*
* Use the table to implement the ListModel
*/
class TableListModel extends AbstractListModel
{
public int getSize()
{
return table.getRowCount();
}
public Object getElementAt(int index)
{
return String.valueOf(index + 1);
}
}
/*
* Use the table row header properties to render each cell
*/
class RowHeaderRenderer extends DefaultListCellRenderer
{
RowHeaderRenderer()
{
setHorizontalAlignment(CENTER);
setOpaque(true);
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
setFont(table.getTableHeader().getFont());
setBackground(table.getTableHeader().getBackground());
setForeground(table.getTableHeader().getForeground());
}
public Component getListCellRendererComponent(
JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus)
{
if (isSelected)
{
setBackground( table.getSelectionBackground() );
}
else
{
setBackground( table.getTableHeader().getBackground() );
}
setText( (value == null) ? "" : value.toString() );
return this;
}
}
private static void createAndShowUI()
{
JTable table = new JTable( 1000, 10 );
JScrollPane scrollPane = new JScrollPane( table );
scrollPane.setRowHeaderView( new TableRowHeader( table) );
JFrame frame = new JFrame("Row Header Test");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
If you want different values in the row header then you would use your own ListModel containing the values you want displayed, instead of the TableListModel.
If you can dynamically add/remove rows of data from the TableModel, then you would need logic to also add/remove rows from the ListModel.