KeyPressed inconsistent event: sometimes it fires, sometimes it doesn't, it restarts the program without changing anything, and it can or can now work

Good, so I'm very upset here. This piece of code is a very simple moving JComponent.

Which is strange, because when I change absolutely nothing, the keyPressed event will be incredibly inconsistent. I run the program, and sometimes it will work, and my ball will move around the screen. On the other hand, I will close it and open it without changing anything, and it will not work. I do not think that the focus here is a problem, although I really know little about it. I have no idea what is going on.

Any help would be greatly appreciated. I just donโ€™t see how a program can so inconsistently fail and succeed.

And here is my code in the character class, because I donโ€™t think just giving you a snippet will help. I donโ€™t know if itโ€™s just me or something else, but if you want to compile it and see it, go ahead.

import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Character extends JComponent implements KeyListener { Timer timer = new Timer(5, new TimeListener()); private int x = 250; private int y = 300; char whichTimer; public Character() { addKeyListener(this); setFocusable(true); requestFocusInWindow(); repaint(); } public void keyReleased(KeyEvent e) { if(e.getKeyCode() == KeyEvent.VK_W) { timer.stop(); } if(e.getKeyCode() == KeyEvent.VK_A) { timer.stop(); } if(e.getKeyCode() == KeyEvent.VK_S) { timer.stop(); } if(e.getKeyCode() == KeyEvent.VK_D) { timer.stop(); } } public void keyPressed(KeyEvent e) { if(e.getKeyCode() == KeyEvent.VK_W) { timer.stop(); whichTimer = 'W'; timer.start(); } if(e.getKeyCode() == KeyEvent.VK_A) { timer.stop(); whichTimer = 'A'; timer.start(); } if(e.getKeyCode() == KeyEvent.VK_S) { timer.stop(); whichTimer = 'S'; timer.start(); } if(e.getKeyCode() == KeyEvent.VK_D) { timer.stop(); whichTimer = 'D'; timer.start(); } } public void keyTyped(KeyEvent e) { } protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; // g2d.drawImage(fatsprite, x-10, y-10, null); g.setColor(Color.BLACK); g.fillOval(x-10, y-10, 20, 20); } class TimeListener implements ActionListener { public void actionPerformed(ActionEvent e) { if(whichTimer == 'W') { y-=1; repaint(); } if(whichTimer == 'A') { x-=1; repaint(); } if(whichTimer == 'S') { y+=1; repaint(); } if(whichTimer == 'D') { x+=1; repaint(); } } } } 
+4
source share
3 answers

@Max is correct, KeyBindings is the best approach to your problem. The main problem (sorry, not a pun) is that as soon as the focus moves to any other component, you will no longer receive key events. Now you probably think: โ€œBut I have not changed focusโ€ - you just need to click on another component to be focused to focus on the loss or click on a tab that KeyListener usually not be notified about.

Usually, as you find out, KeyListeners are not reliable, they will not only receive a notification only when the component of interest has focus, and the keys can be used before they reach you.

+3
source

Make sure the component is customizable and has focus. In addition, it is better to use Key Bindings, see How to Use Key Bindings for more details.

+5
source

1. The problem is that you are loosing focus over your components here.

2. Verify that your components are focusable , try using KeyBinding

3. Also, keep this in mind ... In Swings focus moves from left to right and from top to bottom , where, like in AWT , it follows the sequence in which the components were added to the container.

+3
source

All Articles