tags:

views:

545

answers:

3

Hello,

I use a JTable which has its own cell renderer and cell editor.

Say, this table contains 2 columns and x rows:
The first column contains a boolean value, its own cell rendering and cell editor (a radiobutton)
The second column contains a string value, its own cell renderer: it makes it bold when the first column of the current row is set to true (radiobutton checked)

All the values are correctly updated by the editor but the 2nd row does not become bold when the radio button is set to true...
I have to check a radio button from a different row to see the changes

Where can I fire thoses changes ?

Cheers and thanks for your help


RadiobuttonTableCellEditor.java

public class RadiobuttonTableCellEditor extends DefaultCellEditor
         implements ItemListener {
JRadioButton rb = new JRadioButton();

public RadiobuttonTableCellEditor(JCheckBox pCheckBox) {
 super(pCheckBox);
}

public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
 if (value == null)
  return null;
 rb.addItemListener(this);
 rb.setSelected((Boolean)value);
 return rb;
}

public void itemStateChanged(ItemEvent e) {
 super.fireEditingStopped();
}

public Object getCellEditorValue() {
 rb.removeItemListener(this);
 return rb.isSelected();
}
}
A: 

It doesn't seem to make any sense to extend DeafultCellEditor there. Implementing a listener interface like that is also not a great idea.

Renderers work best as a thin layer. If another cell should change, then that needs to be reflected in the table model which should fire a relevant update event.

Tom Hawtin - tackline
So would you please tell me how to properly code such a thing ?
William Huart
+1  A: 

In your table model whenever your value changes you have to fire appropriate event. If your model is inherited from AbstractTableModel you can use several fireXXX methods. My guess is you should call them from setValueAt method.

If you know exact column and row - you can call fireTableCellUpdated, otherwise you can you probably have to use fireTableChanged since you have to update different column.

And of course you renderer should properly render new value.

eugener
Thanks for your help I added a member declaration of the JTable that I reference when I call getTableCellEditorComponent. Then, well getCellEditorValue is called I state: if (table != null) { ((AbstractTableModel) table.getModel()).fireTableDataChanged(); }
William Huart
Even though it probably works, your approach is not correct. you should call fireXXX methods IN the table model in response to changing DATA. In no case you should do it in the renderer or editor. The idea is simple. your editor will save new value into the model using model.setValueAt method. Then model should let all interested parties know that data changed. Your renderers and editors will react to change automatically.
eugener
A: 

I guess it could help people with a similar problem, make a true radiobutton unique in a row, you'll have to extend the DefaultTableModel to modify its behaviour especially the setValueAt method

Cheers


/**
 * When <code>column</code> is the column that contains the Boolean (in fact the radio button):
 * If aValue == false and that it had a previous value set to true we don't do anything
 * If aValue == true and that it had a previous value set to false, we set all the other booleans to false and this one to true
 */
@Override
public void setValueAt(Object aValue, int row, int column) {
 if (column == colonneBoutonradio)
 {
  if (((Boolean)aValue && !(Boolean)super.getValueAt(row, column)))
   for (int i = 0; i < this.getRowCount(); i++)
    // i==row permet de vérifier si la ligne courante est celle à modifier (et donc celle à mettre à true)
    super.setValueAt(i==row, i, colonneBoutonradio);
 }
 else
  super.setValueAt(aValue, row, column);
}
William Huart