I have a JTable descendant which has custom focus traversal via tab keypresses (input and action maps). The handler figures out which cell to go to next, then does a JTable.changeSelection() and a JTable.editCellAt() so the user only has to press tab and then start entering data in the new cell.
So far, so good. The start of the problem is that the existing text in the cell must be selected in the custom editor component (and highlighted, so the user knows it's selected), so that whatever the user types will replace it. (This is a spec requirement and believe me, it makes sense in the context of that table.) So in my table's constructor I call JTable.setSurrendersFocusOnKeystroke(true).
The problem is that if I single-click on an empty cell and start typing, we go into edit mode on the cell. And that first character appears in the cell,
selected, and the second character I type
replaces the first! This is
not what I want. And there seems to be no way of controlling it.
I have tried, in my custom cell editor's getTableCellEditorComponent() method, doing a selectAll() for the case where I am passed a null object (which is the case when the cell is empty), just in case the first character typed succeeds in replacing the empty selection. That doesn't work. I have isolated the problem, I
think, to the following code at the bottom of JTable.processKeyBinding():
// If the editorComponent is a JComponent, pass the event to it.
if (editorComponent instanceof JComponent)
{
retValue = ((JComponent) editorComponent).processKeyBinding
(ks, e, WHEN_FOCUSED, pressed);
// If we have started an editor as a result of the user
// pressing a key and the surrendersFocusOnKeystroke property
// is true, give the focus to the new editor.
if (getSurrendersFocusOnKeystroke())
{
editorComponent.requestFocus();
}
}
I wonder if the call to JComponent.processKeyBinding() was done
after the call to JComponent.requrestFocus(), the problem would not occur. But I'm not certain about this. The one thing I am certain of is that it is not my code which is causing the problem, since the single-click-and-type behaviour happens with the following SSCCE:
public class TableEditProblem extends JPanel
{
public TableEditProblem()
{
super(new BorderLayout());
DefaultTableModel m = new DefaultTableModel(2, 5);
JTable t = new JTable(m);
t.setGridColor(Color.BLACK);
t.setSurrendersFocusOnKeystroke(true); // comment out this line to have the first character typed NOT be selected
add(t, BorderLayout.CENTER);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("TableEditProblem");
//Create and set up the content pane.
JComponent newContentPane = new TableEditProblem();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
Please, has anyone solved this problem and can point me in the right direction? I cannot be the first person to want this sort of behaviour!!