Как да определим ключ, който чрез свързване на 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 Добре, това е рефакторингът, който имах предвид, когато го споменах в OP. Въпреки че бих могъл да отделя голяма част от основната реализация, тя все още ще изисква действие на конектор за всеки запис на 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