初学JAVA,键盘监听中,我想延时2秒后再确定指定键是否按下,以防止误操作,应该如何处理?

rookie108 2016-11-10 04:05:50
我原想着是在public void keyPressed(KeyEvent e)里面延时2秒后再去判断q键是否按下,但试了,发现点击按键后马上离开,2秒后还是显示q键被按下。应该如何处理q键按下时间没超过2秒系统就不理它呢?
代码如下:
/*
* 测试q键按下2秒后才执行相应动作
*/
package test;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;

public class KeyEventTest extends JFrame implements KeyListener {
public static void main(String[] args) {
KeyEventTest ket = new KeyEventTest();
}

public KeyEventTest() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
this.setTitle("KeyEventTest");
this.setSize(300, 300);
this.setVisible(true);
addKeyListener(this);
}

public void keyPressed(KeyEvent e) {
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}

// 延时2秒,检测是否还有按下q键(键值81)
if (e.getKeyCode() == 81) {
System.out.println("OK!");
}else{
System.out.println("no press \"q\" key!");
}
}

public void keyReleased(KeyEvent e) {}

public void keyTyped(KeyEvent e) {}
}
...全文
522 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
逗泥丸的平方 2016-11-15
  • 打赏
  • 举报
回复
引用 4 楼 rookie108 的回复:
唉,我把这个当成了单片机里面处理按键消抖一样了,思路错了 现在我想这样处理:分别取得按键按下的时间和按键松开的时间,然后求出两者之差,大于2000ms就是有效,否则无效。这样是否可行?对系统资源浪费大吗?
/*
 * 测试q键按下2秒后才执行相应动作
 */
package test;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;

public class KeyEventTest extends JFrame implements KeyListener {
	long pressTime=0;
	long releasedTime=0;
	boolean keyEnable=true;
	
	public static void main(String[] args) {
		KeyEventTest ket = new KeyEventTest();
	}

	public KeyEventTest() {
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLayout(null);
		this.setTitle("KeyEventTest");
		this.setSize(300, 300);
		this.setVisible(true);
		addKeyListener(this);
	}

	public void keyPressed(KeyEvent e) {
		if (keyEnable ==true) {
			pressTime = System.currentTimeMillis();
			keyEnable=false;
		}
	}

	public void keyReleased(KeyEvent e) {
		releasedTime=System.currentTimeMillis();
		long afterTime=releasedTime-pressTime;
		if((e.getKeyCode()==81)&&(afterTime>=2000)){
			System.out.println("有效按键,键码="+e.getKeyCode());
		}else{
			System.out.println("无效按键或按下时间太短,键码="+e.getKeyCode()+"  按下时间="+String.valueOf(afterTime)+"ms");
		}
		keyEnable=true;
	}

	public void keyTyped(KeyEvent e) {
	}
}
这种写法相对来说应该是非常节约资源 的了 但是不知道是不是符合你的要求. 如果说是鼠标左键点button这种,看起来挺合适的, 看你需要的是"松开"的时候生效,还是2秒后生效了. 其实时钟的消耗应该不是很大.. 除非你开发的东西对性能要求特别高 ?
attilax 2016-11-11
  • 打赏
  • 举报
回复
引用 5 楼 rookie108 的回复:
[quote=引用 3 楼 attilax 的回复:] 这个使用watchdog设计模式吧。。很好解决 Atitit. 设计模式watchdog 技术原理 v2 qb9 attilax总结 watchdog 底层是使用定时器实现的。。 1 在判断延时防止误按按钮的时候很有用,原理与流程 1 源码 1 watchdog 底层是使用定时器实现的。。 主要原理,是需要定时喂狗,负责狗就会复位程序。。 在判断延时防止误按按钮的时候很有用,原理与流程 首先默认情况下不断有定时线程进行喂狗操作,所以不会触发按钮事件。。 当按钮按下式,就终止了喂狗,2秒后狗饿了,就出来触发了按钮事件。。 如果在俩妙内,谈起按键 ,就又开始定时喂狗了。。 源码 Watchdog dog=new Watchdog(100); //这里初始化watchdog的精度,即每隔多少毫秒增加一个饥饿值,精度越高,越精确。。 dog.MaxFeedTime=2000;//喂狗的最大时间,单位毫秒,超过此时间,狗就饥饿了,出来触发事件来。。 //狗饥饿了,出来触发事件的定义 dog.hungryEvt=()->{ System.out.println("btn evt..."); }; dog.ini(); //测试 每隔一秒喂狗,就不会触发事件 while(true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } dog.feed(); } 延时2秒后 参考 Watchdog实现分析 - __Shadow - 博客园_files WDT(WatchDog Timer结构)_百度百科_files 作者:: 绰号:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿尔 拉帕努伊 )  汉字名:艾提拉(艾龙),   EMAIL:1466519819@qq.com 转载请注明来源: http://blog.csdn.net/attilax Atiend
谢谢。喂狗这种方法也不错。但我查了watchdog似乎不是JAVA的类吧?需要自己去编写一个watchdog的类?相比我上面那种计算按键按下和松开的时间差,两者对系统资源消耗哪个大呢?[/quote] 计算时间差不错,简洁,实质是jvm做时间计算了。。不用自己实现了。不过有个小小情况,如果一直按着不放比如5秒,就不会触发事件。。。 应该是要俩秒后就触发的,这个可能适用场景稍有不同
rookie108 2016-11-10
  • 打赏
  • 举报
回复
引用 3 楼 attilax 的回复:
这个使用watchdog设计模式吧。。很好解决 Atitit. 设计模式watchdog 技术原理 v2 qb9 attilax总结 watchdog 底层是使用定时器实现的。。 1 在判断延时防止误按按钮的时候很有用,原理与流程 1 源码 1 watchdog 底层是使用定时器实现的。。 主要原理,是需要定时喂狗,负责狗就会复位程序。。 在判断延时防止误按按钮的时候很有用,原理与流程 首先默认情况下不断有定时线程进行喂狗操作,所以不会触发按钮事件。。 当按钮按下式,就终止了喂狗,2秒后狗饿了,就出来触发了按钮事件。。 如果在俩妙内,谈起按键 ,就又开始定时喂狗了。。 源码 Watchdog dog=new Watchdog(100); //这里初始化watchdog的精度,即每隔多少毫秒增加一个饥饿值,精度越高,越精确。。 dog.MaxFeedTime=2000;//喂狗的最大时间,单位毫秒,超过此时间,狗就饥饿了,出来触发事件来。。 //狗饥饿了,出来触发事件的定义 dog.hungryEvt=()->{ System.out.println("btn evt..."); }; dog.ini(); //测试 每隔一秒喂狗,就不会触发事件 while(true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } dog.feed(); } 延时2秒后 参考 Watchdog实现分析 - __Shadow - 博客园_files WDT(WatchDog Timer结构)_百度百科_files 作者:: 绰号:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿尔 拉帕努伊 )  汉字名:艾提拉(艾龙),   EMAIL:1466519819@qq.com 转载请注明来源: http://blog.csdn.net/attilax Atiend
谢谢。喂狗这种方法也不错。但我查了watchdog似乎不是JAVA的类吧?需要自己去编写一个watchdog的类?相比我上面那种计算按键按下和松开的时间差,两者对系统资源消耗哪个大呢?
rookie108 2016-11-10
  • 打赏
  • 举报
回复
唉,我把这个当成了单片机里面处理按键消抖一样了,思路错了 现在我想这样处理:分别取得按键按下的时间和按键松开的时间,然后求出两者之差,大于2000ms就是有效,否则无效。这样是否可行?对系统资源浪费大吗?
/*
 * 测试q键按下2秒后才执行相应动作
 */
package test;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;

public class KeyEventTest extends JFrame implements KeyListener {
	long pressTime=0;
	long releasedTime=0;
	boolean keyEnable=true;
	
	public static void main(String[] args) {
		KeyEventTest ket = new KeyEventTest();
	}

	public KeyEventTest() {
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLayout(null);
		this.setTitle("KeyEventTest");
		this.setSize(300, 300);
		this.setVisible(true);
		addKeyListener(this);
	}

	public void keyPressed(KeyEvent e) {
		if (keyEnable ==true) {
			pressTime = System.currentTimeMillis();
			keyEnable=false;
		}
	}

	public void keyReleased(KeyEvent e) {
		releasedTime=System.currentTimeMillis();
		long afterTime=releasedTime-pressTime;
		if((e.getKeyCode()==81)&&(afterTime>=2000)){
			System.out.println("有效按键,键码="+e.getKeyCode());
		}else{
			System.out.println("无效按键或按下时间太短,键码="+e.getKeyCode()+"  按下时间="+String.valueOf(afterTime)+"ms");
		}
		keyEnable=true;
	}

	public void keyTyped(KeyEvent e) {
	}
}
attilax 2016-11-10
  • 打赏
  • 举报
回复
这个使用watchdog设计模式吧。。很好解决 Atitit. 设计模式watchdog 技术原理 v2 qb9 attilax总结 watchdog 底层是使用定时器实现的。。 1 在判断延时防止误按按钮的时候很有用,原理与流程 1 源码 1 watchdog 底层是使用定时器实现的。。 主要原理,是需要定时喂狗,负责狗就会复位程序。。 在判断延时防止误按按钮的时候很有用,原理与流程 首先默认情况下不断有定时线程进行喂狗操作,所以不会触发按钮事件。。 当按钮按下式,就终止了喂狗,2秒后狗饿了,就出来触发了按钮事件。。 如果在俩妙内,谈起按键 ,就又开始定时喂狗了。。 源码 Watchdog dog=new Watchdog(100); //这里初始化watchdog的精度,即每隔多少毫秒增加一个饥饿值,精度越高,越精确。。 dog.MaxFeedTime=2000;//喂狗的最大时间,单位毫秒,超过此时间,狗就饥饿了,出来触发事件来。。 //狗饥饿了,出来触发事件的定义 dog.hungryEvt=()->{ System.out.println("btn evt..."); }; dog.ini(); //测试 每隔一秒喂狗,就不会触发事件 while(true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } dog.feed(); } 延时2秒后 参考 Watchdog实现分析 - __Shadow - 博客园_files WDT(WatchDog Timer结构)_百度百科_files 作者:: 绰号:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿尔 拉帕努伊 )  汉字名:艾提拉(艾龙),   EMAIL:1466519819@qq.com 转载请注明来源: http://blog.csdn.net/attilax Atiend
逗泥丸的平方 2016-11-10
  • 打赏
  • 举报
回复
你这种写法是 2秒后来执行第一次按下时候的事件 自然是没有用的. 我能想到的解决方法只有外挂一个计时器了.... 如果2秒内没有触发松开的是事件keyReleased 就算确认了
清风步月 2016-11-10
  • 打赏
  • 举报
回复
sleep吧

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧