首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JIntellitype 實作 Java 全域熱鍵註冊

     編輯:Java 相關知識

使用 JIntellitype 實現 Java 全域熱鍵

Java 標準 API 不支援系統層級的全域熱鍵(Global Hotkey),即應用程式未取得焦點時仍能攔截鍵盤組合鍵。JIntellitype 是基於 JNA (Java Native Access) 封裝 Windows API (RegisterHotKey/UnregisterHotKey) 的輕量級函式庫,可讓 Java 程式在 Windows 系統上註冊全域熱鍵。本文詳細說明整合步驟與完整程式碼範例。

專案整合步驟

  1. Maven 依賴 (JIntellitype 已上傳至 Maven Central):
    <dependency>
        <groupId>com.github.kwhat</groupId>
        <artifactId>jintellitype</artifactId>
        <version>1.3.9</version>
    </dependency>
  2. 原生函式庫:JIntellitype 會自動從 JAR 釋放 JIntellitype.dll (32/64 位元) 至臨時目錄並載入,無需手動配置
  3. 系統需求:Windows 7/8/10/11,需 JRE 8+

核心 API 說明

方法說明
registerHotKey(int id, int modifiers, int keyCode)註冊熱鍵,id 為唯一識別碼
unregisterHotKey(int id)註銷指定熱鍵
cleanUp()清理所有熱鍵並釋放原生資源
addHotKeyListener(HintListener)添加熱鍵觸發監聽器

修飾鍵常數:MOD_CTRL (1)、MOD_ALT (2)、MOD_SHIFT (4)、MOD_WIN (8),可組合使用 (如 Ctrl+Alt = 3)

虛擬鍵碼:使用 java.awt.event.KeyEvent 常數 (如 VK_F1、VK_A、VK_1)

完整實作範例

import com.github.kwhat.jintellitype.HotkeyListener;
import com.github.kwhat.jintellitype.JIntellitype;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;

public class GlobalHotkeyDemo extends JFrame {
    // 熱鍵 ID 定義
    private static final int HOTKEY_SHOW_HIDE = 1001;
    private static final int HOTKEY_SCREENSHOT = 1002;
    private static final int HOTKEY_QUICK_SEARCH = 1003;

    private JTextArea logArea;
    private boolean windowVisible = true;

    public GlobalHotkeyDemo() {
        setTitle("JIntellitype 全域熱鍵示範");
        setSize(500, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        // UI 初始化
        logArea = new JTextArea();
        logArea.setEditable(false);
        logArea.setFont(new Font("Monospaced", Font.PLAIN, 13));
        add(new JScrollPane(logArea), BorderLayout.CENTER);
        
        JPanel hintPanel = new JPanel();
        hintPanel.add(new JLabel("熱鍵: Ctrl+Alt+S=顯示/隱藏 | Ctrl+Alt+P=截圖 | Ctrl+Alt+F=快速搜尋"));
        add(hintPanel, BorderLayout.SOUTH);

        // 註冊全域熱鍵
        registerHotkeys();
        
        // 添加熱鍵監聽器
        JIntellitype.getInstance().addHotKeyListener(new HotkeyListener() {
            @Override
            public void onHotKey(int id) {
                SwingUtilities.invokeLater(() -> handleHotkey(id));
            }
        });

        setVisible(true);
    }

    private void registerHotkeys() {
        JIntellitype instance = JIntellitype.getInstance();
        
        // Ctrl + Alt + S : 顯示/隱藏視窗
        instance.registerHotKey(HOTKEY_SHOW_HIDE, 
            JIntellitype.MOD_CONTROL + JIntellitype.MOD_ALT, KeyEvent.VK_S);
        
        // Ctrl + Alt + P : 螢幕截圖
        instance.registerHotKey(HOTKEY_SCREENSHOT, 
            JIntellitype.MOD_CONTROL + JIntellitype.MOD_ALT, KeyEvent.VK_P);
        
        // Ctrl + Alt + F : 快速搜尋 (模擬)
        instance.registerHotKey(HOTKEY_QUICK_SEARCH, 
            JIntellitype.MOD_CONTROL + JIntellitype.MOD_ALT, KeyEvent.VK_F);
        
        log("已註冊 3 組全域熱鍵");
    }

    private void handleHotkey(int id) {
        switch (id) {
            case HOTKEY_SHOW_HIDE:
                windowVisible = !windowVisible;
                setVisible(windowVisible);
                if (windowVisible) toFront();
                log("熱鍵觸發: 視窗" + (windowVisible ? "顯示" : "隱藏"));
                break;
            case HOTKEY_SCREENSHOT:
                log("熱鍵觸發: 執行螢幕截圖...");
                // 這裡可呼叫 Robot 截圖邏輯
                takeScreenshot();
                break;
            case HOTKEY_QUICK_SEARCH:
                log("熱鍵觸發: 開啟快速搜尋");
                // 彈出搜尋框等邏輯
                break;
        }
    }

    private void takeScreenshot() {
        // 簡易截圖示範
        try {
            Robot robot = new Robot();
            Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
            Rectangle rect = new Rectangle(size);
            BufferedImage img = robot.createScreenCapture(rect);
            File file = new File("screenshot_" + System.currentTimeMillis() + ".png");
            ImageIO.write(img, "png", file);
            log("截圖已儲存: " + file.getAbsolutePath());
        } catch (Exception e) {
            log("截圖失敗: " + e.getMessage());
        }
    }

    private void log(String msg) {
        String timestamp = java.time.LocalTime.now().toString().substring(0, 8);
        logArea.append("[" + timestamp + "] " + msg + "\n");
        logArea.setCaretPosition(logArea.getDocument().getLength());
    }

    @Override
    public void dispose() {
        // 程式結束時務必清理熱鍵
        JIntellitype.getInstance().cleanUp();
        super.dispose();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(GlobalHotkeyDemo::new);
    }
}

常見問題與解決方案

  • 熱鍵衝突:若系統或其他軟體已佔用該組合鍵,registerHotKey 會靜默失敗。建議提供設定介面讓使用者自訂熱鍵
  • 64 位元 JVM 問題:JIntellitype 1.3.9+ 已支援 64 位元,舊版需手動替換 DLL
  • 管理員權限:若目標視窗以管理員權限執行,普通權限的 Java 程式無法攔截熱鍵,需同樣以管理員權限啟動
  • 跨平台限制:JIntellitype 僅支援 Windows。Linux/macOS 需使用 jnativehook 或平台原生 API
  • 記憶體洩漏:程式結束時必須呼叫 cleanUp(),否則熱鍵會殘留在系統中

進階應用場景

  • 截圖工具、翻譯軟體、快速啟動器等常駐系統匣應用
  • 遊戲輔助工具、直播推流控制 (推流/停止/切換場景)
  • 無障礙輔助功能、語音指令觸發器
  • 自動化測試中模擬使用者全域操作
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved