我无法使用Key Binding移动我的JLabel?

时间:2017-02-11 07:03:47

标签: java swing key-bindings

我正在尝试用Java创建一个游戏,按空格键移动窗口中的框。我正在使用Key Binding来完成此任务。问题是我无法弄清楚如何在盒子本身上使用ActionListener,这是一个JLabel。以下是代码:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction; 
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class Game {

private static JFrame frame     = new JFrame();
private static JPanel gamePanel = new JPanel();
private static Action playerAction = new PlayerListener();
private static JLabel box = new JLabel();
private static int x = 250;
private static int y = 250;

public static void main(String[] args) {

    frame.add(boxPanel());
    frame.setTitle("Block Game");
    frame.setSize(500,500);
    frame.setLocationRelativeTo(null);
    frame.setFocusable(true);

    box.addActionListener(playerAction);

    frame.setVisible(true);

}

static JPanel boxPanel() {
    ImageIcon boxIcon = new ImageIcon("box.png");
    box.setIcon(boxIcon);

    box.setSize(30,30);
    box.setLocation(x,y);

    box.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "doPlayerAction");
    box.getActionMap().put("doPlayerAction", playerAction);

    gamePanel.setLayout(null);
    gamePanel.add(box);
    frame.add(gamePanel);

    return gamePanel;   
}

static class PlayerListener extends AbstractAction {

    public void actionPerformed(ActionEvent e) {

        System.out.println("SPACEBAR");

    }

}
}

我尝试将框更改为JButton并改为使用它,但我发现“SPACEBAR”仅在我单击框本身时打印出来。任何帮助是极大的赞赏。谢谢!

1 个答案:

答案 0 :(得分:3)

你的核心"问题围绕box.getInputMap(),将其更改为更像box.getInputMap(WHEN_IN_FOCUSED_WINDOW)的内容,这意味着只要窗口具有焦点,API就会响应关键事件,无论其他组件可能具有哪些焦点。

我还建议更像box.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "doPlayerAction"),因为KeyStroke用来解析StringKeyStroke的机制比看起来更复杂,通常需要其他信息,例如pressedreleasedtyped,它更容易使用虚拟键

我还会将键绑定到gamePanel作为一般偏好,因为它应该是容器决定做什么,但那只是我。

有关详细信息,请查看How to Use Key Bindings