【问题标题】:How to determine Key that through Input/ActionMap binding caused AbstractAction to be fired?如何确定通过 Input/ActionMap 绑定导致 AbstractAction 被触发的 Key?
【发布时间】:2013-01-07 00:36:41
【问题描述】:

我正在构建一个 InputMap 和 ActionMap 来将键绑定到方法。许多键会做类似的事情。对于每个绑定键,我在 InputMap 中有一个条目。我想将几个 InputMap 条目与同一个 ActionMap 条目相关联,并使用 AbstractAction.actionPerformed(ActionEvent event) 方法中的 ActionEvent 参数来确定按下/释放/键入了哪个键。我查看了 getID(),测试了 ActionEvent 是否是 KeyEvent(不是)。有没有办法做到这一点,或者我必须进行不同的重构,以便每个唯一的 ActionMap 条目设置一个参数,然后调用我的(参数化)方法?

这是可行的(但很冗长):

    getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0),"myRightHandler");
    getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0),"myLeftHandler");
    getActionMap().put("myRightHandler",new AbstractAction() {
              public void actionPerformed(ActionEvent evt) {
                  System.out.println("Typed Right Arrow");
              }
          });
    getActionMap().put("myLefttHandler",new AbstractAction() {
              public void actionPerformed(ActionEvent evt) {
                  System.out.println("Typed Left Arrow");
              }
          });

这是我想做但找不到魔法的事情:

    getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0),"myGenericHandler");
    getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0),"myGenericHandler");
    getActionMap().put("myGenericHandler",new AbstractAction() {
              public void actionPerformed(ActionEvent evt) {
                  // determine what key caused the event...
                  // evt.getKeyCode() does not work.
                  int keyCode = performMagic(evt);
                  switch (keyCode) {
                      case KeyEvent.VK_RIGHT:
                          System.out.println("Typed Right Arrow");
                          break;
                      case KeyEvent.VK_LEFT:
                          System.out.println("Typed Left Arrow");
                          break;
                      default:
                          System.out.println("Typed unknown key");
                          break;
                  }
              }
          };

【问题讨论】:

  • 那种违反输入/动作映射的点。虽然目前只实现了击键,但 API 已针对其他输入类型进行了设计。关键是,Action 不应该关心它是如何被激活的
  • @MadProgrammer 那我应该改用 KeyListener 吗?
  • 不,输入/动作映射 API 的设计目的是让您更容易使用 KeyListener。设计更好的Action 层次结构。例如,如果您需要提供运动动作,请设计一个基本类,该类知道它在改变什么以及如何改变它(即,将 x 位置更改为 -1)。对于每个移动键,根据您的要求为其分配所需的操作。
  • @MadProgrammer 好的,这就是我在 OP 中提到它时想到的重构。虽然我能够分解出大部分底层实现,但它仍然需要每个 InputMap 条目的“连接器”操作,然后它将使用所需参数调用公共分解实现。对吗?
  • 如果这是你的模型需要做的,那么是的......

标签: java key-bindings keyevent


【解决方案1】:

你应该先试试这个简单的逻辑。

getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0),"myRightHandler");
    getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0),"myLeftHandler");
    getActionMap().put("myRightHandler", new myAction("myRightHandler")); 
    getActionMap().put("myLeftHandler", new myAction("myLeftHandler")); 

    class myAction extends AbstractAction { 

        String str; 

        public myAction(String actName) {

            str = actName; 
        }

        public void actionPerformed(ActionEvent ae) { 

            switch(str) { 

                case "myRightHandler": //Here is code for 'myRightHandler'. 
                break; 

                case "myLeftHandler": //Here is code for 'myLeftHandler'. 
                break; 
                .
                .
                .
                .
                default : //Here is default Action; 
                break;
            }
        }
    } 

现在,您可以通过这种方式添加多对多自定义组合键和操作,并通过 switch 来区分它们。

【讨论】:

  • @mentallurg 代码格式有那么重要吗?你只需要理解我给你的逻辑。
  • 它仍然没有被格式化。这意味着您强迫他人花费宝贵的时间来尝试理解您未格式化的代码。这意味着您不尊重社区。​​span>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-24
  • 2011-08-08
  • 1970-01-01
相关资源
最近更新 更多