自制Java工具:Ctrl+C+C快速翻译鼠标选中文本实践指南

作者:热心市民鹿先生2025.10.11 17:02浏览量:1

简介:本文详细介绍了如何使用Java开发一个工具,通过自定义快捷键Ctrl+C+C实现鼠标选中文本的即时翻译功能,提升工作效率。

引言

在日常办公或学习中,我们经常需要查阅外文资料,频繁切换翻译软件或复制粘贴文本进行翻译不仅耗时,还容易打断工作思路。如果能实现一键翻译选中文本,将极大提升效率。本文将介绍如何利用Java开发一个工具,通过自定义快捷键Ctrl+C+C(避免与系统复制快捷键冲突)实现鼠标选中文本的即时翻译,无需离开当前应用界面。

一、技术选型与工具准备

1.1 Java Swing/AWT

Java Swing和AWT提供了丰富的GUI组件,适合构建桌面应用程序。我们将使用它们来创建系统托盘图标和设置全局快捷键监听。

1.2 JNI/JNA或Robot类

为了监听全局快捷键(包括系统级快捷键),我们可以考虑使用JNI(Java Native Interface)或JNA(Java Native Access)调用本地库,但这会增加项目复杂度。更简单的方法是使用Java的Robot类模拟按键,但结合GlobalScreen库(如JIntellitype或JNativeHook)可以更有效地监听全局事件。这里我们选择JNativeHook,因为它跨平台且易于集成。

1.3 翻译API

选择翻译API时,需考虑免费额度、响应速度、翻译质量等因素。常见的有Google Translate API(需API密钥)、有道翻译API、百度翻译API等。本文以有道翻译API为例,因其提供了免费试用额度且易于接入。

二、实现步骤

2.1 添加依赖

首先,在Maven项目的pom.xml中添加JNativeHook依赖:

  1. <dependency>
  2. <groupId>com.1stleg</groupId>
  3. <artifactId>jnativehook</artifactId>
  4. <version>2.1.0</version>
  5. </dependency>

2.2 创建系统托盘应用

使用Java Swing创建系统托盘图标,用于控制工具的启动与停止:

  1. import javax.swing.*;
  2. import java.awt.*;
  3. import java.awt.event.ActionEvent;
  4. import java.awt.event.ActionListener;
  5. public class TranslationTrayApp {
  6. public static void main(String[] args) {
  7. if (SystemTray.isSupported()) {
  8. SystemTray tray = SystemTray.getSystemTray();
  9. Image image = Toolkit.getDefaultToolkit().getImage("icon.png"); // 替换为实际图标路径
  10. PopupMenu popup = new PopupMenu();
  11. MenuItem exitItem = new MenuItem("Exit");
  12. exitItem.addActionListener(new ActionListener() {
  13. public void actionPerformed(ActionEvent e) {
  14. System.exit(0);
  15. }
  16. });
  17. popup.add(exitItem);
  18. TrayIcon trayIcon = new TrayIcon(image, "Translation Tool", popup);
  19. trayIcon.addActionListener(e -> {
  20. // 这里可以添加点击托盘图标时的操作,如显示/隐藏主窗口
  21. });
  22. try {
  23. tray.add(trayIcon);
  24. } catch (AWTException e) {
  25. System.err.println("TrayIcon could not be added.");
  26. }
  27. // 启动快捷键监听
  28. new GlobalKeyListener().start();
  29. } else {
  30. System.err.println("System tray not supported.");
  31. }
  32. }
  33. }

2.3 监听全局快捷键

使用JNativeHook监听Ctrl+C+C快捷键:

  1. import org.jnativehook.GlobalScreen;
  2. import org.jnativehook.NativeHookException;
  3. import org.jnativehook.keyboard.NativeKeyEvent;
  4. import org.jnativehook.keyboard.NativeKeyListener;
  5. public class GlobalKeyListener implements NativeKeyListener {
  6. private boolean firstCtrlCPressed = false;
  7. public void start() {
  8. try {
  9. GlobalScreen.registerNativeHook();
  10. } catch (NativeHookException ex) {
  11. System.err.println("There was a problem registering the native hook.");
  12. System.err.println(ex.getMessage());
  13. }
  14. GlobalScreen.addNativeKeyListener(this);
  15. }
  16. @Override
  17. public void nativeKeyPressed(NativeKeyEvent e) {
  18. if (e.getKeyCode() == NativeKeyEvent.VC_CONTROL) {
  19. // 这里简化处理,实际需结合时间戳判断是否为双击Ctrl+C
  20. // 更精确的实现需记录按键时间
  21. System.out.println("Control pressed");
  22. // 实际实现中,这里应设置一个标志位,并在release时检查是否为双击
  23. } else if (e.getKeyCode() == NativeKeyEvent.VC_C && isDoubleCtrlCPressed()) {
  24. // 模拟获取选中文本(实际需通过其他方式,如剪贴板或Windows API)
  25. String selectedText = getSelectedText(); // 伪代码,需实现
  26. translateText(selectedText);
  27. }
  28. }
  29. private boolean isDoubleCtrlCPressed() {
  30. // 实现逻辑:检查是否在短时间内连续按下了两次Ctrl+C
  31. // 这里简化处理,实际需使用时间戳和状态管理
  32. return firstCtrlCPressed; // 伪代码,需根据实际逻辑调整
  33. }
  34. // 更精确的Ctrl+C+C检测实现(简化版)
  35. private long lastCtrlCPressTime = 0;
  36. @Override
  37. public void nativeKeyReleased(NativeKeyEvent e) {
  38. if (e.getKeyCode() == NativeKeyEvent.VC_CONTROL) {
  39. long currentTime = System.currentTimeMillis();
  40. if (currentTime - lastCtrlCPressTime < 500) { // 假设500ms内为双击
  41. // 这里应触发翻译,但需结合C键的按下情况
  42. // 更完整的实现需在C键按下时记录时间
  43. }
  44. lastCtrlCPressTime = currentTime;
  45. }
  46. }
  47. // 实际项目中,应使用更精确的状态机来管理按键序列
  48. @Override
  49. public void nativeKeyTyped(NativeKeyEvent e) {
  50. // 不处理
  51. }
  52. private String getSelectedText() {
  53. // 实现获取选中文本的逻辑,可能涉及调用Windows API或使用剪贴板历史
  54. // 这里简化处理,实际需根据操作系统实现
  55. return "Hello World"; // 示例文本
  56. }
  57. private void translateText(String text) {
  58. // 调用翻译API
  59. System.out.println("Translating: " + text);
  60. // 实际实现中,这里应调用有道翻译API等
  61. }
  62. }

注意:上述代码中的isDoubleCtrlCPressedgetSelectedText方法仅为示意,实际实现需更复杂。对于getSelectedText,在Windows上可通过User32.dllGetForegroundWindowGetWindowText结合剪贴板操作获取(但获取非活动窗口选中文本较复杂),或考虑使用第三方库如JNA直接调用Windows API。

2.4 调用翻译API

以有道翻译API为例,实现翻译功能:

  1. import java.io.BufferedReader;
  2. import java.io.InputStreamReader;
  3. import java.net.HttpURLConnection;
  4. import java.net.URL;
  5. import java.net.URLEncoder;
  6. public class Translator {
  7. private static final String APP_KEY = "your_app_key";
  8. private static final String APP_SECRET = "your_app_secret";
  9. private static final String TRANSLATE_URL = "https://openapi.youdao.com/api";
  10. public static String translate(String query, String from, String to) throws Exception {
  11. String salt = String.valueOf(System.currentTimeMillis());
  12. String sign = generateSign(query, salt);
  13. String urlStr = TRANSLATE_URL + "?q=" + URLEncoder.encode(query, "UTF-8") +
  14. "&from=" + from + "&to=" + to + "&appKey=" + APP_KEY +
  15. "&salt=" + salt + "&sign=" + sign;
  16. URL url = new URL(urlStr);
  17. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  18. conn.setRequestMethod("GET");
  19. BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
  20. String inputLine;
  21. StringBuilder response = new StringBuilder();
  22. while ((inputLine = in.readLine()) != null) {
  23. response.append(inputLine);
  24. }
  25. in.close();
  26. // 解析JSON响应获取翻译结果(这里简化处理)
  27. // 实际应使用JSON库如Jackson或Gson解析
  28. return parseTranslationResult(response.toString());
  29. }
  30. private static String generateSign(String query, String salt) {
  31. // 按照有道API文档生成签名
  32. // 这里简化处理,实际需包含APP_SECRET
  33. return "simulated_sign"; // 示例签名
  34. }
  35. private static String parseTranslationResult(String json) {
  36. // 解析JSON获取翻译文本
  37. // 实际应使用JSON库
  38. return "Translated Text"; // 示例结果
  39. }
  40. }

三、优化与扩展

3.1 精确检测Ctrl+C+C

使用状态机精确管理按键序列,确保只在快速连续按下两次Ctrl+C时触发翻译。

3.2 多语言支持

允许用户配置源语言和目标语言,或在界面上提供选择。

3.3 剪贴板历史与翻译记录

集成剪贴板管理功能,保存翻译历史,方便回顾。

3.4 跨平台兼容性

考虑使用Electron或JavaFX结合JNI实现更跨平台的解决方案,或针对不同操作系统编写特定实现。

四、总结

通过Java结合JNativeHook和翻译API,我们成功实现了一个能够监听自定义快捷键Ctrl+C+C并翻译鼠标选中文本的工具。这不仅提升了翻译效率,还展示了Java在桌面应用开发中的灵活性。未来,可以进一步优化快捷键检测逻辑、增加多语言支持和剪贴板管理功能,使工具更加实用。