devxlogo

JTable Headers

JTable Headers

Question:
I would like to add an icon to the header of a column of a JTable indicating the direction the column is currently sorted.

Answer:
It can be pretty tough for even a Java programmer experienced with Swing to figure out how to change the rendering of column headers. The key is that the TableColumn class is responsible forstoring all the physical attributes of JTable columns. Among those attributes is included the renderer for the column header, which is just a TableCellRenderer instance. Once you know this, all you have to do is get the JTable’s TableColumnModel with getTableColumnModel(),fetch the TableColumn for the column whose header you want to alter with getColumn(), and set the header renderer for that TableColumn using setHeaderRenderer(). It’s not the easiest thing to figure out, but once you know how to do it, it’s not that hard to do.

Rather than include extraneous code that demonstrates sorting (which can be found in the Swing example code), I will show you only how to change the icon displayed in the label each time the label is clicked by the mouse.

import com.sun.java.swing.*;import com.sun.java.swing.table.*;import java.awt.*;import java.awt.event.*;class HeaderRenderer extends DefaultTableCellRenderer {  private int __column;  private TableCellRenderer __defaultRenderer;  HeaderRenderer(TableColumn column) {    __defaultRenderer = column.getHeaderRenderer();    __column = column.getModelIndex();  }  public Component getTableCellRendererComponent(		 JTable table, Object value, boolean isSelected,		 boolean hasFocus, int row, int column){    if(column == __column)      return this;    return __defaultRenderer.getTableCellRendererComponent(	   table, value, isSelected, hasFocus, row, column);  }}public final class JTableHeaderIcon extends JFrame {  private static final String[] __COLUMNS = {    "Beowulf", "Location"  };  private static final String[][] __DATA = {    { "Wiglaf", "Goddard Space Flight Center" },    { "Hrothgar", "Goddard Space Flight Center" },    { "Wealhtheow", "California Institute of Technology" },    { "Naegling", "California Institute of Technology" },    { "Avalon", "Los Alamos National Laboratory" },    { "Loki", "Los Alamos National Laboratory" },    { "LoBos", "National Institutes of Health" },    { "Hyglac", "Jet Propulsion Laboratory" },    { "Megalon", "Sandia National Laboratories" }  };  private JTable __table;  private JScrollPane __scrollPane;  private Icon __upIcon, __downIcon;  public JTableHeaderIcon() {    super("JTableHeaderIcon Demo");    TableColumnModel model;    TableColumn column;    JTableHeader header;    MouseAdapter headerListener;    TableCellRenderer renderer;    final HeaderRenderer label;    Component component;    __table = new JTable(__DATA, __COLUMNS);    __scrollPane = new JScrollPane(__table);    setContentPane(__scrollPane);    __upIcon   = new ImageIcon("up.gif");    __downIcon = new ImageIcon("down.gif");    model  = __table.getColumnModel();    column = model.getColumn(0);    renderer = column.getHeaderRenderer();    component =      renderer.getTableCellRendererComponent(__table, null, false,					     false, 0, 0);    label = new HeaderRenderer(column);    label.setText(__COLUMNS[0]);    label.setIcon(__upIcon);    label.setHorizontalAlignment(JLabel.LEFT);    label.setHorizontalTextPosition(JLabel.RIGHT);    label.setBackground(component.getBackground());    label.setForeground(component.getForeground());    label.setFont(component.getFont());    if(component instanceof JComponent) {      label.setBorder(((JComponent)component).getBorder());    }    column.setHeaderRenderer(label);    headerListener = new MouseAdapter() {      private boolean __up = true;      public void mouseClicked(MouseEvent e) {	int col;	TableColumnModel columnModel = __table.getColumnModel();	col = columnModel.getColumnIndexAtX(e.getX());	col = __table.convertColumnIndexToModel(col);	if(e.getClickCount() == 1 && col == 0) {	  if(__up)	    label.setIcon(__downIcon);	  else	    label.setIcon(__upIcon);	  __up = !__up;	}      }    };          header = __table.getTableHeader();    header.addMouseListener(headerListener);  }  public static void main(String[] args) {    Frame frame;    WindowListener exitListener;    exitListener = new WindowAdapter() {      public void windowClosing(WindowEvent e) {	Window window = e.getWindow();	window.setVisible(false);	window.dispose();	System.exit(0);      }    };    frame = new JTableHeaderIcon();    frame.addWindowListener(exitListener);    frame.pack();    frame.setVisible(true);  }}
devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist