用Java做一个及时翻译工具

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

                       

平时看英文文档或者查询资料的时候,遇到了不懂的单词,就要去百度,然后就会很麻烦。于是就想到用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;    }}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

以上是放在一个工具类,做成静态函数方便调用!

获取网页源码

首先想到是就是去百度翻译

翻译页面

我们在这里翻译单词 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=";                        //百度搜索URL    private 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        // 打开URL        HttpURLConnection 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;//返回翻译结果    }}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

再写一个窗体界面

注:有了上面的核心算法,下面的其实都随意实现了!

界面实现

我设计的窗体界面如下:
窗体

简单说一下界面布局:最上面一个JTextFieldJCheckBox,下面是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的监听            @Override            public void actionPerformed(ActionEvent e) {                // TODO Auto-generated method stub                if (translateFlag.isSelected()) {                    translateFlag.setToolTipText("自动复制取词");    //设置提示                } else {                    translateFlag.setToolTipText("手动输入取词");                }            }        });        //监听JTextField里面内容改变的事件        srcContentTextField.getDocument().addDocumentListener(new DocumentListener() {                @Override            public void changedUpdate(DocumentEvent arg0) {            }            @Override            public 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 block                    resContentTextField.setText("!Sorry,未找到该词!");                }            }            @Override            public void removeUpdate(DocumentEvent arg0) {            }        });        this.validate();    }    @Override    public void run() {        // TODO Auto-generated method stub        while (true) {            if (!translateFlag.isSelected()) {  //如果JCheckBox没有被选中,则从剪切板获取单词                try {                    String content = ClipboradUtils.getClipboardText();                    srcContentTextField.setText(getSimpleWord(content));                } catch (Exception e) {                     // TODO Auto-generated catch block                    e.printStackTrace();                }            }            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }    public static String getSimpleWord(String content) {//去掉切板里面的一些特殊字符        return content.replace(".", "").replace(",", "")                .replace("'", "").replace(":", "")                .replace(";", "").trim();    }}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117

接下来就是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();    //开启线程    }}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

程序运行结果

public

随手翻译了下 public 关键字,感觉还是可以的!


以下是2017/03/19日的补充
从eclipse导出jar包时候,发现显示的翻译乱码了。
找了半天的资料,有以下两种解决方案:

  • 在控制台运行:
 

java -Dfile.encoding=utf-8 -jar 
  C:\Users\lenovo\Desktop\TranslateTool.jar(可执行jar的路径)

 

现在就可以在系统环境变量中增加一个变量,变量名为: 
  JAVA_TOOL_OPTIONS, 变量值为:-Dfile.encoding=UTF-8

这样就基本可以解决乱码问题。如果你有好的解决方案,欢迎留言 错错错

软件下载地址:下载及时翻译工具

           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_43685425/article/details/84035831