跳过Java KeyEvents

跳过Java KeyEvents,java,keyevent,Java,Keyevent,我有一个程序,用户可以按一个键来执行操作。一件事只需要一点时间。用户还可以按住该键并连续多次执行该操作。问题在于keyPress()事件排队的速度比处理事件的速度快。这意味着,在用户释放密钥后,将继续处理先前按住密钥的用户排队等待的事件。我还注意到,直到处理完最后一个按键事件之后,才发生keyRelease事件,而不管实际释放的是什么时候。我想两者都可以 1.检测按键释放事件并忽略未来的按键事件,直到用户实际再次按键。 2.在第一个按键事件完成之前,不要执行后续的按键事件,然后在未按下按键时检测

我有一个程序,用户可以按一个键来执行操作。一件事只需要一点时间。用户还可以按住该键并连续多次执行该操作。问题在于keyPress()事件排队的速度比处理事件的速度快。这意味着,在用户释放密钥后,将继续处理先前按住密钥的用户排队等待的事件。我还注意到,直到处理完最后一个按键事件之后,才发生keyRelease事件,而不管实际释放的是什么时候。我想两者都可以 1.检测按键释放事件并忽略未来的按键事件,直到用户实际再次按键。 2.在第一个按键事件完成之前,不要执行后续的按键事件,然后在未按下按键时检测,然后停止


有人知道怎么做吗?

您必须选择选项1。一旦开始较长的流程,请将布尔值设置为某个时间,以指示您正在处理该流程,并抛出其他传入的相同请求。完成此过程后,将布尔值设置回原位并允许其他事件。

免责声明:我感觉不舒服,因此此代码非常可怕。。它也病了

我希望发生的事情:访问DirectInput以获取键盘状态,而不是事件。但这远远超出了这个问题的范围。因此,我们将保持自己的行动状态

您遇到的问题是,您正在UI线程中执行操作。您需要生成工作线程并忽略后续事件,直到操作完成

在我给出的示例中,当按下或按住字母“a”时,我开始一个新动作。在第一个操作完成之前,它不会生成另一个操作。该操作会更新表单上的标签,显示在完成之前还剩多少个“周期”

还有另一个标签显示到目前为止已经发生了多少操作

产生新动作

重要的部分是让所有UI键事件发生,而不是阻塞UI线程导致它们排队

public void keyPressed(KeyEvent e) {
    char keyChar = e.getKeyChar();
    System.out.println("KeyChar: " + keyChar);
    // Press a to start an Action
    if (keyChar == 'a') {
        if (!mAction.isRunning()) {
            mTotalActions.setText("Ran " + (++mTotalActionsRan) + " actions.");
            System.out.println("Starting new Action");
            Thread thread = new Thread(new Runnable() {
                public void run() {
                    mAction.run();
                }
            });
            thread.start();
        }
    }
}
对UI线程的更新

如果您的操作对用户界面执行任何类型的更新,则需要使用
SwingUtilities.invokeLater
方法。此方法将对要在UI线程中运行的代码进行排队。不能在UI线程以外的线程中修改用户界面。此外,仅使用SwingUtilities更新UI组件。任何不调用组件方法的计算、处理等都可以在SwingUtilities.invokeLater的范围之外完成

完整代码列表

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package stackoverflow_4589538;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class Main extends JFrame {

    private JLabel mActionLabel;
    private JLabel mTotalActions;
    private int mTotalActionsRan;

    private class MyAction {

        private boolean mIsRunning = false;

        public void run() {
            // Make up a random wait cycle time
            final int cycles = new Random().nextInt(100);
            for (int i = 0; i < cycles; ++i) {
                final int currentCycle = i;
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                }
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                            mActionLabel.setText("Cycle " + currentCycle + " of " + cycles);
                    }
                });
            }
            completed();
        }

        public synchronized void start() {
            mIsRunning = true;
        }

        public synchronized void completed() {
            mIsRunning = false;
        }

        public synchronized boolean isRunning() {
            return mIsRunning;
    }
}
    private MyAction mAction = new MyAction();

    public Main() {
        setLayout(null);
        setBounds(40, 40, 800, 600);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                char keyChar = e.getKeyChar();
                System.out.println("KeyChar: " + keyChar);
                // Press A to start an Action
                if (keyChar == 'a') {
                if (!mAction.isRunning()) {
                        mTotalActions.setText("Ran " + (++mTotalActionsRan) + " actions.");
                        System.out.println("Starting new Action");
                        Thread thread = new Thread(new Runnable() {

                            public void run() {
                                mAction.run();
                            }
                        });
                        // I had this within the run() method before
                        // but realized that it is possible for another UI event
                        // to occur and spawn another Action before, start() had
                        // occured within the thread
                        mAction.start();
                        thread.start();
                    }
                }
            }

        @Override
            public void keyReleased(KeyEvent e) {
            }
        });

        mActionLabel = new JLabel();
        mActionLabel.setBounds(10, 10, 150, 40);

        mTotalActions = new JLabel();
        mTotalActions.setBounds(10, 50, 150, 40);

        add(mActionLabel);
        add(mTotalActions);
    }    

    public static void main(String[] args) {
        new Main().setVisible(true);
    }
}
/*
*要更改此模板,请选择工具|模板
*然后在编辑器中打开模板。
*/
包裹堆垛溢出_4589538;
导入java.awt.event.KeyAdapter;
导入java.awt.event.KeyEvent;
导入java.util.Random;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.SwingUtilities;
公共类主框架{
私人JLabel mActionLabel;
私人JLabel mTotalActions;
私人内特mTotalActionsRan;
私人集体诉讼{
private boolean mIsRunning=false;
公开募捐{
//组成一个随机的等待周期时间
最终整数周期=新随机().nextInt(100);
对于(int i=0;i