用Java做一个及时翻译工具
平時看英文文檔或者查詢資料的時候,遇到了不懂的單詞,就要去百度,然后就會很麻煩。于是就想到用Java寫一個及時翻譯的小工具!
預期的實現效果:
雙擊選中一個單詞,按下Ctrl+C進行復制
然后馬上顯示出對應單詞的中文翻譯
首先基本思路是這樣的:
- 首先獲取系統剪切板的內容
- 將該內容發送到網頁上,然后獲取網頁的源碼,查找到對應的中文解釋
- 將中文翻譯顯示出來
以上就是基本的思路!但是實際操作的時候還是遇到了很大的困難的。
先寫兩個接口
得到剪切板的內容
這個并不是很困難,畢竟java有提供對應的API,代碼如下:
package translate; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable;public class ClipboradUtils {protected static String getClipboardText() throws Exception{Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();//獲取系統剪貼板// 獲取剪切板中的內容Transferable clipT = clip.getContents(null);if (clipT != null) {// 檢查內容是否是文本類型if (clipT.isDataFlavorSupported(DataFlavor.stringFlavor))return (String)clipT.getTransferData(DataFlavor.stringFlavor); }return null;} }以上是放在一個工具類,做成靜態函數方便調用!
獲取網頁源碼
首先想到是就是去百度翻譯
我們在這里翻譯單詞 blue
我們看地址欄http://fanyi.baidu.com/?aldtype=16047#en/zh/blue,剛好我們要翻譯的單詞就在最后,所以只要爬取頁面http://fanyi.baidu.com/?aldtype=16047#en/zh/待查單詞的源代碼,然后做一些篩選就可以了!
然后事情進展的卻并不是那么的順利,百度的這個應該是為了防止爬取,所以翻譯的操作應該是Dom操作,源代碼上面毫無翻譯痕跡。
這個方法就終止了。
然后想到的是百度翻譯是否有開放接口
果然,百度翻譯提供了開放的接口,但是貌似要收費。
http://api.fanyi.baidu.com/api/trans/product/index
當然,我建議大家用這個方法,畢竟人家公司也不容易,而且功能也相對很豐富。
但是,如果真的不想花錢就不行了嗎?答案是否定的!
意外收獲
我在百度直接搜索一個單詞的是否發現也會出現對應的翻譯!如下:
然后查看一下源代碼,搜索藍色,果然,源代碼上面是有翻譯結果的(偷笑)。
而且對應的翻譯內容就在<span class="op_dict_text2">和</span>之間!
百度搜索的url對應的是http://www.baidu.com/s?wd="搜索內容"
于是就可以把獲取翻譯內容的工具類寫好了,代碼如下:
package translate;import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL;public class GetHtmlContentUtils {private final static String PreUrl="http://www.baidu.com/s?wd="; //百度搜索URLprivate final static String TransResultStartFlag="<span class=\"op_dict_text2\">"; //翻譯開始標簽private final static String TransResultEndFlag="</span>"; //翻譯結束標簽public static String getTranslateResult(String urlString) throws Exception { //傳入要搜索的單詞URL url = new URL(PreUrl+urlString); //生成完整的URL// 打開URLHttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();// 得到輸入流,即獲得了網頁的內容BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));String preLine="";String line;int flag=1;// 讀取輸入流的數據,并顯示String content=""; //翻譯結果while ((line = reader.readLine()) != null) { //獲取翻譯結果的算法if(preLine.indexOf(TransResultStartFlag)!=-1&&line.indexOf(TransResultEndFlag)==-1){content+=line.replaceAll(" | ", "")+"\n"; //去電源代碼上面的半角以及全角字符flag=0;}if(line.indexOf(TransResultEndFlag)!=-1){flag=1;}if(flag==1){preLine=line;}}return content;//返回翻譯結果}}再寫一個窗體界面
注:有了上面的核心算法,下面的其實都隨意實現了!
界面實現
我設計的窗體界面如下:
簡單說一下界面布局:最上面一個JTextField和JCheckBox,下面是JTextArea。
簡單說一下各個控件的作用:
JTextField:顯示待翻譯的單詞
JCheckBox:表示是從剪切板獲取單詞還是自己直接輸入
JTextArea:顯示翻譯結果
實現思路
界面已經實現完成了,那么思路是什么呢?
我的思路是這樣的:
- 開啟一個線程,將JTextField里面的值不斷設置為剪切板里面的值
- 如果JTextField里面的值改變了(剪切板的值改變了,也就是選中復制了新的單詞),調用GetHtmlContentUtils 里面的方法獲取翻譯的結果,并顯示!
對應代碼如下:
package translate;import java.awt.BorderLayout; import java.awt.Container; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.border.LineBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener;public class MainFrame extends JFrame implements Runnable {private JTextField srcContentTextField; // 記錄剪切板的內容private JTextArea resContentTextField; // 記錄翻譯的內容private JCheckBox translateFlag; //標記單詞的獲取來源//選中:手動輸入 未選中:剪切板獲取private Container topContainer;public MainFrame() {//初始化控件srcContentTextField = new JTextField(10);resContentTextField = new JTextArea();translateFlag = new JCheckBox();topContainer = new Container();}public void setMinWindowLayout() {// TODO Auto-generated method stub//布局設置resContentTextField.setBorder(new LineBorder(new java.awt.Color(127, 157, 185), 1, false));this.setLayout(new BorderLayout());this.add(this.resContentTextField);translateFlag.setToolTipText("手動輸入取詞");topContainer.setLayout(new BorderLayout());topContainer.add(srcContentTextField, BorderLayout.CENTER);topContainer.add(translateFlag, BorderLayout.EAST);this.add(this.topContainer, BorderLayout.NORTH);this.setResizable(false);translateFlag.addActionListener(new ActionListener() {//設置JCheckBox的監聽@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubif (translateFlag.isSelected()) {translateFlag.setToolTipText("自動復制取詞"); //設置提示} else {translateFlag.setToolTipText("手動輸入取詞");}}});//監聽JTextField里面內容改變的事件srcContentTextField.getDocument().addDocumentListener(new DocumentListener() { @Overridepublic void changedUpdate(DocumentEvent arg0) {}@Overridepublic void insertUpdate(DocumentEvent arg0) { //內容改變try {//調用接口獲取翻譯結果String result = GetHtmlContentUtils.getTranslateResult(srcContentTextField.getText());if (result == "")result = "!Sorry,未找到該詞!";resContentTextField.setText(result);//顯示翻譯結果} catch (Exception e) {// TODO Auto-generated catch blockresContentTextField.setText("!Sorry,未找到該詞!");}}@Overridepublic void removeUpdate(DocumentEvent arg0) {}});this.validate();}@Overridepublic void run() {// TODO Auto-generated method stubwhile (true) {if (!translateFlag.isSelected()) { //如果JCheckBox沒有被選中,則從剪切板獲取單詞try {String content = ClipboradUtils.getClipboardText();srcContentTextField.setText(getSimpleWord(content));} catch (Exception e) { // TODO Auto-generated catch blocke.printStackTrace();}}try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public static String getSimpleWord(String content) {//去掉切板里面的一些特殊字符return content.replace(".", "").replace(",", "").replace("'", "").replace(":", "").replace(";", "").trim();} }接下來就是main函數了,代碼如下:
package translate;import javax.swing.JFrame;public class TranslateTool {public static void main(String[] args) {MainFrame mainFrame = new MainFrame();mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);mainFrame.setBounds(300, 200, 400, 300);mainFrame.setVisible(true);mainFrame.setAlwaysOnTop(true);//設置在最頂層mainFrame.setMinWindowLayout();Thread t = new Thread(mainFrame);t.start(); //開啟線程} }程序運行結果
隨手翻譯了下 public 關鍵字,感覺還是可以的!
以下是2017/03/19日的補充
從eclipse導出jar包時候,發現顯示的翻譯亂碼了。
找了半天的資料,有以下兩種解決方案:
- 在控制臺運行:
java -Dfile.encoding=utf-8 -jar
C:\Users\lenovo\Desktop\TranslateTool.jar(可執行jar的路徑)
- 設置JAVA_TOOL_OPTIONS:
有關JAVA_TOOL_OPTIONS,參考:
http://docs.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#tooloptions
現在就可以在系統環境變量中增加一個變量,變量名為:
JAVA_TOOL_OPTIONS, 變量值為:-Dfile.encoding=UTF-8
這樣就基本可以解決亂碼問題。如果你有好的解決方案,歡迎留言
軟件下載地址:下載及時翻譯工具
總結
以上是生活随笔為你收集整理的用Java做一个及时翻译工具的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 幼儿园观察记录的目的和目标_幼儿园观察记
- 下一篇: GeoDa空间自相关分析和计量模型的权重