简体   繁体   English

Swing 的 KeyListener 和同时按下的多个键

[英]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 eg 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.但它看起来像一团糟。

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) {
        pressed.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) { /* Not used */ }
}

The KeyListener interface allows detecting key pressing and releasing separately. KeyListener 接口允许分别检测按键按下和释放。 Therefore, you can maintain a set of "active keys", ie keys which have been pressed but not released yet.因此,您可以维护一组“活动键”,即已按下但尚未释放的键。

If after 7 years I tried to do this (just to see if it is possible), someone else might as well...如果 7 年后我尝试这样做(只是为了看看是否可能),其他人也可能......

The code below controls the movement with 8 axis direction, explanation in the comments.下面的代码控制8轴方向的运动,注释中说明。 But basically, the KeyListener just define where it is possible to move, then a Thread will combine the possible destinations and move the JLabel .但基本上, 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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM