Wednesday, August 5, 2009

Custom JTable Cell Renderer (Part 2)

While overriding getTableCellRendererComponent() in DefaultTableCellRenderer allows you to render any arbitrary JComponent in a cell, it is unfortunately all it does. If getTableCellRendererComponent() returns a JCheckBox, then JTable will render it in the appropriate cell including its check state. But the rendered checkbox will not be responsive to any mouse click applied, which of course defeats the purpose of displaying a checkbox inside a cell in the first place.

It is relatively easy to make a cell interactive. First, register a MouseListener on the JTable. When a mouseClicked(MouseEvent evt) is called, you can determine the cell picked using:

int row = table.rowAtPoint(evt.getPoint());
int col = table.columnAtPoint(evt.getPoint());

If we determine that the cell at this row and column can respond to a selection, then we need a way to keep track of the state of that cell. For example, a cell rendering a checkbox needs to keep track of its check state. The JCheckBox returned by getTableCellRendererComponent() cannot be used for this purpose because there is only one and is used as a rendering template. Here is where an arbitrary data object comes in handy. For example, if the cell is a checkbox, then data object for that cell can be a Boolean object. Then you can call the JTable's model's setValueAt(row, col) to store the boolean value of the cell clicked, making it true if it were false and vice versa.

This data object will be passed as the argument to getTableCellRenderer()'s value object parameter. Using the checkbox example above, this will be a Boolean object and depending on whether the value is true or false, set the selection state of the JCheckBox template before returning it. The checked state will be used to render the affected cell accordingly.

No comments:

Post a Comment