码迷,mamicode.com
首页 > 其他好文 > 详细

人工智能初体验(二):开发简单的图灵智能聊天工具

时间:2015-12-24 08:10:29      阅读:409      评论:0      收藏:0      [点我收藏+]

标签:java   人工智能   图灵   图灵机器人   

前言:这里为了有更好的个性化设置,因此我选择了图灵机器人(http://www.tuling123.com/)的接口,使用方法跟上一篇中使用百度的接口是差不多的。

注:文末有打包好的小软件和完整源代码的下载链接技术分享

一 API Key申请

申请地址:http://www.tuling123.com/

中间的注册登录过程不说,最后把API Key值记录下来

技术分享

二 核心功能开发

这个小项目的目录结构:

技术分享

核心功能文件TuringRobot.java,代码很简单,一看就明白,代码如下:

package action;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TuringRobot {
	/**
	 * 使用图灵机器人接口获取回答
	 * 
	 * @param apikey API认证
	 * @param info 想要请求的问题
	 * @return 获取的回复
	 * */
	public static String getResponse(String apikey,String info){
		String httpUrl;
		try {
			httpUrl = "http://www.tuling123.com/openapi/api?key=" + apikey + "&info=" + URLEncoder.encode(info,"UTF-8");
			URL url = new URL(httpUrl);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("GET");
			connection.setReadTimeout(5000);
			connection.setConnectTimeout(5000);
			
			InputStream inputStream = connection.getInputStream();
			BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
			String line = "";
			String reg = "\"text\":\"(.*)?\"}";
			Pattern pattern = Pattern.compile(reg);
			Matcher matcher;
			while((line = reader.readLine()) != null){
				matcher = pattern.matcher(line);
				if(matcher.find()){
					connection.disconnect();
					return matcher.group(1);
				}
			}
			connection.disconnect();	
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}
	
	/**
	 * 使用百度接口获取回答
	 * 
	 * @param key 默认值:879a6cb3afb84dbf4fc84a1df2ab7319
	 * @param ApiKey 在APIStore调用服务所需要的API密钥,申请地址:http://apistore.baidu.com
	 * @param info 想要请求的问题
	 * @param userid 用户id 默认值:eb2edb736
	 * 
	 * @return 获取的回复
	 * */
	public static String getResponse(String key,String ApiKey,String info,String userid){
		String httpUrl = "http://apis.baidu.com/turing/turing/turing?";
		try {
			info = URLEncoder.encode(info,"UTF-8");  
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		String httpArg = "key=" + key + "&info=" + info + "&userid=" + userid;
		try {
			URL url = new URL(httpUrl + httpArg);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("GET");
			connection.setRequestProperty("apikey", ApiKey);
			
			InputStream inputStream = connection.getInputStream();
			BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
			String line = "";
			String reg = "\"text\":\"(.*)?\",\"code\"";
			Pattern pattern = Pattern.compile(reg);
			Matcher matcher;
			while((line = reader.readLine()) != null){
				matcher = pattern.matcher(line);
				if(matcher.find()){
					connection.disconnect();
					return matcher.group(1);
				}
			}	
			connection.disconnect();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
		
	}

}

三 前台界面开发

在界面开发中有几个关键点需要注意:

(1)使用了新的线程来执行数据获取过程,并且通过SwingUtilities.invokeLater()来通知EDT更新界面。具体技术可以参考我写的这篇文章:http://www.zifangsky.cn/2015/12/java中事件分发线程(edt)与swingutilities-invokelater相关总结/

(2)本来最开始是使用了JTextArea来显示聊天记录,后来发现不能对聊天双方的记录分别左对齐和右对齐,而且也不能对聊天记录中的文字颜色和字体进行个性化设置,因此后来将聊天界面的JTextArea改成了JTextPane。这是一个强大的控件,我这里仅仅只是进行了简单使用,看代码就明白了

(3)API Key保存在配置文件config/config.txt中了

技术分享

界面代码如下:

package view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

import action.TuringRobot;

public class MainView extends JFrame implements ActionListener, WindowListener, KeyListener{
	/**
	 * @author zifangsky
	 * @blog www.zifangsky.cn
	 * @date 2015-12-21
	 * @version v1.0.0
	 * 
	 * */
	private static final long serialVersionUID = 1L;
	private JPanel mainJPanel,tipJPanel;
	private JScrollPane message_JScrollPane,edit_JScrollPane;
	private JTextArea edit_JTextArea;
	private JButton close,submit;
	private JTextPane messageJTextPane;
	private DefaultStyledDocument doc;
	
	private JMenuBar jMenuBar;
	private JMenu help;
	private JMenuItem author,contact,version,readme;

	private Font contentFont = new Font("宋体", Font.LAYOUT_NO_LIMIT_CONTEXT, 16);  //正文字体
	private Font menuFont = new Font("宋体", Font.LAYOUT_NO_LIMIT_CONTEXT, 14);  //菜单字体
	private Color buttonColor = new Color(85,76,177);  //按钮背景色
	Color inputColor1 = new Color(31,157,255);  //输入相关颜色
	Color inputColor2 = new Color(51,51,51);  //输入相关颜色
	Color outputColor1 = new Color(0,186,4);  //返回相关颜色
	Color outputColor2 = new Color(51,51,51);  //返回相关颜色
	

	private DataOperating dataOperating = null;  //数据操作线程
	private Runnable updateInputInterface,updateResponseInterface;  //更新界面线程
	
	private String inputString = "",responseString = ""; 
	private String key = "";  
	
	public MainView(){
		super("图灵智能聊天");
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		screenSize = Toolkit.getDefaultToolkit().getScreenSize();  //屏幕大小
		setPreferredSize(new Dimension(350, 600));
		int frameWidth = this.getPreferredSize().width;  //界面宽度
		int frameHeight = this.getPreferredSize().height;  //界面高度
		setSize(frameWidth,frameHeight);
		setLocation((screenSize.width - frameWidth) / 2,(screenSize.height - frameHeight) / 2);
		//初始化
		mainJPanel = new JPanel();
		tipJPanel = new JPanel();
		message_JScrollPane = new JScrollPane();
		edit_JScrollPane = new JScrollPane();
		messageJTextPane = new JTextPane();
		doc = new DefaultStyledDocument();
		edit_JTextArea = new JTextArea(5, 10);
		close = new JButton("关闭");
		submit = new JButton("发送");		
		jMenuBar = new JMenuBar();
		help = new JMenu("帮助");
		author = new JMenuItem("作者");
		contact = new JMenuItem("联系方式");
		version = new JMenuItem("版本");
		readme = new JMenuItem("说明");
		
		//设置字体
		messageJTextPane.setFont(contentFont);
		edit_JTextArea.setFont(contentFont);
		close.setFont(contentFont);
		submit.setFont(contentFont);
		help.setFont(menuFont);
		author.setFont(menuFont);
		contact.setFont(menuFont);
		version.setFont(menuFont);
		readme.setFont(menuFont);
		//布局
		mainJPanel.setLayout(new BorderLayout());
		mainJPanel.add(message_JScrollPane,BorderLayout.NORTH);
		mainJPanel.add(edit_JScrollPane,BorderLayout.CENTER);
		mainJPanel.add(tipJPanel,BorderLayout.SOUTH);
		messageJTextPane.setPreferredSize(new Dimension(350, 350));
		messageJTextPane.setBackground(new Color(204,232,207));
		message_JScrollPane.getViewport().add(messageJTextPane);
		edit_JScrollPane.getViewport().add(edit_JTextArea);
		edit_JTextArea.setBackground(new Color(204,232,207));
		edit_JTextArea.requestFocus();
		tipJPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 10));
		tipJPanel.add(close);
		tipJPanel.add(submit);
		close.setBackground(buttonColor);
		close.setForeground(Color.WHITE);
		submit.setBackground(buttonColor);
		submit.setForeground(Color.WHITE);
		
		messageJTextPane.setEditable(false);
		edit_JTextArea.setLineWrap(true);
		edit_JTextArea.setWrapStyleWord(true);
		
		jMenuBar.add(help);
		help.add(author);
		help.add(contact);
		help.add(version);
		help.add(readme);

		add(mainJPanel);
		setJMenuBar(jMenuBar);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		addWindowListener(this);
		//获取配置文件中的配置信息
		try {
			BufferedReader reader = new BufferedReader(new FileReader(new File("config/config.txt")));
			String line = reader.readLine();  //第一行不要
			Pattern pattern = Pattern.compile("key=(.*)?");
			Matcher matcher;
			while((line = reader.readLine()) != null){
				matcher = pattern.matcher(line);
				if(matcher.find())
					key = matcher.group(1);
				break;	
			}	
			reader.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		//点击事件
		close.addActionListener(this);
		submit.addActionListener(this);
		author.addActionListener(this);
		contact.addActionListener(this);
		version.addActionListener(this);
		readme.addActionListener(this);
		//键盘时间
		edit_JTextArea.addKeyListener(this);
		//输入对话,提交后触发,更新界面
		updateInputInterface = new Runnable() {
			public void run() {
				messageJTextPane.setEditable(true);
				
				setInputString("我[" + getDateString() + "]:", inputColor1, true, contentFont);
				setInputString(inputString + "\n", inputColor2, false, menuFont);
				messageJTextPane.selectAll();
				messageJTextPane.setCaretPosition(messageJTextPane.getSelectionEnd());
				messageJTextPane.setEditable(false);
			}
		};
		//获取到回答后触发,更新界面
		updateResponseInterface = new Runnable() {
			public void run() {
				messageJTextPane.setEditable(true);

				setResponseString("智子[" + getDateString() + "]:", outputColor1, true, contentFont);
				setResponseString(responseString + "\n", outputColor2, false, menuFont);
				messageJTextPane.selectAll();
				messageJTextPane.setCaretPosition(messageJTextPane.getSelectionEnd());
				messageJTextPane.setEditable(false);
				
				inputString = "";
				responseString = "";
				edit_JTextArea.setText("");
				edit_JTextArea.requestFocus();
				dataOperating = null;
			}
		};
	}
	
	
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				new MainView();
			}
		});
	}

	/**
	 * 输入的信息在界面显示出来
	 * */
	private void setInputString(String str,Color color,boolean bold,Font font){
		MutableAttributeSet attributeSet = new SimpleAttributeSet();
		StyleConstants.setForeground(attributeSet, color);  //设置文字颜色
		if(bold)
			StyleConstants.setBold(attributeSet, true);  //设置加粗
		StyleConstants.setFontFamily(attributeSet, "Consolas");  //设置字体
		StyleConstants.setFontSize(attributeSet, font.getSize());  //设置字体大小
		StyleConstants.setAlignment(attributeSet, StyleConstants.ALIGN_RIGHT);  //左对齐
		insertText(str,attributeSet);
	}
	/**
	 * 返回的信息在界面显示出来
	 * */
	private void setResponseString(String str,Color color,boolean bold,Font font){
		MutableAttributeSet attributeSet = new SimpleAttributeSet();
		StyleConstants.setForeground(attributeSet, color);
		if(bold)
			StyleConstants.setBold(attributeSet, true);
		StyleConstants.setFontFamily(attributeSet, "Consolas");
		StyleConstants.setFontSize(attributeSet, font.getSize());
		StyleConstants.setAlignment(attributeSet, StyleConstants.ALIGN_LEFT);
		insertText(str,attributeSet);
	}

	/**
	 * 在JTextPane中插入文字
	 * */
	private void insertText(String str, MutableAttributeSet attributeSet) {
		messageJTextPane.setStyledDocument(doc);
		str += "\n";
		doc.setParagraphAttributes(doc.getLength(), str.length(), attributeSet, false);
		try {
			doc.insertString(doc.getLength(), str, attributeSet);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 点击事件
	 * */
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == close){
			System.exit(0);
		}
		else if(e.getSource() == submit){
			if(dataOperating == null){
				dataOperating = new DataOperating();
				new Thread(dataOperating).start();
			}
		}
		else if(e.getSource() == author){
			JOptionPane.showMessageDialog(this, "zifangsky","作者:",JOptionPane.INFORMATION_MESSAGE);
		}
		else if(e.getSource() == contact){
			JOptionPane.showMessageDialog(this, "邮箱:admin@zifangsky.cn\n" +
					"博客:www.zifangsky.cn","联系方式:",JOptionPane.INFORMATION_MESSAGE);
		}
		else if(e.getSource() == version){
			JOptionPane.showMessageDialog(this, "v1.0.0","版本号:",JOptionPane.INFORMATION_MESSAGE);
		}
		else if(e.getSource() == readme){
			JOptionPane.showMessageDialog(this, "本程序只是简单的智能聊天,没有多余的功能。源码已经在我博客进行开源,\n" +
					"有需求的可以在此基础上进行APP开发,移植到Android平台上去。","说明:",JOptionPane.INFORMATION_MESSAGE);
		}
		
	}
	
	/**
	 * 具体的数据处理内部类
	 * */
	private class DataOperating implements Runnable{
		public void run() {
			//获取输入
			inputString = edit_JTextArea.getText().trim();
			if(inputString == null || "".equals(inputString))
				return;
			SwingUtilities.invokeLater(updateInputInterface);
			//获取回复
			responseString = TuringRobot.getResponse(key, inputString);
			SwingUtilities.invokeLater(updateResponseInterface);
		}
		
	}
	
	/**
	 * 获取当前时间的字符串
	 * @return 当前时间的字符串
	 * */
	private String getDateString(){
		Date date = new Date();
		Format format = new SimpleDateFormat("HH:mm:ss");
		return format.format(date);				
	}

	public void windowOpened(WindowEvent e) {
		
	}

	public void windowClosing(WindowEvent e) {
		System.exit(0);
	}

	public void windowClosed(WindowEvent e) {

	}

	public void windowIconified(WindowEvent e) {

	}

	public void windowDeiconified(WindowEvent e) {

	}

	public void windowActivated(WindowEvent e) {
		
	}

	public void windowDeactivated(WindowEvent e) {
		
	}

	public void keyTyped(KeyEvent e) {
		
	}
	/**
	 * 键盘事件,键盘按下ENTER键触发
	 * */
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode() == KeyEvent.VK_ENTER){
			if(dataOperating == null){
				dataOperating = new DataOperating();
				new Thread(dataOperating).start();
			}
		}
		
	}

	public void keyReleased(KeyEvent e) {
		
	}

}

四 运行效果

技术分享

技术分享

附:源代码和打包好的可执行jar下载:http://down.51cto.com/data/2133061  

(PS:如果没有下载豆的话,可以看我个人博客上的这篇文章,文末有百度云盘的下载链接。传送门:http://www.zifangsky.cn/2015/12/人工智能初体验(二):开发简单的图灵智能聊天/

本文出自 “zifangsky的个人博客” 博客,请务必保留此出处http://983836259.blog.51cto.com/7311475/1727742

人工智能初体验(二):开发简单的图灵智能聊天工具

标签:java   人工智能   图灵   图灵机器人   

原文地址:http://983836259.blog.51cto.com/7311475/1727742

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!