
A JTable with all column headers customized with a same renderer

A JTable with multi renderers for different column headers
Basically we create a custom renderer by writing a class that implements the TableCellRender interface and extends a Swing component (e.g. JLabel) like this:public class SimpleHeaderRenderer extends JLabel implements TableCellRenderer {
public SimpleHeaderRenderer() {
// code to initilize the GUI...
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
// code to customize the GUI based on the parameters
return this;
}
}Then we set this renderer for all column headers in the table like this:table.getTableHeader().setDefaultRenderer(new SimpleHeaderRenderer());Or set this renderer for a specific column, e.g. the 3rd column in this example:
table.getColumnModel().getColumn(2).setHeaderRenderer(new SimpleHeaderRenderer());Now let’s see how to create tables with custom renderers that look like the above screenshots.
package net.codejava.swing.jtable;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
/**
* A simple renderer class for JTable component.
* @author www.codejava.net
*
*/
public class SimpleHeaderRenderer extends JLabel implements TableCellRenderer {
public SimpleHeaderRenderer() {
setFont(new Font("Consolas", Font.BOLD, 14));
setForeground(Color.BLUE);
setBorder(BorderFactory.createEtchedBorder());
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
setText(value.toString());
return this;
}
} Code of a demo program, JTableHeaderRendererSimple.java:package net.codejava.swing.jtable;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
/**
* A Swing program demonstrates how to use a custom renderer for
* all column headers of a JTable component.
* @author www.codejava.net
*
*/
public class JTableHeaderRendererSimple extends JFrame {
private JTable table;
public JTableHeaderRendererSimple(){
super("JTable Column Header Custom Renderer Basic");
// constructs the table
String[] columnNames = new String[] {"Title", "Author", "Publisher", "Published Date", "Pages", "Rating"};
String[][] rowData = new String[][] {
{"Effective Java", "Joshua Bloch", "Addision-Wesley", "May 08th 2008", "346", "5"},
{"Thinking in Java", "Bruce Eckel", "Prentice Hall", "Feb 26th 2006", "1150", "4"},
{"Head First Java", "Kathy Sierra & Bert Bates", "O'Reilly Media", "Feb 09th 2005", "688", "4.5"},
};
table = new JTable(rowData, columnNames);
table.getTableHeader().setDefaultRenderer(new SimpleHeaderRenderer());
add(new JScrollPane(table));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(640, 150);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new JTableHeaderRendererSimple().setVisible(true);
}
});
}
}Output when running the demo program:
package net.codejava.swing.jtable;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
/**
* A simple renderer class for JTable component.
* @author www.codejava.net
*
*/
public class DefaultHeaderRenderer extends JLabel implements TableCellRenderer {
public DefaultHeaderRenderer() {
setFont(new Font("Consolas", Font.BOLD, 14));
setOpaque(true);
setForeground(Color.WHITE);
setBackground(Color.BLACK);
setBorder(BorderFactory.createEtchedBorder());
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
setText(value.toString());
return this;
}
} Code of the renderer class for the “Won” column header, WonHeaderRenderer.java:package net.codejava.swing.jtable;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
/**
* A simple renderer class for JTable component.
* @author www.codejava.net
*
*/
public class WonHeaderRenderer extends JLabel implements TableCellRenderer {
public WonHeaderRenderer() {
setFont(new Font("Consolas", Font.BOLD, 14));
setOpaque(true);
setForeground(Color.WHITE);
setBackground(Color.BLUE);
setBorder(BorderFactory.createEtchedBorder());
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
setText(value.toString());
return this;
}
} Code of the renderer class for the “Drawn” column header, DrawnHeaderRenderer.java:package net.codejava.swing.jtable;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
/**
* A simple renderer class for JTable component.
* @author www.codejava.net
*
*/
public class DrawnHeaderRenderer extends JLabel implements TableCellRenderer {
public DrawnHeaderRenderer() {
setFont(new Font("Consolas", Font.BOLD, 14));
setOpaque(true);
setForeground(Color.BLACK);
setBackground(Color.YELLOW);
setBorder(BorderFactory.createEtchedBorder());
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
setText(value.toString());
return this;
}
} Code of the renderer class for the “Lost” column header, LostHeaderRenderer.java:package net.codejava.swing.jtable;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
/**
* A simple renderer class for JTable component.
* @author www.codejava.net
*
*/
public class LostHeaderRenderer extends JLabel implements TableCellRenderer {
public LostHeaderRenderer() {
setFont(new Font("Consolas", Font.BOLD, 14));
setOpaque(true);
setForeground(Color.WHITE);
setBackground(Color.GRAY);
setBorder(BorderFactory.createEtchedBorder());
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
setText(value.toString());
return this;
}
} Code of a demo program, JTableHeaderMultiRenderers.java:package net.codejava.swing.jtable;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
/**
* A Swing program demonstrates how to use multi custom renderers for
* column headers of a JTable component.
* @author www.codejava.net
*
*/
public class JTableHeaderMultiRenderers extends JFrame {
private JTable table;
public JTableHeaderMultiRenderers() {
super("JTable Column Header Multi Custom Renderers");
// constructs the table
String[] columnNames = new String[] {"Position", "Team", "Won", "Drawn", "Lost", "Points"};
String[][] rowData = new String[][] {
{"1", "Manchester United", "28", "5", "5", "89"},
{"2", "Manchester City", "23", "9", "6", "78"},
{"3", "Chelsea", "22", "9", "7", "75"},
{"4", "Arsenal", "21", "10", "7", "73"},
};
table = new JTable(rowData, columnNames);
table.getTableHeader().setDefaultRenderer(new DefaultHeaderRenderer());
table.getColumnModel().getColumn(2).setHeaderRenderer(new WonHeaderRenderer());
table.getColumnModel().getColumn(3).setHeaderRenderer(new DrawnHeaderRenderer());
table.getColumnModel().getColumn(4).setHeaderRenderer(new LostHeaderRenderer());
add(new JScrollPane(table));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(640, 150);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new JTableHeaderMultiRenderers().setVisible(true);
}
});
}
}Output when running the demo program:
package net.codejava.swing.jtable;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
/**
* A simple renderer class for JTable component, but keep the sort icons.
* @author www.codejava.net
*
*/
public class KeepSortIconHeaderRenderer implements TableCellRenderer {
private TableCellRenderer defaultRenderer;
public KeepSortIconHeaderRenderer(TableCellRenderer defaultRenderer) {
this.defaultRenderer = defaultRenderer;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Component comp = defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (comp instanceof JLabel) {
JLabel label = (JLabel) comp;
label.setFont(new Font("Consolas", Font.BOLD, 14));
label.setForeground(Color.BLUE);
label.setBorder(BorderFactory.createEtchedBorder());
}
return comp;
}
} The trick here is to update the default renderer (which is usually a JLabel instance) instead of returning a completely new JLabel component. Code to use this renderer is as follows:JTableHeader header = table.getTableHeader(); header.setDefaultRenderer(new KeepSortIconHeaderRenderer(header.getDefaultRenderer()));
TableColumn column = table.getColumnModel().getColumn(2); column.setHeaderRenderer(new KeepSortIconHeaderRenderer(table.getTableHeader().getDefaultRenderer()));
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.