How can I show up and down icons in the table header to visualize the sort order and sorted column of a sorted table?

Thomas Auinger

The general approach to provide sorting for a table can be found in FAQ entry http://www.jguru.com/jguru/faq/view.jsp?EID=39959.

Still, it would be nice to have some sort of indication, which table column is responsible for the sorting and in which order the sort has been done (ascending or descending). Many applications use a up or down arrow icon, which is displayed in the table header cell of the sorted column.

The general idea is to provide an implementation of the TableCellRenderer interface. The following code shows such an implementation:

class TableHeadRenderer extends JButton implements TableCellRenderer {
    public static ImageIcon ICON_DESCENDING_ORDER = null;
    public static ImageIcon ICON_NO_ORDER;
    public static ImageIcon ICON_ASCENDING_ORDER;
    public int sortingOrder = 0;

    /** Creates a renderer to paint a table column's header and initializes
      * the static image variables the first time an instance is created.
    public TableHeadRenderer() {

        // Table headers ALWAYS display the text centered, therefor we can
        // set this property already in the constructor.
        // If images are not loaded, use ImageLoader to load image-icons.
        if(ICON_DESCENDING_ORDER==null) {
            ICON_DESCENDING_ORDER = new ImageIcon( "images/ScrollUpArrow.gif" );
            ICON_NO_ORDER = null;
            ICON_ASCENDING_ORDER = new ImageIcon( "images/ScrollDownArrow.gif" );

    /** Returns a configured component, which will be used to paint the table
      * header.
    public Component getTableCellRendererComponent( JTable table,
                                                    Object value,
                                                    boolean isSelected,
                                                    boolean hasFocus,
                                                    int row,
                                                    int column) {

        // Try to set default fore- and background colors                                                        
        if(table!=null) {                                                        
            JTableHeader header = table.getTableHeader();
            if(header!=null) {
        // Set header text                
        String columnTitle = (value==null) ? "" : value.toString();
        this.setText( columnTitle );            
        // set normal border
        // set icon            
        return this;

The shown implementation provides external access to the member attribute sortingOrder, which stores the sort order for the header's column.

Next, we need a table that a) sets the new renderer for the table header and b) provides a method, which allows for setting the sorted column index and the sort order:

public class MyTable extends JTable {
    /** If model changes, we have to set the header renderers.
    public void setModel(TableModel model) {
        // One renderer for each column
        TableColumn tc;
        for(int i=0; i<model.getColumnCount(); i++) {
            tc = this.getColumnModel().getColumn(i);
                tc.setHeaderRenderer(new TableHeadRenderer());
    /** Allow setting of sorted column index and sort order.
      * @param column Index of sorted column (or -1 if unsorted)
      * @param order The sort order  (-1 descending, 0 unsorted, 1 ascending)
    public void setSortedColumnAndOrder(int column, int order) {
        TableHeadRenderer   thr;
        TableColumn         tc;
        // Unset existing sorted column 
        if(sortedColumn != -1) {
            tc = this.getColumnModel().getColumn(sortedColumn);
            if(tc!=null) {
                thr = (TableHeadRenderer) tc.getHeaderRenderer();
                thr.sortingOrder = 0;

        // Store sort infos
        this.sortedColumn = column;
        this.sortOrder = order;
        // Set new sort infos
        tc = this.getColumnModel().getColumn(sortedColumn);
        if(tc!=null) {
            thr = (TableHeadRenderer) tc.getHeaderRenderer();
            thr.sortingOrder = order;