The problem is the way in which you are looking up the KeyStroke
. KeyStroke.getKeyStroke('w')
will return typed w
, which for some reason, doesn't trigger a key event. This is why I tend to avoid this method. Instead use
panel.getInputMap().put(KeyStroke.getKeyStroke("W"),"forward");
or
panel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0),"forward");
Also, you may want to define the focus constraint for the InputMap
, something like
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)...
Would be safer...but you will need to decided at what level you want the key strokes to triggered from
See JComponent
and How to use Key Bindings for more details
Updated with example
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test extends JFrame {
private JPanel panel;
public Test() {
super();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 500);
setLayout(new BorderLayout());
setVisible(true);
panel = new JPanel();
// HERE ARE THE KEY BINDINGS
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "forward");
panel.getActionMap().put("forward", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("test");
}
});
// END OF KEY BINDINGS
add(panel, BorderLayout.CENTER);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
new Test();
}
});
}
}