In my program, there is a JMenu with many accelerators, and a JTable that is editable. Problem is, when editing the JTable, the accelerator keys still get triggered.
E.g., if I enter the letter 'n' into the jtable cell, the 'next' menu option fires as well.
How would one go about making the jtable cell editor consume the keystrokes exclusively?
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import java.awt.event.KeyEvent;
import java.awt.Toolkit;
public class SampleClass{
public SampleClass(){
JFrame frame = new JFrame();
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu();
JMenuItem item = new JMenuItem();
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, 0));
item.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
Toolkit.getDefaultToolkit().beep();
}
});
JTable table = new JTable(new Object[][]{{"Hello","World"},{"Goodbye","World"}}, new String[]{"A","B"});
menu.add(item);
menuBar.add(menu);
frame.setJMenuBar(menuBar);
frame.add(table);
frame.pack();
frame.show();
}
public static void main(String[] args){
new SampleClass();
}
}
Edit any cell in the above table, there's a menu item set to beep with the accelerator 'n'.
It's a bug (which I thought had been fixed ages ago ... tsssee) due to a rather weird key processing of JTable. It starts editing in processKeyBinding on a pressed keyEvent - if autoStartEdits is true, as it is by default - and then passes that key on to the editingComponent. So at the end of the day, the key is consumed if the editingComponent consumes it. TextComponents consume a key on typed, not pressed ... which allows the pressed to travel up the dispatch chain until it reaches the menu.
A hackaround (beware: all hacks are dirty and might have unforeseen/unforseable side-effects!) is to override the table's processKeyBinding and consume the key if it started an edit:
@Override
protected boolean processKeyBinding(KeyStroke ks,
KeyEvent e, int condition, boolean pressed) {
boolean result = super.processKeyBinding(ks, e, condition, pressed);
if (isEditing() && pressed) return true;
return result;
}
来源:https://stackoverflow.com/questions/23052777/can-jtable-cell-edit-consume-key-strokes