简介:本文详细介绍了如何使用Java开发一个工具,通过自定义快捷键Ctrl+C+C实现鼠标选中文本的即时翻译功能,提升工作效率。
在日常办公或学习中,我们经常需要查阅外文资料,频繁切换翻译软件或复制粘贴文本进行翻译不仅耗时,还容易打断工作思路。如果能实现一键翻译选中文本,将极大提升效率。本文将介绍如何利用Java开发一个工具,通过自定义快捷键Ctrl+C+C(避免与系统复制快捷键冲突)实现鼠标选中文本的即时翻译,无需离开当前应用界面。
Java Swing和AWT提供了丰富的GUI组件,适合构建桌面应用程序。我们将使用它们来创建系统托盘图标和设置全局快捷键监听。
为了监听全局快捷键(包括系统级快捷键),我们可以考虑使用JNI(Java Native Interface)或JNA(Java Native Access)调用本地库,但这会增加项目复杂度。更简单的方法是使用Java的Robot类模拟按键,但结合GlobalScreen库(如JIntellitype或JNativeHook)可以更有效地监听全局事件。这里我们选择JNativeHook,因为它跨平台且易于集成。
选择翻译API时,需考虑免费额度、响应速度、翻译质量等因素。常见的有Google Translate API(需API密钥)、有道翻译API、百度翻译API等。本文以有道翻译API为例,因其提供了免费试用额度且易于接入。
首先,在Maven项目的pom.xml中添加JNativeHook依赖:
<dependency><groupId>com.1stleg</groupId><artifactId>jnativehook</artifactId><version>2.1.0</version></dependency>
使用Java Swing创建系统托盘图标,用于控制工具的启动与停止:
import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;public class TranslationTrayApp {public static void main(String[] args) {if (SystemTray.isSupported()) {SystemTray tray = SystemTray.getSystemTray();Image image = Toolkit.getDefaultToolkit().getImage("icon.png"); // 替换为实际图标路径PopupMenu popup = new PopupMenu();MenuItem exitItem = new MenuItem("Exit");exitItem.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {System.exit(0);}});popup.add(exitItem);TrayIcon trayIcon = new TrayIcon(image, "Translation Tool", popup);trayIcon.addActionListener(e -> {// 这里可以添加点击托盘图标时的操作,如显示/隐藏主窗口});try {tray.add(trayIcon);} catch (AWTException e) {System.err.println("TrayIcon could not be added.");}// 启动快捷键监听new GlobalKeyListener().start();} else {System.err.println("System tray not supported.");}}}
使用JNativeHook监听Ctrl+C+C快捷键:
import org.jnativehook.GlobalScreen;import org.jnativehook.NativeHookException;import org.jnativehook.keyboard.NativeKeyEvent;import org.jnativehook.keyboard.NativeKeyListener;public class GlobalKeyListener implements NativeKeyListener {private boolean firstCtrlCPressed = false;public void start() {try {GlobalScreen.registerNativeHook();} catch (NativeHookException ex) {System.err.println("There was a problem registering the native hook.");System.err.println(ex.getMessage());}GlobalScreen.addNativeKeyListener(this);}@Overridepublic void nativeKeyPressed(NativeKeyEvent e) {if (e.getKeyCode() == NativeKeyEvent.VC_CONTROL) {// 这里简化处理,实际需结合时间戳判断是否为双击Ctrl+C// 更精确的实现需记录按键时间System.out.println("Control pressed");// 实际实现中,这里应设置一个标志位,并在release时检查是否为双击} else if (e.getKeyCode() == NativeKeyEvent.VC_C && isDoubleCtrlCPressed()) {// 模拟获取选中文本(实际需通过其他方式,如剪贴板或Windows API)String selectedText = getSelectedText(); // 伪代码,需实现translateText(selectedText);}}private boolean isDoubleCtrlCPressed() {// 实现逻辑:检查是否在短时间内连续按下了两次Ctrl+C// 这里简化处理,实际需使用时间戳和状态管理return firstCtrlCPressed; // 伪代码,需根据实际逻辑调整}// 更精确的Ctrl+C+C检测实现(简化版)private long lastCtrlCPressTime = 0;@Overridepublic void nativeKeyReleased(NativeKeyEvent e) {if (e.getKeyCode() == NativeKeyEvent.VC_CONTROL) {long currentTime = System.currentTimeMillis();if (currentTime - lastCtrlCPressTime < 500) { // 假设500ms内为双击// 这里应触发翻译,但需结合C键的按下情况// 更完整的实现需在C键按下时记录时间}lastCtrlCPressTime = currentTime;}}// 实际项目中,应使用更精确的状态机来管理按键序列@Overridepublic void nativeKeyTyped(NativeKeyEvent e) {// 不处理}private String getSelectedText() {// 实现获取选中文本的逻辑,可能涉及调用Windows API或使用剪贴板历史// 这里简化处理,实际需根据操作系统实现return "Hello World"; // 示例文本}private void translateText(String text) {// 调用翻译APISystem.out.println("Translating: " + text);// 实际实现中,这里应调用有道翻译API等}}
注意:上述代码中的isDoubleCtrlCPressed和getSelectedText方法仅为示意,实际实现需更复杂。对于getSelectedText,在Windows上可通过User32.dll的GetForegroundWindow和GetWindowText结合剪贴板操作获取(但获取非活动窗口选中文本较复杂),或考虑使用第三方库如JNA直接调用Windows API。
以有道翻译API为例,实现翻译功能:
import java.io.BufferedReader;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLEncoder;public class Translator {private static final String APP_KEY = "your_app_key";private static final String APP_SECRET = "your_app_secret";private static final String TRANSLATE_URL = "https://openapi.youdao.com/api";public static String translate(String query, String from, String to) throws Exception {String salt = String.valueOf(System.currentTimeMillis());String sign = generateSign(query, salt);String urlStr = TRANSLATE_URL + "?q=" + URLEncoder.encode(query, "UTF-8") +"&from=" + from + "&to=" + to + "&appKey=" + APP_KEY +"&salt=" + salt + "&sign=" + sign;URL url = new URL(urlStr);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));String inputLine;StringBuilder response = new StringBuilder();while ((inputLine = in.readLine()) != null) {response.append(inputLine);}in.close();// 解析JSON响应获取翻译结果(这里简化处理)// 实际应使用JSON库如Jackson或Gson解析return parseTranslationResult(response.toString());}private static String generateSign(String query, String salt) {// 按照有道API文档生成签名// 这里简化处理,实际需包含APP_SECRETreturn "simulated_sign"; // 示例签名}private static String parseTranslationResult(String json) {// 解析JSON获取翻译文本// 实际应使用JSON库return "Translated Text"; // 示例结果}}
使用状态机精确管理按键序列,确保只在快速连续按下两次Ctrl+C时触发翻译。
允许用户配置源语言和目标语言,或在界面上提供选择。
集成剪贴板管理功能,保存翻译历史,方便回顾。
考虑使用Electron或JavaFX结合JNI实现更跨平台的解决方案,或针对不同操作系统编写特定实现。
通过Java结合JNativeHook和翻译API,我们成功实现了一个能够监听自定义快捷键Ctrl+C+C并翻译鼠标选中文本的工具。这不仅提升了翻译效率,还展示了Java在桌面应用开发中的灵活性。未来,可以进一步优化快捷键检测逻辑、增加多语言支持和剪贴板管理功能,使工具更加实用。