2

I have a custom TableCellRenderer (ValueRenderer) for a JTable, the cell is a Checkbox.

I have attached an ItemListener to the valueRenderer to listen to the checkbox's state change (selected/deselected) as mentioned by this example.

My problem is that inside the itemStateChanged(ItemEvent e), I do not know how to get the row in which this checkbox is contained knowing that the ItemEvent source is the ValueRenderer.

Can you help me?

Here is some of my code:

Custom TableCellRender:

public class ValueRenderer extends JCheckBox implements TableCellRenderer {

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
        this.setSelected((Boolean) value);
        return this;
    }

} 

ItemListener:

public class TableRowCheckBoxListener implements ItemListener {

    private JTable hqlRequestTable;

    public TableRowCheckBoxListener(JTable hqlRequestTable) {
        this.hqlRequestTable = hqlRequestTable;
    }

    @Override
    public void itemStateChanged(ItemEvent e) {

        /*How do I get the row which contains the checkbox clicked knowing that :
            e.getSource() == ValueRenderer
            e.getItem() == ValueRender
        */
    }

}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
Adel Boutros
  • 10,205
  • 7
  • 55
  • 89
  • why do you need it ? If you reread the example you will notice that the itemstate listening is done in the editor and not in the renderer, but there you dont have the row column either. The JTable takes care of the necessary row and column mapping if you stop editing. – Peter Jan 16 '12 at 12:14
  • 1
    renderers are completely passive slaves, doing nothing but stamping their renderingComponent into some real component whenever the paint mechanism deems it appropriate. Don't _ever_ register any listener to them, their notification doesn't make sense, never! – kleopatra Jan 16 '12 at 12:23
  • @kleopatra It was done by a Dr., not by me. [example](https://sites.google.com/site/drjohnbmatthews/table). So I took his code and tried to modify it to my needs – Adel Boutros Jan 16 '12 at 12:45
  • no, that example doesn't add a listener to a renderer ;-) Though mis-reading that is easy, due to inappropirate subclassing, @trashgod – kleopatra Jan 16 '12 at 13:32
  • @kleopatra Yeah I see your point. Anyway, I solved it using a propertyChange Listener :) – Adel Boutros Jan 16 '12 at 13:51

1 Answers1

2

If you want to know when some value changes in your table, you must not register a listener on the renderer. You must register a listener on the table model: that's where the data displayed by the table is held, and that's the object which fires an event if anything changes in the data.

The alternative is to use a custom table model consisting in a list of beans, have the table model modify the properties of the beans it holds, and have the bean fire a property change event when a property changes. You'll then register listeners on the beans themselves rather than registering a table model listener (note that the table model still has to fire table model events, though).

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255