java监听全局组合键
生活随笔
收集整理的這篇文章主要介紹了
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监听全局组合键的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 玩中单的王者网名有哪些(有什么在线玩游戏
- 下一篇: 各个数据库存二进制大文件的性能测试