Как определить ключ, который через привязку Input/ActionMap вызвал срабатывание AbstractAction?

Я создаю InputMap и ActionMap для привязки ключей к методам. Многие ключи будут делать аналогичные вещи. У меня есть одна запись в InputMap для каждого связанного ключа. Я хотел бы связать несколько записей InputMap с одной и той же записью ActionMap и использовать параметр ActionEvent в методе AbstractAction.actionPerformed(ActionEvent event), чтобы определить, какая клавиша была нажата/отпущена/набрана. Я просмотрел 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;
                  }
              }
          };

person ags    schedule 07.01.2013    source источник
comment
Такой вид нарушает точку сопоставления ввода/действия. Хотя в настоящее время реализованы только нажатия клавиш, API был разработан для других типов ввода. Дело в том, что Action не должно волновать, как он был активирован.   -  person MadProgrammer    schedule 07.01.2013
comment
@MadProgrammer Так должен ли я вместо этого использовать KeyListener?   -  person ags    schedule 07.01.2013
comment
Нет, API сопоставления ввода/действия был разработан для того, чтобы сделать его проще, чем прибегать к использованию KeyListener. Разработайте лучшую Action иерархию. Если, например, вам необходимо обеспечить действия по перемещению, спроектируйте базовый класс, который знает, что он меняет и как он это меняет (т. е. изменяет позицию x на -1). Для каждой клавиши движения назначьте требуемое действие, установленное вашими требованиями.   -  person MadProgrammer    schedule 07.01.2013
comment
@MadProgrammer Хорошо, это рефакторинг, который я имел в виду, когда упомянул об этом в ОП. Хотя я мог бы выделить большую часть базовой реализации, для каждой записи InputMap все равно потребовалось бы действие коннектора, которое затем вызывало бы общую факторизованную реализацию с необходимыми параметрами. Это правильно?   -  person ags    schedule 07.01.2013
comment
Если это то, что нужно вашей модели, то да...   -  person MadProgrammer    schedule 07.01.2013


Ответы (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;
            }
        }
    } 

Теперь таким образом вы можете добавлять много-много пользовательских комбинаций клавиш и действий и различать их с помощью переключателя.

person Harshad Khandagale    schedule 07.07.2018
comment
@mentallurg Так ли важен формат кода? Вам просто нужно понять логику, которую я вам дал. - person Harshad Khandagale; 07.07.2018
comment
Он до сих пор не отформатирован. Это означает, что вы заставляете других тратить свое драгоценное время на то, чтобы понять ваш неформатированный код. Это означает, что вы не уважаете сообщество. - person mentallurg; 08.07.2018