为什么我的Java密钥输入有时只能起作用?

时间:2017-05-14 18:09:54

标签: java input jframe sprite keystroke

我一直试图在我的代码中添加一些关键输入一段时间,但由于某种原因它不会在一个类中工作,但在另一个类中它工作得很好,我不知道为什么。这里的例子是可以工作的那个。

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类并获得相同的响应时,我发现我已经尝试更改顺序,每次我都没有得到响应,即使它们没有错误消息。该特定问题的代码在我的主要方法

 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类的其余部分帮助弄清问题是什么,可以在我的其他问题的链接中找到整个问题。 Why can't I erase my Sprite

1 个答案:

答案 0 :(得分:1)

您的部分问题是与焦点相关的问题。

使用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")这样的内容,因为这可能会为 SHIFT + W 返回KeyStroke,这可能不是'你想要什么。而是使用KeyStroke.getKeyStroke(int, int),这将使您更多地控制它