Code: package main; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.GridLayout; public class TableSortDemo extends JPanel { // private boolean DEBUG = false; public TableSortDemo() { super(new GridLayout(1, 0)); JTable table = new JTable(new MyTableModel()){ public Component prepareRenderer (TableCellRenderer renderer,int Index_row, int Index_col) { Component comp = super.prepareRenderer(renderer, Index_row, Index_col); //even index, selected or not selected if (Index_row % 2 == 0 && !isCellSelected(Index_row, Index_col)) { comp.setBackground(Color.lightGray); } else { comp.setBackground(Color.white); } return comp; } }; table.setPreferredScrollableViewportSize(new Dimension(500, 70)); table.setFillsViewportHeight(true); table.setAutoCreateRowSorter(true); // Create the scroll pane and add the table to it. JScrollPane scrollPane = new JScrollPane(table); // Add the scroll pane to this panel. add(scrollPane); } class MyTableModel extends AbstractTableModel { private String[] columnNames = { "First Name", "Last Name", "Sport", "# of Years", }; private Object[][] data = { { "Kathy", "Smith", "Snowboarding", new Integer(5) }, { "John", "Doe", "Rowing", new Integer(3) }, { "Sue", "Black", "Knitting", new Integer(2) }, { "Jane1", "White", "Speed reading", new Integer(20) }, { "Jane2", "White", "Speed reading", new Integer(20) }, { "Jane3", "White", "Speed reading", new Integer(20) }, { "Jane4", "White", "Speed reading", new Integer(20) }, { "Jane5", "White", "Speed reading", new Integer(20) }, { "Jane6", "White", "Speed reading", new Integer(20) }, { "Jane7", "White", "Speed reading", new Integer(20) }, { "Jane8", "White", "Speed reading", new Integer(20) }, { "Jane9", "White", "Speed reading", new Integer(20) }, { "Jane10", "White", "Speed reading", new Integer(20) }, { "Jane11", "White", "Speed reading", new Integer(20) }, { "Jane12", "White", "Speed reading", new Integer(20) }, { "Jane13", "White", "Speed reading", new Integer(20) }, { "Jane14", "White", "Speed reading", new Integer(20) }, { "Joe15", "Brown", "Pool", new Integer(10) } }; public int getColumnCount() { return columnNames.length; } public int getRowCount() { return data.length; } public String getColumnName(int col) { return columnNames[col]; } public Object getValueAt(int row, int col) { return data[row][col]; } /* * JTable uses this method to determine the default renderer/ editor for * each cell. If we didn't implement this method, then the last column * would contain text ("true"/"false"), rather than a check box. */ public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); } /* * Don't need to implement this method unless your table's editable. */ public boolean isCellEditable(int row, int col) { // Note that the data/cell address is constant, // no matter where the cell appears onscreen. if (col < 2) { return false; } else { return true; } } /* * Don't need to implement this method unless your table's data can * change. */ public void setValueAt(Object value, int row, int col) { // if (DEBUG) { // System.out.println("Setting value at " + row + "," + col // + " to " + value // + " (an instance of " // + value.getClass() + ")"); // } data[row][col] = value; // Normally, one should call fireTableCellUpdated() when // a value is changed. However, doing so in this demo // causes a problem with TableSorter. The tableChanged() // call on TableSorter that results from calling // fireTableCellUpdated() causes the indices to be regenerated // when they shouldn't be. Ideally, TableSorter should be // given a more intelligent tableChanged() implementation, // and then the following line can be uncommented. // fireTableCellUpdated(row, col); // if (DEBUG) { // System.out.println("New value of data:"); // printDebugData(); // } } } /** * Create the GUI and show it. For thread safety, this method should be * invoked from the event-dispatching thread. */ private static void createAndShowGUI() { // Create and set up the window. JFrame frame = new JFrame("TableSortDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Create and set up the content pane. TableSortDemo newContentPane = new TableSortDemo(); newContentPane.setOpaque(true); // content panes must be opaque frame.setContentPane(newContentPane); // Display the window. frame.pack(); frame.setVisible(true); } public static void main(String[] args) { // Schedule a job for the event-dispatching thread: // creating and showing this application's GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } }