Keylistener does not work for JPanel

I try to do something when one of the arrow keys is pressed using KeyListener in my JPanel class. Here is my code:

public class TestPanel extends JPanel implements KeyListener{ public TestPanel(){ this.addKeyListener(this); this.setFocusable(true); this.requestFocusInWindow(); } public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_RIGHT) { System.out.println("Right"); } if (e.getKeyCode() == KeyEvent.VK_LEFT) { System.out.println("Left"); } } public void keyTyped(KeyEvent e) {} public void keyReleased(KeyEvent e) {} } 

My main method adds a new instance of this panel to the frame and displays it. Do I need to add a key list in a JFrame? In my case, it would be difficult and inefficient, so I would like to work with this JPanel, if possible. Does anyone know what I'm doing wrong?

EDIT: Key binding code that also doesn't work:

 public class GamePanel extends JPanel implements ActionListener{ //Constructor public GamePanel(){ setupKeyBinding(); this.setFocusable(true); this.requestFocusInWindow(); } private void setupKeyBinding() { int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; InputMap inMap = getInputMap(condition); ActionMap actMap = getActionMap(); inMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "Left"); actMap.put("Left", new leftAction()); } private class leftAction extends AbstractAction { public void actionPerformed(ActionEvent e) { System.out.println("test"); } } public void actionPerformed(ActionEvent e) { //some other game info } } 

Can someone tell me why this doesn't work either? (my second action listener for other things needed for my game)

+8
source share
4 answers

If you are looking for this problem, you will see that it is asked and solved many times.

  • KeyListeners should be focused on work. One solution is to give your component focus after it has become primary.
  • It is better to use snap keys, however, with a long shot. Google tutorial on this.

Please look at my answer to this question to learn more about this, including many gory details.

+10
source

For reference, I am creating an example using your approach; while it works, it also offers a focus problem elsewhere in your code. Key Bindings avoid this, as shown here .

Addendum: Here is my working key binding.

 private static class TestPanel extends JPanel { private static final String LEFT = "Left"; private Action left = new AbstractAction(LEFT) { @Override public void actionPerformed(ActionEvent e) { System.out.println(LEFT); } }; private static final String RIGHT = "Right"; private Action right = new AbstractAction(RIGHT) { @Override public void actionPerformed(ActionEvent e) { System.out.println(RIGHT); } }; public TestPanel() { this.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), LEFT); this.getActionMap().put(LEFT, left); this.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), RIGHT); this.getActionMap().put(RIGHT, right); } } 

Original SSCCE:

 import java.awt.EventQueue; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; import javax.swing.JPanel; /** * @see https://stackoverflow.com/a/16531380/230513 */ public class Test { private void display() { JFrame f = new JFrame("Test"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(new TestPanel()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } private static class TestPanel extends JPanel implements KeyListener { public TestPanel() { this.addKeyListener(this); this.setFocusable(true); this.requestFocusInWindow(); } @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_RIGHT) { System.out.println("Right"); } if (e.getKeyCode() == KeyEvent.VK_LEFT) { System.out.println("Left"); } } @Override public void keyTyped(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { } } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new Test().display(); } }); } } 
+5
source

I had to do two things: I added comp.setFocusable (true); to the comp component that listens for key events, and I added comp.requestFocus (); for every action that caused the comp to lose focus.

0
source

To get key events on JPanel you need to set the focus:

 setFocusable(true); requestFocus(); 

JPanel now has focus, so it gets key events

0
source

Source: https://habr.com/ru/post/944926/


All Articles