Reputation: 11779
I'm having a JTable containing JComboBox editors initialized somewhat like
JComboBox comboBox = ...;
TableColumn tc = table.getColumnModel().getColumn(i);
tc.setCellEditor(new DefaultCellEditor(comboBox));
This is working otherwise fine but I'd like to be able to navigate in the table and update the values with keyboard only. Now this is possible with the combo boxes but if I want to update the value "1" I must first press a key to activate the combo box and then press "1" to select the item.
So, what I want is that I could press "1" and the item would be selected with only one key press.
For the text cells I've managed to do this with prepareEditor like the following...
@Override
public Component prepareEditor(TableCellEditor editor, int row, int column) {
Component c = super.prepareEditor(editor, row, column);
if (c instanceof JTextComponent) {
((JTextComponent) c).selectAll();
}
return c;
}
... but I haven't managed to figure out what to do with the combo box.
One possibility could be own TableCellEditor but if there's a more simple solution that would be nice =)
br, Touko
Upvotes: 4
Views: 2737
Reputation: 3103
In case anyone is still interested, I do a simple modification to Touko's code and this works for me:
public class CustomTable extends JTable {
private static final long serialVersionUID = -8855616864660280561L;
public CustomTable(TableModel tableModel) {
super(tableModel);
}
@Override
public Component prepareEditor(TableCellEditor editor, int row, int column) {
final Component comp = super.prepareEditor(editor, row, column);
// Text component should select all text when initiated for editing.
if (comp instanceof JTextComponent)
((JTextComponent) comp).selectAll();
// Try to obtain focus for the editor component.
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() { comp.requestFocusInWindow(); }
});
return comp;
}
}
So basically, I'm just requesting focus for the editor component at some later time using SwingUtilities.invokeLater
. The reason for this approach is because focus request will fail if the editor component is not yet visible.
Hope this can help anyone.
Upvotes: 2
Reputation: 769
You must add a KeyListener
to your code.
The best solution is add it to the JTable
component where you are laying the JComboBox
and implement the method keyPressed(KeyEvent e)
or the keyReleased(KeyEvent e)
one in order to know which is the key and do the necessary action.
Here I give you an example:
JTable table = new JTable();
// Your necessary code (create combo box, cell editor...etc)
table.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch(keyCode) {
case KeyEvent.VK_1:
// manage key 1
break;
case KeyEvent.VK_A:
// manage key A
break;
case KeyEvent.VK_F1:
// manage key F1
break;
case KeyEvent.VK_TAB:
// manage key TAB
break;
default:
// manage other keys
}
}
});
You also can combine this solution with a dictionary which relates the keyCode with an action interface.
This second solution needs the following code: A global attribute (the dictionary):
Map<Integer,MyAction> keyActions = new Hashmap<Integer,MyAction>();
A own action interface:
public interface MyAction {
public void doAction();
}
And the KeyListener.keyPressed() function would be the following:
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
MyAction ma = keyActions.get(keyCode);
if (ma != null) {
ma.doAction();
}
else {
// do default action for other keys
}
}
I hope this helps you.
Regards!
Upvotes: 0