KeyListener Swing и несколько клавиш нажаты одновременно - PullRequest
12 голосов
/ 12 апреля 2010

Есть ли какой-нибудь обычный способ отслеживания событий, когда одновременно нажимаются две клавиши клавиатуры? У меня есть пара идей, например запоминание ключа и времени генерации события, чтобы мы могли при последовательном вызове обработчика события проверить разницу во времени между этими двумя событиями и решить, является ли это событием с двумя кнопками или нет. Но это похоже на кучу.

Ответы [ 3 ]

16 голосов
/ 12 апреля 2010

Используйте коллекцию, чтобы запомнить, какие клавиши были нажаты в данный момент, и проверить, нажимается ли более одной клавиши при каждом нажатии клавиши.

class MultiKeyPressListener implements KeyListener {

    // Set of currently pressed keys
    private final Set<Character> pressed = new HashSet<Character>();

    @Override
    public synchronized void keyPressed(KeyEvent e) {
        pressed.add(e.getKeyChar());
        if (pressed.size() > 1) {
            // More than one key is currently pressed.
            // Iterate over pressed to get the keys.
        }
    }

    @Override
    public synchronized void keyReleased(KeyEvent e) {
        pressed.remove(e.getKeyChar());
    }

    @Override
    public void keyTyped(KeyEvent e) {/* Not used */ }
}
2 голосов
/ 12 апреля 2010

Интерфейс KeyListener позволяет определять нажатие и отпускание клавиш по отдельности. Следовательно, вы можете сохранить набор «активных клавиш», то есть клавиш, которые были нажаты, но еще не отпущены.

0 голосов
/ 01 июля 2019

Если через 7 лет я попытался это сделать (просто чтобы посмотреть, возможно ли это), кто-то еще мог бы ...

Код ниже управляет движением в направлении 8 осей, объяснение в комментариях. Но в основном KeyListener просто определяет, куда можно переместиться, тогда Thread объединит возможные направления и переместит JLabel.

package tests;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Move8Axis extends JFrame {

    private static final long serialVersionUID = 7722803326073073681L;

    private boolean left = false;
    private boolean up = false;
    private boolean down = false;
    private boolean right = false;

    private JLabel lbl = new JLabel("#");


    public Move8Axis() {
        // Just setting up the window and objects
        setSize(400, 400);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
        lbl.setBounds(100, 100, 20, 20);
        add(lbl);
        setLocationRelativeTo(null);

        // Key listener, will not move the JLabel, just set where to
        addKeyListener(new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {}
            @Override
            public void keyReleased(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_LEFT) left = false;
                if (e.getKeyCode() == KeyEvent.VK_RIGHT) right = false;
                if (e.getKeyCode() == KeyEvent.VK_UP) up = false;
                if (e.getKeyCode() == KeyEvent.VK_DOWN) down = false;
            }
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_LEFT) left = true;
                if (e.getKeyCode() == KeyEvent.VK_RIGHT) right = true;
                if (e.getKeyCode() == KeyEvent.VK_UP) up = true;
                if (e.getKeyCode() == KeyEvent.VK_DOWN) down = true;
            }
        });

        // This thread will read the 4 variables left/right/up/down at every 30 milliseconds
        // It will check the combination of keys (left and up, right and down, just left, just up...) 
        // And move the label 3 pixels
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {

                    while (true) {  
                        if (left && up) {
                            lbl.setBounds(lbl.getX() - 3, lbl.getY() - 3, 20, 20);
                        } else if (left && down) {
                            lbl.setBounds(lbl.getX() - 3, lbl.getY() + 3, 20, 20);
                        } else if (right && up) {
                            lbl.setBounds(lbl.getX() + 3, lbl.getY() - 3, 20, 20);
                        } else if (right && down) {
                            lbl.setBounds(lbl.getX() + 3, lbl.getY() + 3, 20, 20);
                        } else if (left) {
                            lbl.setBounds(lbl.getX() - 3, lbl.getY(), 20, 20);
                        } else if (up) {
                            lbl.setBounds(lbl.getX(), lbl.getY() - 3, 20, 20);
                        } else if (right) {
                            lbl.setBounds(lbl.getX() + 3, lbl.getY(), 20, 20);
                        } else if (down) {
                            lbl.setBounds(lbl.getX(), lbl.getY() + 3, 20, 20);
                        } 

                        Thread.sleep(30);
                    }

                } catch (Exception ex) {
                    ex.printStackTrace();
                    System.exit(0);
                }
            }
        }).start();
    }

    public static void main(String[] args) {
        new Move8Axis();
    }
}
...