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