Reputation: 143
I have made my own version of Tetris in Java and i have added the possibility of moving the shapes both with JButtons and with certain keyboard keys. The code snippet i used is the following:
leftButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent E) {
moveLeft();
}
});
rightButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent E) {
moveRight();
}
});
rotateButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent E) {
rotateMovingShape();
}
});
myPanel.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent event) {
int keyCode = event.getKeyCode();
if (keyCode == event.VK_A)
{
moveLeft();
}
if (keyCode == event.VK_D)
{
moveRight();
}
if (keyCode == event.VK_S)
{
rotateMovingShape();
}
}
});
The problem i have is that after i use the JButtons, i cannot longer control the shapes with the keyboard keys. I suspect it has something to do with gaining/losing focus, but i am not sure. Could anyone tell me what's going on?
Upvotes: 0
Views: 41
Reputation: 50021
A KeyListener only receives key events when the component has the keyboard focus. Clicking on the buttons transfers the focus to them and away from your panel, so you don't get the events. Any one of the following approaches will solve this:
Call setFocusable(false);
on the buttons so that they won't steal the focus.
Add the KeyListener to the buttons too.
Use key bindings instead of a KeyListener, so that you can catch the key press whether the component has focus or not.
Upvotes: 0
Reputation: 10994
You get that problem, because you use KeyListener
, instead of that you need to use Key Bindings. For example:
component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_A,0), "aPressed");
component.getActionMap().put("aPressed", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("a key");
}
});
component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_D,0), "dPressed");
component.getActionMap().put("dPressed", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("d key");
}
});
// other bindings
where component
is your JPanel
.
Upvotes: 2