Tuesday, August 4, 2009

Custom JTable Cell Renderer (Part 1)

If the data is not a supported type, or if not all the cells in a single column is of the same type, then you will need to write a custom renderer for your JTable.

JTable asks the renderer's getTableCellRendererComponent() what kind of display component each cell should look like in the course of painting the table. Note that the JTable does not actually place a JComponent in each cell. Instead, each cell simply visually mimics the JComponent returned by getTableCellRendererComponent() by painting it in the cell.

For example, if getTableCellRendererComponent() returns a JLabel, then the attributes of that JLabel is used to paint the cell so that the cell looks like a JLabel (but is not really one). In other words, the JLabel is simply used like a data structure to pass information. For this reason, it is important that getTableCellRendererComponent() should not create a new component with each call. For example, the default JTable renderer, DefaultTableCellRenderer (an extension of JLabel), always returns itself when its getTableCellRendererComponent() is called.

In order to display a different "component" in each cell, the simplest method is to extend the DefaultTableCellRenderer. Instantiate in advance (say, in the constructor) all the different types of JComponent you will need (only one of each type is needed). Then when getTableCellRendererComponent() is called, determine which JComponent is to be returned, adjusting their attributes if necessary.

public class MyTableCellRenderer extends DefaultTableCellRenderer
{
private JCheckBox checkbox;
private JButton button;

public MyTableCellRenderer()
{
// Create one checkbox and one button. We will always return the same ones.
checkbox = new JCheckBox("Check Box");
button = new JButton("Button");
}

public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
// Render row 0 column 0 as a JCheckBox. Return the pre-created
// JCheckBox after setting the "selected" attribute appropriately
// based on its value in the JTable model.
if (row == 0 && column == 0)
{
checkbox.setSelected(table.getValue(row, column));
return checkbox;
}

// Render row 0 column 2 as a JButton.
if (row == 1 && column == 2)
return button;

// Everywhere else, return the usual DefaultTableCellRenderer.
return this;
}
}

No comments:

Post a Comment