java监听全局组合键
1. jintellitype
- pom
<!-- 不能注册多个组合键比如alt+abc -->
<!-- https://mvnrepository.com/artifact/com.melloware/jintellitype -->
<dependency>
<groupId>com.melloware</groupId>
<artifactId>jintellitype</artifactId>
<version>1.4.1</version>
</dependency>
- 代码
package com.hotkey.app; import cn.hutool.core.date.DateUtil;
import com.melloware.jintellitype.JIntellitype; public class IntelApplication {
public static void main(String[] args) { // 添加全局热键
JIntellitype instance = JIntellitype.getInstance();
instance.registerHotKey(0, JIntellitype.MOD_ALT + JIntellitype.MOD_SHIFT, 'B');
instance.registerHotKey(2, 20, 'B');
instance.registerHotKey(1, "CTRL+SHIFT+X+V");
instance.registerHotKey(3, "CTRL+SHIFT+ALT+WIN+DELETE+B"); // 添加热键监听器
instance.addHotKeyListener(hotkey -> {
System.out.println(DateUtil.now() + " Hotkey pressed: " + hotkey);
// 在这里处理你的逻辑
}); }
}
- 缺点: 对于ctrl a b 按ctrl b也可以触发
2. jkeymaster
- pom
<!-- https://mvnrepository.com/artifact/com.github.tulskiy/jkeymaster -->
<dependency>
<groupId>com.github.tulskiy</groupId>
<artifactId>jkeymaster</artifactId>
<version>1.3</version>
</dependency> <!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.12.1</version>
</dependency>
- 代码
import com.tulskiy.keymaster.common.Provider; import javax.swing.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent; public class KeyApplication { public static void main(String[] args) {
Provider provider = Provider.getCurrentProvider(true); provider.register(
KeyStroke.getKeyStroke(KeyEvent.CTRL_MASK,
InputEvent.ALT_MASK),
x -> System.err.println(x));
}
}
- 缺点: 对于+ = [ ]特殊按键识别不到; 不能注册类似ctrl a b会报错
3. jnativehook(推荐)
- pom
<!-- https://mvnrepository.com/artifact/com.1stleg/jnativehook -->
<dependency>
<groupId>com.1stleg</groupId>
<artifactId>jnativehook</artifactId>
<version>2.1.0</version>
</dependency>
- 代码
import cn.hutool.core.collection.CollUtil;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener; import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger; /**
* 监听键盘和鼠标按键, 这个是强制顺序和不支持重复的
* 如果要支持重复就得使用List保存快捷键, 并给每个编键去配置标志位, 或者快捷键数组使用对象数组
* 如果要不要求顺序, 就按下时候直接标志位变成true即可
*
* @author codor
* @date 2023/12/08 16:23
* @see org.jnativehook.example.NativeHookDemo
*/
public class NativeApplication extends JFrame implements NativeKeyListener { // ----------------------------------------------------------------------------------------------------------------- 逻辑使用 /**
* 快捷键组合
* 名字也可以不写上去, 使用NativeKeyEvent.getKeyText(event.getKeyCode())获取
*/
private Map<Integer, String> hotKeys; /**
* 键编码的列表, 因为要保证顺序
*/
private List<Integer> codes; /**
* 快捷键是否按下标标志位
*/
private Map<Integer, Boolean> flags; /**
* 窗口是否展示出来了
*/
private boolean isWindowShow = false; // ---------------------------------------------------------------------------------------------------------------- 界面使用 /**
* 倒计时
*/
private Timer countdownTimer; /**
* 倒计时事件
*/
private final static Integer COUNT_DOWN_SECONDS = 10; /**
* 初始化标志位
*
* @see org.jnativehook.keyboard.NativeKeyEvent
*/
public void initHotKeys() {
this.hotKeys = new LinkedHashMap<>();
this.hotKeys.put(29, "Ctrl");
this.hotKeys.put(46, "C");
this.hotKeys.put(45, "X");
this.hotKeys.put(47, "V"); // 初始化键编码
this.codes = new ArrayList<>();
this.hotKeys.forEach((k, v) -> this.codes.add(k)); // 初始化标指位
this.initFlags();
} /**
* 初始化标志位
*/
public void initFlags() {
if (this.hotKeys == null) {
this.initHotKeys();
}
this.flags = new HashMap<>();
for (Integer code : this.codes) {
this.flags.put(code, false);
}
} /**
* 按下键时候, 强制要求顺序
*
* @param code 键编码
* @return 是否全部按下了, true是, 反之false
*/
public boolean pressedKey(int code) {
// 如果未在内, 重置标志位
if (!this.codes.contains(code)) {
this.initFlags();
return false;
} for (Integer k : this.codes) {
// 循环到 第一个非按下状态的就跳出循环或退出方法
if (!this.flags.get(k)) {
// 并且等于按下的键, 设置按下成功
if (k.equals(code)) {
this.flags.put(code, true);
break;
} else { // 不是不等于按下的, 说明按了后面的,
this.initFlags();
return false;
}
}
} // 只有break时候到这里, 判断是否循环完, 也即code是否最后一个
return code == this.codes.get(this.codes.size() - 1);
} /**
* 松开键
*/
public void releaseKey(int code) {
this.flags.put(code, false);
} public String getKeyTexts() {
if (CollUtil.isEmpty(this.codes)) {
return "";
}
StringBuilder resB = new StringBuilder(" ");
for (Integer code : this.codes) {
resB.append(NativeKeyEvent.getKeyText(code)).append(" ");
}
return resB.toString();
} public void showWindow(String hotKeyTexts) { setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setUndecorated(true); // 窗口无装饰, 但是标题也会干掉 setTitle("倒计时窗口");
setLayout(new BorderLayout()); JLabel countdownLabel = new JLabel("倒计时: " + COUNT_DOWN_SECONDS + " 秒", JLabel.CENTER);
JButton cancelButton = new JButton("取消"); cancelButton.addActionListener(e -> {
// 点击取消按钮时的处理
if (countdownTimer != null) {
// 重置标志位
this.initFlags();
// 关闭窗口
this.closeWindow();
}
}); add(countdownLabel, BorderLayout.CENTER);
add(cancelButton, BorderLayout.SOUTH); setSize(300, 150);
setLocationRelativeTo(null); // 将窗口置于屏幕中央
setVisible(true); AtomicInteger second = new AtomicInteger(COUNT_DOWN_SECONDS);
countdownTimer = new Timer(1000, e -> {
second.getAndDecrement(); if (second.get() >= 0) {
countdownLabel.setText("倒计时: " + second.get() + " 秒");
} else {
// 关闭窗口
this.closeWindow();
// 触发成功后发送指令
// 指令发送成功后重置标志位
this.initFlags();
}
}); countdownTimer.start();
} public void closeWindow() {
countdownTimer.stop();
dispose(); // 关闭窗口
setVisible(false); // 设置窗口不可见
getContentPane().removeAll(); // 移除所有组件
revalidate(); // 重新验证布局
repaint(); // 重绘窗口 // 关闭窗口时候重置
isWindowShow = false;
} // ---------------------------------------------------------------------------------------------------------------- Override Method @Override
public void nativeKeyTyped(NativeKeyEvent nativeKeyEvent) {
} @Override
public void nativeKeyPressed(NativeKeyEvent event) {
boolean isHotKey = this.pressedKey(event.getKeyCode());
// 成功并且窗口未展示时候
if (isHotKey && !isWindowShow) {
System.err.println("触发快捷组合键成功...");
// 窗口标志位设置成功
isWindowShow = true;
this.showWindow(this.getKeyTexts());
}
} @Override
public void nativeKeyReleased(NativeKeyEvent event) {
this.releaseKey(event.getKeyCode());
} public static void main(String[] args) {
try {
// 设置日志级别,避免 JNativeHook 的日志输出
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.OFF); // 注册全局键盘事件
GlobalScreen.registerNativeHook();
} catch (NativeHookException ex) {
ex.printStackTrace();
System.err.println("Failed to initialize native hook. Exiting.");
System.exit(1);
} // 添加 NativeKeyListener
NativeApplication application = new NativeApplication();
application.initFlags();
GlobalScreen.addNativeKeyListener(application);
}
}
java监听全局组合键的更多相关文章
- JS实现键盘监听(包括组合键)
依然使用案例驱动~案例是学习的最好实践! <html> <head> <meta http-equiv="Content-Type" co ...
- vue 定义全局函数,监听android返回键事件
vue 定义全局函数,监听android返回键事件 方法一:main.js 注入(1)在main.js中写入函数Vue.prototype.changeData = function (){ aler ...
- vue+hbuilder监听安卓返回键问题
1.监听安卓返回键问题 效果:在一级页面按一下返回键提示退出应用,按两下退出应用;在其它页面中,按一下返回上个历史页面 1 2 import mui from './assets/js/mui.min ...
- 监听 手机back键和顶部的回退
// 回退事件,监听 手机back键和顶部的回退 pushHistory(); window.addEventListener("popstate", function(e) { ...
- Java监听模式
说明 生活中,监听无处不在.比如说,手机播放音乐功能,也是一种监听:你不点击播放按钮,手机就不放歌,当你点击时,手机就播放音乐.即触发某种行为,便执行相应的动作. 组成 Java监听模式右三个部分组成 ...
- java 监听控制台输入
分享一下我写的java监听控制台输入并可以给出响应的功能. 很多时候需要监听控制台的输入内容,相当于信号监听,根据输入的内容做出相应的动作,这里给出我的一个简单实现. 要注意的是:监听得到的消息中前后 ...
- javascript监听手机返回键
javascript监听手机返回键 <pre> if (window.history && window.history.pushState) { $(window).on ...
- Vue 监听鼠标左键 鼠标右键以及鼠标中键修饰符click.left&contextmenu&click.middle
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- iOS 监听 出发 Home键 NSNotificationCenter UIApplicationWillResignActiveNotification
第一步: 创建2个NSNotificationCenter监听 [[NSNotificationCenter defaultCenter] addObserver:self selector:@sel ...
- java监听事件
2014年2月23日 09:51:54 成功添加了打开官网的事件, 回头研究下,那个打开url的类 java的System.getProperty()方法可以获取的值 ################ ...
随机推荐
- 学好Elasticsearch系列-索引的批量操作
本文已收录至 Github,推荐阅读 Java 随想录 微信公众号:Java 随想录 先看后赞,养成习惯. 点赞收藏,人生辉煌. 目录 基于 mget 的批量查询 基于 bulk 的批量增删改 增加 ...
- 原生CSS嵌套简介
嵌套是使用Sass等CSS预处理器的核心原因之一.现在,该功能已经以类似的语法出现在标准浏览器CSS中.你能否在构建系统时放弃对预处理器的依赖? CSS嵌套可以节省输入时间,并使语法更易于阅读和维护. ...
- [ABC148F] Playing Tag on Tree
2023-03-04 题目 题目传送门 翻译 翻译 难度&重要性(1~10):5 题目来源 AtCoder 题目算法 最短路 解题思路 考虑到 T 想活得久, A 想尽早追上 T ,所以我们就 ...
- 2023-09-03:用go编写。给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1 给你整数 n 和一个长度为 n - 1 的二维整数数组 edges , 其中 edges[i] =
2023-09-03:用go语言编写.给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1 给你整数 n 和一个长度为 n - 1 的二维整数数组 edges , 其中 edges[i] ...
- 发现了一个可以免费下载jar包的网站,所有jar包都有
苦苦找不到项目所需要的jar包?发现了一个可以免费下载jar包的网站: https://jar-download.com/ 非常好用. 每个JAR文件都将从官方Maven存储库下载.通过下载所有Mav ...
- 《Docker到Kubernetes容器运维实战》简介
#好书推荐##好书奇遇季#<Docker到Kubernetes容器运维实战>已经出版.本书帮助读者系统掌握Docker与K8s运维技能. 本书内容 本书分两部分系统介绍Docker与K ...
- crypto 加解密库简介与测试【GO 常用的库】
〇.前言 GO 语言的标准库 crypto 提供了一组用于加密和解密的包,包括对称加密.哈希函数.数字签名.随机数生成等功能.在日常开发中,通过使用这些库,可以确保数据的安全性和完整性. 对于使用频率 ...
- 一些H5对接微信JSSDK的问题记录
这里给大家分享我在实际生活中总结出来的一些知识,希望对大家有所帮助 一.SDK引入 这里提供两套引入流程,一套是vue2.0及其他h5项目,一套是vue3.0的引入流程 不懂的也可以看我之前的一篇详细 ...
- 小米手机抓取Log教程
当小米手机遇到任何系统下的较为严重的故障时(即此时系统还是基本正常运行的,只是某些功能实现出了问题),例如软件自动退出,SD卡自动卸载,电话无法拨出等等.可以请用户协助抓取log即系统运行日志,来发送 ...
- Go字符串实战操作大全!
在本篇文章中,我们深入探讨了Go语言中字符串的魅力和深度.从基础定义.操作.字符编码到复杂的类型转换,每个环节都带有实例和代码示例来深化理解.通过这些深入的解析,读者不仅能够掌握字符串在Go中的核心概 ...