Key combination of characters (non-Ctrl or Alt) in Java

前提是你 提交于 2019-12-11 13:55:17

问题


I'm doing a project that needs to detect if a certain key combination has been pressed. Any keys like Ctrl, Alt, A-Z and 0-9 can be used as key combination.

I've searched some codes using KeyStroke.getKeyStroke but it seems like it does not allow combinations without a Ctrl, Shift, Alt, etc.

My application needs to detect combinations even WITHOUT Ctrl or Alt e.g. just a combination of plain A+B+C. Is this can also be done withKeyStroke.getKeyStroke? Replies are greatly appreciated.


回答1:


Depends of if applications type if has GUI or not, for GUI rellated you have to look for

DocumentListener and KeyBindings, and I suggest to refuse implements KeyListener for more than complicated code and Focus workaround

or add addAWTEventListener(AWTEventListener listener, long eventMask) and there is possible listening for KeyEvents and MouseEvents too




回答2:


AFAIK, there is no way to get the status of a key, that is nothing like:

KeyStroke keyStroke = KeyStroke.getKeyStroke("A");
// NOT supported
if (keyStroke.isPressed()) {
  // do something
}

The only thingy supported is notification about change of a single key's status, f.i. at the lowest level in a KeyListener

public void keyPressed(KeyEvent e) {
    if (KeyEvent.VK_A == e.getKeyCode()) {
        ....
    }
}

To handle key combinations (except with special modifier keys), there is no way around keeping track of which keys have been pressed/released to know which are in a pressed state.

Below is an example of doing so on the level of keyBindings. The basic ingredients

  • Trigger: the entity containing the logic of accumulative "arming" of the ultimate action to perform
  • an Action which dis/arms the trigger
  • keyBindings for both released/pressed of particual key strokes, bound to the corresponding arming action

Some code:

// the logic container
public static interface Trigger {
    public void addTrigger(String trigger);
    public void arm(ActionEvent e);
    public void disarm(ActionEvent e);
}

// a particular implementation which uses the actionCommand 
// as identifiers 
public static class ActionTrigger implements Trigger {
    private Action triggered;
    private List<String> triggers = new ArrayList<>();
    private List<String> armed = new ArrayList<>();

    public ActionTrigger(Action triggered) {
        this.triggered = triggered;
    }

    @Override
    public void arm(ActionEvent e) {
        String command = e.getActionCommand();
        if (!triggers.remove(command)) return;
        armed.add(command);
        if (triggers.isEmpty()) {
            triggered.actionPerformed(e);
        }
    }

    @Override
    public void disarm(ActionEvent e) {
        String command = e.getActionCommand();
        if (!armed.remove(command)) return;
        triggers.add(command);
    }

    @Override
    public void addTrigger(String trigger) {
        triggers.add(trigger);
    }
}

// an Action notifying the trigger of dis/arms
public static class ArmingAction extends AbstractAction {
    private Trigger trigger;
    private boolean arm;

    /**
     * @param trigger
     */
    public ArmingAction(Trigger trigger, String command, boolean arm) {
        this.trigger = trigger;
        this.arm = arm;
        putValue(ACTION_COMMAND_KEY, command);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (arm) {
            trigger.arm(e);
        } else {
            trigger.disarm(e);
        }
    }
}

// usage
// the action to trigger with multiple keys
Action action = new AbstractAction("real") {

    @Override
    public void actionPerformed(ActionEvent e) {
        LOG.info("******triggered: " + e);
    }

};

JComponent comp = new JPanel();
ActionMap actionMap = comp.getActionMap();
InputMap inputMap = comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
Trigger trigger = new ActionTrigger(action);
// the key combination
char[] chars = {'A', 'S', 'D'};
for (int i = 0; i < chars.length; i++) {
    // the identifier
    String command = "step" + chars[i];
    trigger.addTrigger(command);
    // binding for pressed
    String pressedID = "pressed" + chars[i];
    actionMap.put(pressedID, new ArmingAction(trigger, command, true));
    inputMap.put(KeyStroke.getKeyStroke("pressed " + chars[i]), pressedID);
    // binding for released
    String releasedID = "released" + chars[i];
    actionMap.put(releasedID, new ArmingAction(trigger, command, false));
    inputMap.put(KeyStroke.getKeyStroke("released " + chars[i]), releasedID);
}


comp.add(new JButton("multibindings ... a s d"));



回答3:


You can play keyPressed and keyReleased method of KeyListener. If u type with ur keyboard, keyPressed event first occour before keyReleased. You can get key event in key pressed and catch that combination key in key released with business logic.

public void keyPressed(KeyEvent evt) {

      keyHit = KeyEvent.getKeyText(evt.getKeyCode());            
      System.out.println("Key Pressed is "+keyHit);

}

public void keyReleased(KeyEvent evt) {

      stringBuffer.append(keyHit)      
      System.out.println("Key Released is "+keyHit);

}




回答4:


I tried many methods and finally found out a method which can be excuted by any two key combination.

Below is my GUI project code:

Boolean k4 = false;
Boolean k5 = false;
Boolean k6 = false;
Boolean ke = false;
Boolean vs = false;
private void jLabel1KeyPressed(java.awt.event.KeyEvent evt) {                                   
int i = evt.getKeyCode();

   switch(i) {
       case  VK_NUMPAD4 :  k4=true;  break;
       case  VK_NUMPAD5 :   k5= true; break;
       case  VK_NUMPAD6 :    k6 = true; break;
       case  VK_ENTER : ke = true; break;
       case   VK_SUBTRACT:  vs=true; break;
   }  
   if(k4==true && ke==true) {

       jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/audit/images/banker.png")));

       k4=false;
       ke=false;

   }
   else if(k5==true &&  ke==true) {

            jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/audit/images/tie.png")));

             k5=false;
             ke=false;
   }
   else if(k6==true && ke==true) {

            jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/audit/images/player.png")));

             k6=false;
             ke=false;
   }

 else if(vs==true && ke==true) {

    jLabel1.requestFocus();
            jLabel1.setIcon(null);

            vs=false;
            ke=false;

   }

  enter_squence();


} 


来源:https://stackoverflow.com/questions/8464727/key-combination-of-characters-non-ctrl-or-alt-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!