前言
本功能的实现基于这篇笔记 http://t.csdnimg.cn/1I8ln,本文阅读过程中有疑惑都可以查看此笔记
实现思路:检测到按压ctrl +c +c 后,获取当前剪切板文字,调用百度翻译api。
实现结果:
完整代码在最后
实现过程
1 监控ctrl +c +c
在当前demo的功能中我们可以看到,当按压键盘时会调用nativeKeyPressed
方法,并会打印当前按下的按钮字符串。
我们去掉一些打印的干扰:去除release和type的打印,以及press打印的前缀
此时就只会打印我们的按键
现在去实现:当连续按压ctrl+c+c时,打印"你按下了ctrl+c+c哦"
思路:初始设置一个key字符串为"“,当检测到按压ctrl时,设置key为"Ctrl”,当不是Ctrl时,key拼接本次按压的按键,然后和"CtrlCC"做比较。如果相同,则说明用户连续按压了ctrl+c+c;
代码实现(红框内为添加的代码):
效果:
2 获取剪切板内容
在我们进行ctrl+c+c的操作过程中,第一个ctrl+c就会将鼠标选择的内容放到剪切板里,此时我们获取剪切板的内容,之后再用这个内容调用翻译api即可。
创建一个剪切板工具类
/*** 剪切板工具类*/
public class ClipBoardUtil {public static String getClipboardText() {Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();//从系统剪切板中获取数据Transferable content = clipboard.getContents(null);//判断是否为文本类型if (content.isDataFlavorSupported(DataFlavor.stringFlavor)) {//从数据中获取文本值String text = null;try {text = (String) content.getTransferData(DataFlavor.stringFlavor);} catch (Exception e) {}if (text == null) {return "剪切板为空";}return text;}return "剪切板无文本值";}
}
在代码中调用:
效果:
3 调用百度翻译api
注册账号,开通服务
搜索百度翻译开放平台,注册账号,实名认证后,可以申请高级版用户
标准版:注册,未实名
高级版:注册,实名
尊享版:企业认证
高级版每个月有100万字符的免费调用量,对于个人使用的话绰绰有余了。
注册后,在管理控制台中开通文本翻译服务
详细见文档:
根据文档,编写代码
其中appid和密钥,在我们的管理控制台中
以下是调用方法的代码实现,我们创建一个TransApi
类
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpUtil;import java.util.HashMap;
import java.util.Map;public class TransApi {private static final String TRANS_API_HOST = "http://api.fanyi.baidu.com/api/trans/vip/translate";private String appid;private String securityKey;/*** 有参构造* @param appid appid* @param securityKey 密钥*/public TransApi(String appid, String securityKey) {this.appid = appid;this.securityKey = securityKey;}/*** 调用方法* @param query 翻译内容* @param from 来源语言* @param to 翻译语言* @return 返回参数*/ public String getTransResult(String query, String from, String to) {Map<String, Object> params = this.buildParams(query, from, to);return HttpUtil.get("http://api.fanyi.baidu.com/api/trans/vip/translate", params);}/*** 初始化参数* @param query 翻译内容* @param from 来源语言* @param to 翻译语言* @return*/private Map<String, Object> buildParams(String query, String from, String to) {Map<String, Object> params = new HashMap();params.put("q", query);params.put("from", from);params.put("to", to);params.put("appid", this.appid);String salt = String.valueOf(System.currentTimeMillis());params.put("salt", salt);String src = this.appid + query + salt + this.securityKey;//MD5加密params.put("sign", DigestUtil.md5Hex(src));return params;}
}
其中调用接口的HttpUtil
和加密的DigestUtil
使用的是hutool
中的类
hutool包的地址:
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.24</version>
</dependency>
ctrl+c+c获取剪切板内容并调用翻译接口
在GlobalKeyListenerExample
类中添加TransApi类的初始化:
在获取剪切板内容后,将剪切板的内容调用翻译接口,并处理返回数据
运行效果
我们看到这里,已经初步完成了ctrl+c+c进行翻译的功能,剩下的就是进行一些小优化,如生成窗口展示数据
4 小窗口展示剪切板内容和翻译内容
因为笔者对java的gui窗口不是很了解,这里使用chatgpt工具生成了小窗口,可能有些简陋,读者可以自己美化一下
新建一个MyWindows
类
import javax.swing.*;
import java.awt.*;public class MyWindow extends JFrame {private JTextArea textArea;public MyWindow() {setTitle("Text Window");setSize(400, 300);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);textArea = new JTextArea();//设置字体大小textArea.setFont(new Font("SimSun", Font.PLAIN, 16));// 自动换行textArea.setLineWrap(true);// 断行不断字textArea.setWrapStyleWord(true);JPanel panel = new JPanel();setVisible(true);add(textArea, "Center");add(panel, "South");}//写入文本public void writeText(String text) {textArea.append(text + "\n");}//清楚文本public void clearText() {textArea.setText("");}public static void main(String[] args) {MyWindow window = new MyWindow();window.setVisible(true);}
}
在GlobalKeyListenerExample
类中初始化MyWindow:
在获取翻译后,清除原来的文字,写入新的文字:
运行:
完整代码
ClipBoardUtil
类,TransApi
类,MyWindow
类上文已給出完整代码。
GlobalKeyListenerExample
类:
import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.github.kwhat.jnativehook.GlobalScreen;
import com.github.kwhat.jnativehook.NativeHookException;
import com.github.kwhat.jnativehook.keyboard.NativeKeyEvent;
import com.github.kwhat.jnativehook.keyboard.NativeKeyListener;
import com.icepeach.Utils.ClipBoardUtil;
import com.icepeach.Utils.GUI.MyWindow;public class GlobalKeyListenerExample implements NativeKeyListener {String key = "";private static final String APP_ID = "你的appid";private static final String SECURITY_KEY = "你的密钥";TransApi api = new TransApi(APP_ID, SECURITY_KEY);MyWindow window = new MyWindow();public void nativeKeyPressed(NativeKeyEvent e) {if ("Ctrl".equals(NativeKeyEvent.getKeyText(e.getKeyCode()))) {key = new String("Ctrl");} else {key += NativeKeyEvent.getKeyText(e.getKeyCode());}if ("CtrlCC".equals(key)) {window.setVisible(true);//打印剪切板内容System.out.println("剪切板内容为:" + ClipBoardUtil.getClipboardText());//调用翻译接口String jsonStr = api.getTransResult(ClipBoardUtil.getClipboardText(), "auto", "zh");// 解析JSON字符串JSONObject jsonObject = JSONUtil.parseObj(jsonStr);// 获取trans_result数组中的第一个元素JSONObject transResult = jsonObject.getJSONArray("trans_result").getJSONObject(0);// 获取dst中的内容并转换成中文String dst = transResult.getStr("dst");String chineseDst = UnicodeUtil.toString(dst);System.out.println("翻译:"+chineseDst);window.clearText();window.writeText("剪切板内容为:" + ClipBoardUtil.getClipboardText());window.writeText("翻译:"+chineseDst);}if (e.getKeyCode() == NativeKeyEvent.VC_ESCAPE) {try {GlobalScreen.unregisterNativeHook();} catch (NativeHookException nativeHookException) {nativeHookException.printStackTrace();}}}public void nativeKeyReleased(NativeKeyEvent e) {
// System.out.println("Key Released: " + NativeKeyEvent.getKeyText(e.getKeyCode()));}public void nativeKeyTyped(NativeKeyEvent e) {
// System.out.println("Key Typed: " + e.getKeyText(e.getKeyCode()));}public static void main(String[] args) {try {GlobalScreen.registerNativeHook();} catch (NativeHookException ex) {System.err.println("There was a problem registering the native hook.");System.err.println(ex.getMessage());System.exit(1);}GlobalScreen.addNativeKeyListener(new GlobalKeyListenerExample());}
}