Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将多个键绑定附加到java swing对象_Java_Swing_User Interface_Key Bindings - Fatal编程技术网

将多个键绑定附加到java swing对象

将多个键绑定附加到java swing对象,java,swing,user-interface,key-bindings,Java,Swing,User Interface,Key Bindings,我有一个问题,我试图让“玩家”图标在我的JFrame周围移动使用键盘控件。我有一个对象,我想用w、a、s和d键四处移动。我之所以使用键绑定,是因为在我的研究中,它们似乎更适合此任务 我已经成功地将所有想要的键连接到我的图标上,它们都会调用动作,唯一的问题是我无法区分按下了哪个按钮。我希望通过在我的操作事件上使用getActionCommand()可以以某种方式实现这一点。到目前为止还没有成功 我所看到的其他示例似乎对此有一个解决方案,但它们也有很多额外的代码,注释很少,因此很难确定实际发生了什么

我有一个问题,我试图让“玩家”图标在我的JFrame周围移动使用键盘控件。我有一个对象,我想用w、a、s和d键四处移动。我之所以使用键绑定,是因为在我的研究中,它们似乎更适合此任务

我已经成功地将所有想要的键连接到我的图标上,它们都会调用动作,唯一的问题是我无法区分按下了哪个按钮。我希望通过在我的操作事件上使用
getActionCommand()
可以以某种方式实现这一点。到目前为止还没有成功

我所看到的其他示例似乎对此有一个解决方案,但它们也有很多额外的代码,注释很少,因此很难确定实际发生了什么。它们似乎都涉及多个类,包括方法和字段。我希望这段代码少一点涉及

我想知道的是:什么是最好的方式让这个工作?我可以用键绑定吗?它真的需要复杂吗

我真的很感激任何帮助,即使这只是我可以用来帮助自己找到答案的来源

以下是我现有的代码:

//My method that gets called by the constructor
//This is all based on a tutorial I found: ftp://ecs.csus.edu/clevengr/133/handouts/UsingJavaKeyBindings.pdf
//player is just an image icon
public static void setUpKeys() {
    InputMap playerMap = player.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);

    KeyStroke wKey = KeyStroke.getKeyStroke('w');
    KeyStroke aKey = KeyStroke.getKeyStroke('a');
    KeyStroke sKey = KeyStroke.getKeyStroke('s');
    KeyStroke dKey = KeyStroke.getKeyStroke('d');
    KeyStroke wSprint = KeyStroke.getKeyStroke((char) ('w' + KeyEvent.SHIFT_DOWN_MASK)); //As a side note, what's the best way to get it to move faster when the shift key is held down? Not that important, but if someone happens to know, that'd be great

    playerMap.put(wKey, "moveUp");
    playerMap.put(aKey, "moveLeft");
    playerMap.put(sKey, "moveDown");
    playerMap.put(dKey, "moveRight");
    playerMap.put(wSprint, "moveFast");

    ActionMap playerAction = player.getActionMap();

    playerAction.put("moveUp", playerMoved);
    playerAction.put("moveLeft", playerMoved);
    playerAction.put("moveDown", playerMoved);
    playerAction.put("moveRight", playerMoved);
    playerAction.put("moveFast", playerMoved);
}
以下是我的playerMoved动作:

static Action playerMoved = new AbstractAction() {
    //This isn't important, just put it in instead of suppressing the warning
    private static final long serialVersionUID = 2L; 

    //This doesn't do anything yet, just gives console confirmation
    public void actionPerformed(ActionEvent e) {
        System.out.println("Activated");

        //Here's what I was talking about with the getActionCommand() not working
        if (e.getActionCommand().equals("moveUp")) {
            System.out.println("up");
        }
    }
};
如果有人需要我的代码的任何其他部分,我可以提供它。我只是想把它缩减到我觉得对这个问题很重要的程度

我希望通过在我的动作事件上使用getActionCommand()可以以某种方式实现这一点

您不想这样做,因为您将尝试使用“操作命令”进行“处理”。这不是一个好的设计,因为它会导致嵌套的if/else语句

相反,您需要创建一个接受参数以控制移动的
操作。因此,您需要4个单独的动作来控制移动。有关此方法的完整工作示例,请参见中的
MotionWithKeyBindings
示例

它演示了如何通过为
操作
指定参数使简单的
操作
可重用。这比您当前的操作提供了更大的灵活性

注1:

操作中使用以下调试代码:

System.out.println("Activated");
与其简单地显示硬编码的值,不如执行以下操作

System.out.println( e.getActionCommand() );
在这种情况下,您应该注意值是“a,s,w,d”,这是用来调用
操作的
击键

因此,这意味着if语句应该测试上述任何一个字符,而不是字符串“moveUp”,它是用于在
ActionMap
中标识
操作的字符串

但是,如上所述,这不是您应该使用的解决方案,我只是想更好地解释“操作命令”是如何确定的

注2:

您可能希望使用单个
操作
getActionCommand()
方法的唯一时间是希望将“Action命令”用作
操作
的“数据”时


有关此方法的示例,请查看:。这是一个简单数字输入面板的示例,其中按下的数字键被添加到文本字段中。因此,关键字符成为文本字段的数据,不需要进行特殊处理。

作为您可能会提到的几个答案的作者,我必须请您尝试改进您的问题——请更具体地说明您所指的代码,它的混淆之处,您试图用自己的代码实现的目标。。。您可能需要某种类型的动画循环--您计划如何实现它?此外,大多数发布的答案都显示了一个有效的、可编译的、可运行的代码,这是您的问题所缺少的。您的
playerMoved
Action
应该对其应用某种标识符/delta,以便在调用它时,它知道它必须做什么-基本上使用相同的
操作实例是个坏主意
它们似乎都涉及多个类,带有方法和字段。
-我没有见过。它们通常涉及一个基本的
动作
类,该类接受参数,因此您可以轻松地定义运动,而无需硬编码。它们通常还定义了一种方法,用于将键绑定分配给击键和操作,以简化代码,避免重复同一代码多次<代码>我无法区分按下了哪个按钮
——这就是为什么在创建对象时要将参数传递给对象。例如,请查看中的
运动WithKeyBindings
代码。如果你有什么不明白的地方,那就问一个具体的问题。我们猜不出您对可重用类和方便方法有什么困惑。注意:理解了这个基本示例后,您可能希望继续学习
键盘动画
示例,该示例添加了更多功能来处理同时按下的多个键。@VasylLyashkevych,该示例没有说明如何使用参数化操作,以便您可以通过更改参数使用相同的操作来上/下/左/右移动。OPs问题是关于确定在使用相同操作时按下的键。感谢您的贡献。我意识到我的问题没有用最好的方式表达,因此可能不必要地难以回答。我很高兴指出我可以打印出getActionCommand,因为我甚至没有想到这一点。我会考虑你所说的,在这个问题上找到我自己的方法。