javaswingkeylistener

Swing's KeyListener and multiple keys pressed at the same time


is there any conventional way in swing of tracking down the events, when two keyboard keys are pressed at the same time? I have a couple of ideas e.g. remembering the key and event generation time so that we could in a consecutive event handler invocation check the time difference between these two events and decide, whether it's a two-button event or not. But it looks like a kludge.


Solution

  • Use a collection to remember which keys are currently pressed and check to see if more than one key is pressed every time a key is pressed.

    class MultiKeyPressListener implements KeyListener {
        // Set of currently pressed keys
        private final Set<Integer> pressedKeys = new HashSet<>();
            
        @Override
        public synchronized void keyPressed(KeyEvent e) {
            pressedKeys.add(e.getKeyCode());
            Point offset = new Point();
            if (!pressedKeys.isEmpty()) {
                for (Iterator<Integer> it = pressedKeys.iterator(); it.hasNext();) {
                    switch (it.next()) {
                        case KeyEvent.VK_W:
                        case KeyEvent.VK_UP:
                            offset.y = -1;
                            break;
                        case KeyEvent.VK_A:
                        case KeyEvent.VK_LEFT:
                            offset.x = -1;
                            break;
                        case KeyEvent.VK_S:
                        case KeyEvent.VK_DOWN:
                            offset.y = 1;
                            break;
                        case KeyEvent.VK_D:
                        case KeyEvent.VK_RIGHT:
                            offset.x = 1;
                            break;
                    }
                }
            }
            System.out.println(offset); // Do something with the offset.
        }
        
        @Override
        public synchronized void keyReleased(KeyEvent e) {
            pressedKeys.remove(e.getKeyCode());
        }
        
        @Override
        public void keyTyped(KeyEvent e) { /* Event not used */ }
    }