Re: JSpinners as JTable cells - a solution
In article <op.uh8q60x1p9vcmo@macmini.local>,
"Rexx Magnus" <trashcan@uk2.net> wrote:
I've been writing an application for the past several weeks that has a
JTable that uses JSpinners in one column.
I discovered that I was having problems with the TableModel not updating
whenever a spinner was edited using only the buttons.
Editing with the text field was not a problem - but if you changed a value
using the buttons, you had to click in a different cell of the table
before the model would update.
Evidently, this was a focus problem. JSpinner buttons do not ordinarily
seem to get focus within a table - the text part can, but the buttons
don't.
After following numerous posts on forums etc. I stumbled across one
suggestion to use a custom UI for the spinner - however, this relied on
the plaf.basic look and feel, which means that if you change the UI in
order to add focuslisteners as you build it, the buttons may become a
different look and feel whilst you edit the values.
This wasn't very nice on the Mac, I can tell you!
I didn't really have much of a clue as to what I was doing - but I
definately didn't want to rebuild the UI from scratch, so I dug down into
the JSpinner's component list and applied focuslisteners to each. This
appears to fix the problem completely - something which no other solution
on the net had seemed to do without requiring a total program rewrite.
I tried your SpinnerEditor in Sun's TableRenderDemo, adding a few lines
in the constructor:
TableColumn yearsColumn = table.getColumnModel().getColumn(3);
yearsColumn.setCellEditor(new SpinnerEditor(0, 25));
table.setRowHeight(20);
<http://java.sun.com/docs/books/tutorial/uiswing/examples/components/Tabl
eRenderDemoProject/src/components/TableRenderDemo.java>
It seems to work as advertised, but I miss being able to use the up and
down arrows to operate the JSpinner. Of course, the JComboBox has the
same problem with keyboard navigation.
[rewrapped]
class SpinnerEditor extends AbstractCellEditor
implements TableCellEditor {
final JSpinner spinner;
private JTable currentTable;
private int selectedRow;
private int selectedColumn;
// Initializes the spinner.
public SpinnerEditor(int min, int max) {
spinner = new JSpinner(
new SpinnerNumberModel(min, min, max, 1));
//This alone does not fix the issue
spinner.setFocusable(true);
//List all of the components and make them focusable
//then add an empty focuslistener to each
for(Component tmpComponent:spinner.getComponents()){
tmpComponent.setFocusable(true);
tmpComponent.addFocusListener(new FocusAdapter(){
@Override
public void focusLost(FocusEvent fe){}
});
}
}
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
spinner.setValue(value);
currentTable = table;
selectedRow = row;
selectedColumn = column;
return spinner;
}
public Object getCellEditorValue() {
return spinner.getValue();
}
}
--
John B. Matthews
trashgod at gmail dot com
home dot woh dot rr dot com slash jbmatthews