Java 我能';不能用键绑定移动我的JLabel?

Java 我能';不能用键绑定移动我的JLabel?,java,swing,key-bindings,Java,Swing,Key Bindings,我正在尝试用Java制作一个游戏,按下空格键可以移动窗口中的框。我正在使用密钥绑定来完成这项任务。问题是我不知道如何在盒子本身上使用ActionListener,这是一个JLabel。代码如下: import java.awt.Color; import java.awt.Graphics; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.Action; impo

我正在尝试用Java制作一个游戏,按下空格键可以移动窗口中的框。我正在使用密钥绑定来完成这项任务。问题是我不知道如何在盒子本身上使用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并使用它,但我发现“空格键”只有在单击框本身时才会打印出来。非常感谢您的帮助。谢谢

您的“核心”问题围绕着
box.getInputMap()
,将其更改为类似于
box.getInputMap(在聚焦窗口中时)
,这意味着API将在窗口有焦点时响应关键事件,而不管其他组件可能有焦点

我还建议使用类似于
box.getInputMap(当在聚焦窗口中时).put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,0),“doPlayerAction”)
,作为
击键
用于将
字符串
解析为
击键
的机制,可能看起来要复杂得多,通常需要额外的信息,如按下
释放
或键入
等,使用虚拟键就更容易了

我还将把键绑定到
gamePanel
作为一个通用的首选项,因为它应该是容器来决定做什么,但那只是我自己

查看更多详细信息

您的“核心”问题围绕着
box.getInputMap()
,将其更改为类似于
box.getInputMap(在聚焦窗口中时)
,这意味着无论其他组件可能有聚焦,只要窗口有聚焦,API都会响应关键事件

我还建议使用类似于
box.getInputMap(当在聚焦窗口中时).put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,0),“doPlayerAction”)
,作为
击键
用于将
字符串
解析为
击键
的机制,可能看起来要复杂得多,通常需要额外的信息,如按下
释放
或键入
等,使用虚拟键就更容易了

我还将把键绑定到
gamePanel
作为一个通用的首选项,因为它应该是容器来决定做什么,但那只是我自己


查看更多详细信息

而不是扩展
AbstractAction
实现
KeyListener
。@jackjay KeyBindings不像KeyListener那样受到焦点相关问题的困扰,它代表了一种可重复使用的工作功能,可应用于其他输入方法,与KeyListener不同,它更像是一个布局issue@MadProgrammer谢谢但正如OP所说,OP点击标签时会有输出,所以我认为这可能是焦点问题。@jackjay因为代码中没有
MouseListener
s,所以我不确定它是如何工作的:P@jackjay这在一定程度上是一个与焦点相关的问题,但是,
KeyListener
并不能更好地解决这个问题:Pin代替了扩展
AbstractAction
implement
KeyListener
。@jackjay KeyBindings不像KeyListener那样受到焦点相关问题的困扰,它代表了一个可以应用于其他输入方法的可重用工作函数,与KeyListener不同,它更像是一个布局issue@MadProgrammer谢谢但正如OP所说,OP点击标签时会有输出,所以我认为这可能是焦点问题。@jackjay因为代码中没有
MouseListener
s,所以我不确定它是如何工作的:P@jackjay这在一定程度上是一个与焦点相关的问题,但是
KeyListener
无法更好地解决它:p它解决了这个问题。谢谢你,伙计!我一定会按照你的建议来做:)那就解决了。谢谢你,伙计!我一定会按照你的建议来做:)