为什么我的 Java 键输入有时会起作用?
Why does my Java key input work only sometimes?
一段时间以来,我一直在尝试向我的代码中添加一些关键输入,但出于某种原因,它在一个 class 中不起作用,但在另一个中它工作得很好,但我不不知道为什么。这是一个确实有效的例子。
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.KeyStroke;
public class KeyStrokeSample {
public static void main(String[] a) {
String ACTION_KEY = "theAction";
JFrame frame = new JFrame("KeyStroke Sample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton buttonA = new JButton("Press 'W'");
Action actionListener = new AbstractAction() {
public void actionPerformed(ActionEvent actionEvent) {
JButton source = (JButton) actionEvent.getSource();
System.out.println(source.getText());
}
};
KeyStroke W = KeyStroke.getKeyStroke("W");
InputMap inputMap = buttonA.getInputMap();
inputMap.put(W, ACTION_KEY);
ActionMap actionMap = buttonA.getActionMap();
actionMap.put(ACTION_KEY, actionListener);
frame.add(buttonA);
frame.setSize(400, 200);
frame.setVisible(true);
}
}
然而,当我尝试将其放入我的 Sprite class 并获得相同的响应时,我尝试更改顺序,但每次我都没有收到响应,即使它们没有错误信息。该特定问题的代码在我的主要方法下面
public static void main(String[] args) throws IOException,
InterruptedException{
//setting the window and sprites
Sprite orig_world = new Sprite(ImageIO.read(new
File("C:/Users/sfiel42/Documents/game/castles.png")),0,0);
Sprite world = new Sprite(ImageIO.read(new
File("C:/Users/sfiel42/Documents/game/castles.png")),0,0);
JLabel label = new JLabel();
label.setLocation(0,0);
label.setIcon(new ImageIcon(world.getSprite()));
label.setVisible(true);
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(783,615);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(label);
Sprite archer = new Sprite(ImageIO.read(new
File("C:/Users/sfiel42/Documents/game/archer.png")),30,40);
String ACTION_KEY = "theAction";
JButton buttonA = new JButton("Button For W");
Action actionListener = new AbstractAction() {
public void actionPerformed(ActionEvent actionEvent) {
JButton source = (JButton) actionEvent.getSource();
System.out.println(source.getText());
}
};
KeyStroke W = KeyStroke.getKeyStroke("W");
InputMap inputMap = buttonA.getInputMap();
inputMap.put(W, ACTION_KEY);
ActionMap actionMap = buttonA.getActionMap();
actionMap.put(ACTION_KEY, actionListener);
buttonA.setVisible(false);
frame.add(buttonA);
如果你想要其余的 sprite class 帮助找出问题所在,可以在 link 我的其他问题中找到整个问题。
您的部分问题与焦点相关。
当您使用 getInputMap()
时,您要求 InputMap
仅当组件具有键盘焦点时才响应按键事件。
相反,请考虑使用 JComponent#getInputMap(int)
并向其传递其他条件之一,例如 JComponent#WHEN_IN_FOCUSED_WINDOW
此外,我不会将键绑定注册到按钮,而是将它们绑定到父组件并重新使用 Action
和按钮
public class MoveAction extends AbstractAction {
public MoveAction(String name) {
putValue(NAME, name);
}
public void actionPerformed(ActionEvent actionEvent) {
System.out.println(getValue(NAME));
}
}
//...
MoveAction action = new MoveAction("W");
String ACTION_KEY = "theAction";
KeyStroke W = KeyStroke.getKeyStroke(KeyEvent.VK_W, 0);
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
inputMap.put(W, ACTION_KEY);
ActionMap actionMap = getActionMap();
actionMap.put(ACTION_KEY, action);
JButton buttonA = new JButton(action);
buttonA.setVisible(false); // This worries me :P
以这种方式使用 Action
可以产生更加灵活和可重复使用的解决方案
我也会避免使用 KeyStroke.getKeyStroke("W")
之类的东西,因为这可能 return 一个 KeyStroke
for SHIFT+W 这可能不是您想要的。而是使用 KeyStroke.getKeyStroke(int, int)
,这将使您更好地控制它
一段时间以来,我一直在尝试向我的代码中添加一些关键输入,但出于某种原因,它在一个 class 中不起作用,但在另一个中它工作得很好,但我不不知道为什么。这是一个确实有效的例子。
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.KeyStroke;
public class KeyStrokeSample {
public static void main(String[] a) {
String ACTION_KEY = "theAction";
JFrame frame = new JFrame("KeyStroke Sample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton buttonA = new JButton("Press 'W'");
Action actionListener = new AbstractAction() {
public void actionPerformed(ActionEvent actionEvent) {
JButton source = (JButton) actionEvent.getSource();
System.out.println(source.getText());
}
};
KeyStroke W = KeyStroke.getKeyStroke("W");
InputMap inputMap = buttonA.getInputMap();
inputMap.put(W, ACTION_KEY);
ActionMap actionMap = buttonA.getActionMap();
actionMap.put(ACTION_KEY, actionListener);
frame.add(buttonA);
frame.setSize(400, 200);
frame.setVisible(true);
}
}
然而,当我尝试将其放入我的 Sprite class 并获得相同的响应时,我尝试更改顺序,但每次我都没有收到响应,即使它们没有错误信息。该特定问题的代码在我的主要方法下面
public static void main(String[] args) throws IOException,
InterruptedException{
//setting the window and sprites
Sprite orig_world = new Sprite(ImageIO.read(new
File("C:/Users/sfiel42/Documents/game/castles.png")),0,0);
Sprite world = new Sprite(ImageIO.read(new
File("C:/Users/sfiel42/Documents/game/castles.png")),0,0);
JLabel label = new JLabel();
label.setLocation(0,0);
label.setIcon(new ImageIcon(world.getSprite()));
label.setVisible(true);
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(783,615);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(label);
Sprite archer = new Sprite(ImageIO.read(new
File("C:/Users/sfiel42/Documents/game/archer.png")),30,40);
String ACTION_KEY = "theAction";
JButton buttonA = new JButton("Button For W");
Action actionListener = new AbstractAction() {
public void actionPerformed(ActionEvent actionEvent) {
JButton source = (JButton) actionEvent.getSource();
System.out.println(source.getText());
}
};
KeyStroke W = KeyStroke.getKeyStroke("W");
InputMap inputMap = buttonA.getInputMap();
inputMap.put(W, ACTION_KEY);
ActionMap actionMap = buttonA.getActionMap();
actionMap.put(ACTION_KEY, actionListener);
buttonA.setVisible(false);
frame.add(buttonA);
如果你想要其余的 sprite class 帮助找出问题所在,可以在 link 我的其他问题中找到整个问题。
您的部分问题与焦点相关。
当您使用 getInputMap()
时,您要求 InputMap
仅当组件具有键盘焦点时才响应按键事件。
相反,请考虑使用 JComponent#getInputMap(int)
并向其传递其他条件之一,例如 JComponent#WHEN_IN_FOCUSED_WINDOW
此外,我不会将键绑定注册到按钮,而是将它们绑定到父组件并重新使用 Action
和按钮
public class MoveAction extends AbstractAction {
public MoveAction(String name) {
putValue(NAME, name);
}
public void actionPerformed(ActionEvent actionEvent) {
System.out.println(getValue(NAME));
}
}
//...
MoveAction action = new MoveAction("W");
String ACTION_KEY = "theAction";
KeyStroke W = KeyStroke.getKeyStroke(KeyEvent.VK_W, 0);
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
inputMap.put(W, ACTION_KEY);
ActionMap actionMap = getActionMap();
actionMap.put(ACTION_KEY, action);
JButton buttonA = new JButton(action);
buttonA.setVisible(false); // This worries me :P
以这种方式使用 Action
可以产生更加灵活和可重复使用的解决方案
我也会避免使用 KeyStroke.getKeyStroke("W")
之类的东西,因为这可能 return 一个 KeyStroke
for SHIFT+W 这可能不是您想要的。而是使用 KeyStroke.getKeyStroke(int, int)
,这将使您更好地控制它