Reputation: 379
I have a class which implements KeyListener
, all's working fine, but there a little problem that my KeyListener
works only after I click on a Canvas, so if I start a game, I have to click once on it and then I can use my keyboard, code:
public class Game extends Canvas implements Runnable {
....
initGame() {
...
addKeyListener(new Keyboard());
setFocusable(true);
}
private class Keyboard implements KeyListener {
...
}
}
-is there a method which make my canvas "active" after creating?
Upvotes: 0
Views: 3906
Reputation: 1
I solved this problem in the next way: I created Canvas object, added KeyListener to it and made this object focusable. After these operations I added Canvas object to JFrame and everything started working fine.
Upvotes: 0
Reputation: 46871
It might be an issue if Canvas
is added after making JFrame
visible.
Call
frame.setVisible(true)
in the end after adding all the components on it.
This is what happening with me if I add Canvas
after making JFrame
visible and I have to click on Canvas
to gain focus on it.
-- EDIT --
Sample code to understand it (try after un-commenting last frame.setVisible(true)
)
import java.awt.Canvas;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
public class CanvasDemo extends Canvas implements ActionListener, KeyListener {
public CanvasDemo() {
addKeyListener(this);
setFocusable(true);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setVisible(true);
CanvasDemo apple = new CanvasDemo();
frame.add(apple);
frame.setTitle("The Game");
// frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
// animates rectangle
public void actionPerformed(ActionEvent arg0) {
System.out.println("action performed");
}
@Override
public void keyPressed(KeyEvent arg0) {
System.out.println("key pressed");
}
@Override
public void keyReleased(KeyEvent arg0) {
System.out.println("key released");
}
@Override
public void keyTyped(KeyEvent arg0) {
System.out.println("key typed");
}
}
Upvotes: 0
Reputation: 347314
KeyListener
will only respond to key events when the component it is registered to is focusable AND has focus.
While you can use requestFocusInWindow
, there is no guarantee that focus will be transferred to the component and if focus is lost for some reason (you click on another component), then you back to square one.
A better solution is to use a JComoponet
based componet (like JPanel
) and make use of the Key Bindings API which allows you to define the focus level that triggers the key events
Upvotes: 1