Java 按键绑定
Java Key Bindings
我有一个任务要为 uni 做,需要让用户使用方向键控制游戏。
到目前为止,我得到了以下结果,但这不起作用。有什么明显的我遗漏的吗?
// key bindings
// add the key bindings for up, down, left and right to the input map
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0), "down");
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0), "up");
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0), "left");
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0), "right");
// assign actions to the key bindings in the action map
gamePanel.getActionMap().put("down", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
move("DOWN");
}
});
gamePanel.getActionMap().put("up", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
move("UP");
}
});
gamePanel.getActionMap().put("left", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
move("LEFT");
}
});
gamePanel.getActionMap().put("right", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
move("RIGHT");
}
});
按下任何方向按钮时没有任何反应。
在此先感谢您的帮助。
下方的 MCVE - 我完成的第一个所以让我知道它是否足够好
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import com.sun.java.swing.plaf.windows.resources.windows;
import java.util.ArrayList;
public class MCVE extends JFrame
{
// Game panel
private JPanel gamePanel;
private Container window;
public static void main(String[] args)
{
MCVE frame = new MCVE();
frame.setSize(1000,700);
frame.createGUI();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void createGUI()
{
setDefaultCloseOperation(EXIT_ON_CLOSE);
window = getContentPane();
gamePanel = new JPanel();
window.add(gamePanel);
}
private void keyBindings()
{
// key bindings
// add the key bindings for up, down, left and right to the input map
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0), "down");
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0), "up");
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0), "left");
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0), "right");
// assign actions to the key bindings in the action map
gamePanel.getActionMap().put("down", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("down");
}
});
gamePanel.getActionMap().put("up", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("up");
}
});
gamePanel.getActionMap().put("left", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("left");
}
});
gamePanel.getActionMap().put("right", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("right");
}
});
}
}
JPanel 具有为左箭头键和右箭头键定义的 WHEN_FOCUSED 键绑定。我不知道定义了什么动作,但这不是我的动作。这就是为什么我为箭头键定义了 WHEN_FOCUSED 键绑定以及 WHEN_IN_FOCUSED_WINDOW 键绑定。
这是我的按键绑定方法。如果你愿意,你可以忽略 WASD 键。
private void setKeyBindings() {
InputMap inputMap =
gridPanel.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(KeyStroke.getKeyStroke("W"), "up arrow");
inputMap.put(KeyStroke.getKeyStroke("S"), "down arrow");
inputMap.put(KeyStroke.getKeyStroke("A"), "left arrow");
inputMap.put(KeyStroke.getKeyStroke("D"), "right arrow");
inputMap.put(KeyStroke.getKeyStroke("UP"), "up arrow");
inputMap.put(KeyStroke.getKeyStroke("DOWN"), "down arrow");
inputMap.put(KeyStroke.getKeyStroke("LEFT"), "left arrow");
inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "right arrow");
inputMap = gridPanel.getInputMap(JPanel.WHEN_FOCUSED);
inputMap.put(KeyStroke.getKeyStroke("UP"), "up arrow");
inputMap.put(KeyStroke.getKeyStroke("DOWN"), "down arrow");
inputMap.put(KeyStroke.getKeyStroke("LEFT"), "left arrow");
inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "right arrow");
gridPanel.getActionMap().put("up arrow",
new UpArrowAction(this, model));
gridPanel.getActionMap().put("down arrow",
new DownArrowAction(this, model));
gridPanel.getActionMap().put("left arrow",
new LeftArrowAction(this, model));
gridPanel.getActionMap().put("right arrow",
new RightArrowAction(this, model));
}
您的可运行示例从不调用 keyBindings
方法,因此它们从不注册...
private void createGUI() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
window = getContentPane();
gamePanel = new JPanel();
window.add(gamePanel);
// This is going to help...
keyBindings();
}
这就是调试语句和投入少量时间调试代码会有所帮助的地方。当某些东西不起作用时,请始终先检查您是否已正确设置...我仍然经常犯这种错误 ;)
为了以防万一,此示例使用 onKeyRelease
参数来监视按下和释放事件以及支持数字键盘箭头键
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel up;
private JLabel down;
private JLabel left;
private JLabel right;
public TestPane() {
up = createLabel("UP");
down = createLabel("DOWN");
left = createLabel("LEFT");
right = createLabel("RIGHT");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
add(up, gbc);
gbc.gridy = 2;
add(down, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
add(left, gbc);
gbc.gridx = 2;
add(right, gbc);
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "up-press", new HighlightAction(up, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_UP, 0, false), "up-press", new HighlightAction(up, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "down-press", new HighlightAction(down, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_DOWN, 0, false), "down-press", new HighlightAction(down, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "left-press", new HighlightAction(left, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_LEFT, 0, false), "left-press", new HighlightAction(left, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "right-press", new HighlightAction(right, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_RIGHT, 0, false), "right-press", new HighlightAction(right, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "up-release", new HighlightAction(up, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_UP, 0, true), "up-release", new HighlightAction(up, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "down-release", new HighlightAction(down, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_DOWN, 0, true), "down-release", new HighlightAction(down, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "left-release", new HighlightAction(left, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_LEFT, 0, true), "left-release", new HighlightAction(left, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "right-release", new HighlightAction(right, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_RIGHT, 0, true), "right-release", new HighlightAction(right, false));
}
public void registerKeyBinding(KeyStroke keyStroke, String name, Action action) {
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(keyStroke, name);
am.put(name, action);
}
public JLabel createLabel(String text) {
JLabel label = new JLabel(text);
label.setOpaque(true);
label.setHorizontalAlignment(JLabel.CENTER);
return label;
}
public class HighlightAction extends AbstractAction {
private JLabel label;
private boolean on;
public HighlightAction(JLabel label, boolean on) {
this.label = label;
this.on = on;
}
@Override
public void actionPerformed(ActionEvent e) {
if (on) {
label.setBackground(Color.RED);
label.repaint();
} else {
label.setBackground(null);
}
}
}
}
}
我有一个任务要为 uni 做,需要让用户使用方向键控制游戏。
到目前为止,我得到了以下结果,但这不起作用。有什么明显的我遗漏的吗?
// key bindings
// add the key bindings for up, down, left and right to the input map
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0), "down");
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0), "up");
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0), "left");
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0), "right");
// assign actions to the key bindings in the action map
gamePanel.getActionMap().put("down", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
move("DOWN");
}
});
gamePanel.getActionMap().put("up", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
move("UP");
}
});
gamePanel.getActionMap().put("left", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
move("LEFT");
}
});
gamePanel.getActionMap().put("right", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
move("RIGHT");
}
});
按下任何方向按钮时没有任何反应。
在此先感谢您的帮助。
下方的 MCVE - 我完成的第一个所以让我知道它是否足够好
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import com.sun.java.swing.plaf.windows.resources.windows;
import java.util.ArrayList;
public class MCVE extends JFrame
{
// Game panel
private JPanel gamePanel;
private Container window;
public static void main(String[] args)
{
MCVE frame = new MCVE();
frame.setSize(1000,700);
frame.createGUI();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void createGUI()
{
setDefaultCloseOperation(EXIT_ON_CLOSE);
window = getContentPane();
gamePanel = new JPanel();
window.add(gamePanel);
}
private void keyBindings()
{
// key bindings
// add the key bindings for up, down, left and right to the input map
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0), "down");
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0), "up");
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0), "left");
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0), "right");
// assign actions to the key bindings in the action map
gamePanel.getActionMap().put("down", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("down");
}
});
gamePanel.getActionMap().put("up", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("up");
}
});
gamePanel.getActionMap().put("left", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("left");
}
});
gamePanel.getActionMap().put("right", new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("right");
}
});
}
}
JPanel 具有为左箭头键和右箭头键定义的 WHEN_FOCUSED 键绑定。我不知道定义了什么动作,但这不是我的动作。这就是为什么我为箭头键定义了 WHEN_FOCUSED 键绑定以及 WHEN_IN_FOCUSED_WINDOW 键绑定。
这是我的按键绑定方法。如果你愿意,你可以忽略 WASD 键。
private void setKeyBindings() {
InputMap inputMap =
gridPanel.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(KeyStroke.getKeyStroke("W"), "up arrow");
inputMap.put(KeyStroke.getKeyStroke("S"), "down arrow");
inputMap.put(KeyStroke.getKeyStroke("A"), "left arrow");
inputMap.put(KeyStroke.getKeyStroke("D"), "right arrow");
inputMap.put(KeyStroke.getKeyStroke("UP"), "up arrow");
inputMap.put(KeyStroke.getKeyStroke("DOWN"), "down arrow");
inputMap.put(KeyStroke.getKeyStroke("LEFT"), "left arrow");
inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "right arrow");
inputMap = gridPanel.getInputMap(JPanel.WHEN_FOCUSED);
inputMap.put(KeyStroke.getKeyStroke("UP"), "up arrow");
inputMap.put(KeyStroke.getKeyStroke("DOWN"), "down arrow");
inputMap.put(KeyStroke.getKeyStroke("LEFT"), "left arrow");
inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "right arrow");
gridPanel.getActionMap().put("up arrow",
new UpArrowAction(this, model));
gridPanel.getActionMap().put("down arrow",
new DownArrowAction(this, model));
gridPanel.getActionMap().put("left arrow",
new LeftArrowAction(this, model));
gridPanel.getActionMap().put("right arrow",
new RightArrowAction(this, model));
}
您的可运行示例从不调用 keyBindings
方法,因此它们从不注册...
private void createGUI() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
window = getContentPane();
gamePanel = new JPanel();
window.add(gamePanel);
// This is going to help...
keyBindings();
}
这就是调试语句和投入少量时间调试代码会有所帮助的地方。当某些东西不起作用时,请始终先检查您是否已正确设置...我仍然经常犯这种错误 ;)
为了以防万一,此示例使用 onKeyRelease
参数来监视按下和释放事件以及支持数字键盘箭头键
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel up;
private JLabel down;
private JLabel left;
private JLabel right;
public TestPane() {
up = createLabel("UP");
down = createLabel("DOWN");
left = createLabel("LEFT");
right = createLabel("RIGHT");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
add(up, gbc);
gbc.gridy = 2;
add(down, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
add(left, gbc);
gbc.gridx = 2;
add(right, gbc);
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "up-press", new HighlightAction(up, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_UP, 0, false), "up-press", new HighlightAction(up, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "down-press", new HighlightAction(down, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_DOWN, 0, false), "down-press", new HighlightAction(down, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "left-press", new HighlightAction(left, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_LEFT, 0, false), "left-press", new HighlightAction(left, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "right-press", new HighlightAction(right, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_RIGHT, 0, false), "right-press", new HighlightAction(right, true));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "up-release", new HighlightAction(up, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_UP, 0, true), "up-release", new HighlightAction(up, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "down-release", new HighlightAction(down, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_DOWN, 0, true), "down-release", new HighlightAction(down, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "left-release", new HighlightAction(left, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_LEFT, 0, true), "left-release", new HighlightAction(left, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "right-release", new HighlightAction(right, false));
registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_KP_RIGHT, 0, true), "right-release", new HighlightAction(right, false));
}
public void registerKeyBinding(KeyStroke keyStroke, String name, Action action) {
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(keyStroke, name);
am.put(name, action);
}
public JLabel createLabel(String text) {
JLabel label = new JLabel(text);
label.setOpaque(true);
label.setHorizontalAlignment(JLabel.CENTER);
return label;
}
public class HighlightAction extends AbstractAction {
private JLabel label;
private boolean on;
public HighlightAction(JLabel label, boolean on) {
this.label = label;
this.on = on;
}
@Override
public void actionPerformed(ActionEvent e) {
if (on) {
label.setBackground(Color.RED);
label.repaint();
} else {
label.setBackground(null);
}
}
}
}
}