Java Swing';s键侦听器,同时按下多个键

Java Swing';s键侦听器,同时按下多个键,java,swing,keylistener,Java,Swing,Keylistener,当同时按下两个键盘键时,在swing中是否有跟踪事件的常规方法? 我有一些想法,例如记住键和事件生成时间,这样我们就可以在连续的事件处理程序调用中检查这两个事件之间的时间差,并确定它是否是两个按钮的事件。但是它看起来像一个乱七八糟的东西。KeyListener界面允许分别检测按键和释放。因此,您可以保留一组“活动键”,即已按下但尚未释放的键。使用集合来记住当前按下的键,并检查每次按下键时是否按下多个键 类MultiKeyPressListener实现KeyListener{ //当前按下的一组键

当同时按下两个键盘键时,在swing中是否有跟踪事件的常规方法?
我有一些想法,例如记住键和事件生成时间,这样我们就可以在连续的事件处理程序调用中检查这两个事件之间的时间差,并确定它是否是两个按钮的事件。但是它看起来像一个乱七八糟的东西。

KeyListener界面允许分别检测按键和释放。因此,您可以保留一组“活动键”,即已按下但尚未释放的键。

使用集合来记住当前按下的键,并检查每次按下键时是否按下多个键

类MultiKeyPressListener实现KeyListener{
//当前按下的一组键
private final Set pressedKeys=new HashSet();
@凌驾
按下公共同步无效键(按键事件e){
添加(例如getKeyCode());
点偏移=新点();
如果(!pressedKeys.isEmpty()){
for(Iterator it=pressedKeys.Iterator();it.hasNext();){
开关(it.next()){
case KeyEvent.VK_W:
case KeyEvent.VK_UP:
偏移量y=-1;
打破
case KeyEvent.VK_A:
case KeyEvent.VK_左:
偏移量x=-1;
打破
case KeyEvent.VK_S:
case KeyEvent.VK_向下:
偏移量y=1;
打破
case KeyEvent.VK_D:
case KeyEvent.VK_RIGHT:
偏移量x=1;
打破
}
}
}
System.out.println(offset);//用偏移量做些什么。
}
@凌驾
公共同步无效密钥释放(密钥事件e){
按按键。移除(如getKeyCode());
}
@凌驾
public void keyTyped(KeyEvent e){/*未使用*/}
}

如果7年后我试图这么做(只是想看看是否可行),其他人也可能会这么做

下面的代码控制8轴方向的移动,注释中有说明。但是基本上,
keylister
只定义可以移动的位置,然后
线程将组合可能的目标并移动
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();
    }
}

对不起,我不明白怎么用这个。你能再给我举个例子吗?如何同时使用每个键?因为Java 1.7
HashSet
必须声明为:
Set pressed=new HashSet()@Ernestatsgruodis不是“必须”,你的意思是“可能”。不太冗长是可选的。无论如何,我更新了它,并添加了一个实际的用法示例。@K_7:集合将强制项目的唯一性,并且我估计会有更快的查找速度(如果您使用HashSet示例)。谢谢你的确认!与AWT/Swing组件的交互必须仅从以下位置发生:。因此,构造函数调用和标签更改不能在另一个线程中发生。对于更新标签,重复也很合适。