最近用java模拟“会说话的汤姆猫”做了一个超级简陋的小程序。重点研究了一下JFrame(javax.swing.JFram)、SequentialGroup(javax.swing.GroupLayout.SequentialGroup)、ParallelGroup(javax.swing.GroupLayout. ParallelGroup)、Canvas(java.awt.Canvas)、Graphics(java.awt.Graphics)的使用。
程序效果如下: 欢迎大家下载这个小程序的可运行jar包!趣味聊天demo.jar
可以在问题框中输入任意问题与小猫对话。当输入问题时,小猫会做出聆听状态。
点击发送后,小猫做回答状态。对于各种问题的答案,这里调用的是欧拉蜜智能语音api,详情可参考http://cn.olami.ai
主要代码如下:
1、界面MyJFrame:
import java.awt.Canvas;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.net.URL;
import javax.swing.GroupLayout.Alignment;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import com.alibaba.fastjson.JSONObject;
public class MyJFrame extends javax.swing.JFrame {
private static final long serialVersionUID = 1L;
private NLIProcess nlp = new NLIProcess();
private JButton jButton_send;
private JLabel jLabel1;
private JLabel jLabel2;
private JPanel jPanel1;
private JPanel jPanel2;
private JTextField jTextField1;
private JTextField jTextField2;
private Image act1;
private Image act2;
// 初始图像编号
int actPhase = 1;
Canvas c = null;
public MyJFrame() {
getImage();
initComponents();
}
private void getImage(){
setBackground(Color.BLACK);
URL imageUrl = getClass().getResource("image/img0.png");
act1 = Toolkit.getDefaultToolkit().createImage(imageUrl);
imageUrl = getClass().getResource("image/img3.png");
act2 = Toolkit.getDefaultToolkit().createImage(imageUrl);
}
private void initComponents() {
jPanel1 = new JPanel();
jLabel1 = new JLabel();
jLabel2 = new JLabel();
jTextField1 = new JTextField();
jTextField2 = new JTextField();
jButton_send = new JButton();
jPanel2 = new JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setMinimumSize(new java.awt.Dimension(400, 300));
jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("智能问答"));
jLabel1.setText("问题:");
jLabel2.setText("回答:");
jTextField1.setText("你多大了?");
jTextField2.setEnabled(false);
jButton_send.setText("send");
jButton_send.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton_sendActionPerformed(evt);
}
});
jTextField1.addFocusListener(new FocusListener(){
@Override
public void focusGained(FocusEvent arg0) {
// TODO Auto-generated method stub
actPhase = 2;
c.repaint();
}
@Override
public void focusLost(FocusEvent arg0) {
// TODO Auto-generated method stub
actPhase = 1;
c.repaint();
}
});
GroupLayout jPanel1Layout = new GroupLayout(jPanel1);
GroupLayout.SequentialGroup hGroup = jPanel1Layout.createSequentialGroup();
hGroup.addGap(8);
hGroup.addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(jLabel1)
.addComponent(jLabel2));
hGroup.addGap(5);
hGroup.addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(jTextField1)
.addComponent(jTextField2));
hGroup.addGap(5);
hGroup.addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(jButton_send));
hGroup.addGap(8);
jPanel1Layout.setHorizontalGroup(hGroup);
GroupLayout.SequentialGroup vGroup = jPanel1Layout.createSequentialGroup();
vGroup.addGap(8);
vGroup.addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(jLabel1)
.addComponent(jTextField1).addComponent(jButton_send));
vGroup.addGap(3);
vGroup.addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(jLabel2)
.addComponent(jTextField2));
vGroup.addGap(8);
//设置垂直组
jPanel1Layout.setVerticalGroup(vGroup);
jPanel1.setLayout(jPanel1Layout);
jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("可爱小猫"));
jPanel2.setLayout(new FlowLayout());
c = new MyCanvas();
jPanel2.add(c);
GroupLayout layout = new GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
.addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())
);
pack();
}
private void jButton_sendActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
JSONObject result = nlp.process(jTextField1.getText());
jTextField2.setText(nlp.getAnswer(result));
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
MyJFrame frame = new MyJFrame();
frame.setTitle("自然语言理解试验小程序——趣味聊天");
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
class MyCanvas extends Canvas {
private static final long serialVersionUID = 1L;
public MyCanvas () {
setBackground (Color.GRAY);
setSize(300, 320);
}
public void paint (Graphics g) {
Graphics2D g2;
g2 = (Graphics2D) g;
update(g2);
}
public void update(Graphics g) {
if (actPhase == 1) {
g
.drawImage(act1, getWidth() / 2
- act1.getWidth(null) / 2, getHeight() / 2
- act1.getHeight(null) / 2, act1
.getWidth(null), act1.getHeight(null), this);
} else {
g
.drawImage(act2, getWidth() / 2
- act2.getWidth(null) / 2, getHeight() / 2
- act2.getHeight(null) / 2, act2
.getWidth(null), act2.getHeight(null), this);
}
}
}
}
2、语义理解NLIProcess:
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
public class NLIProcess {
private static final String url = "https://cn.olami.ai/cloudservice/api";
private static final String Appkey = "beaf1c8e85894e1c90b333670d479581";
private static final String Appsecret = "52b158f9c8b741218dcf3931136611b6";
private static final String api = "nli";
public String getAnswer(JSONObject semantic) {
String error = "你刚才说什么,我没有听懂。";
if (semantic == null || !"ok".equalsIgnoreCase(semantic.getString("status")))
return error;
JSONObject data = semantic.getJSONObject("data");
JSONArray s_list = data.getJSONArray("nli");
JSONObject s_first = s_list.getJSONObject(0);
JSONObject desc_obj = s_first.getJSONObject("desc_obj");
int status = desc_obj.getIntValue("status");
if (0 == status) {
return desc_obj.getString("result");
}
return error;
}
public JSONObject process (String input) {
JSONObject NLIresult = new JSONObject();
List params = new ArrayList();
params.add(new BasicNameValuePair("appkey", Appkey));
params.add(new BasicNameValuePair("api", api));
long timestamp = Calendar.getInstance().getTimeInMillis();
params.add(new BasicNameValuePair("timestamp", String.valueOf(timestamp)));
params.add(new BasicNameValuePair("sign", generateSign(timestamp)));
JSONObject request = new JSONObject();
JSONObject data = new JSONObject();
try {
data.put("input_type", 0);
data.put("text", input);
request.put("data_type", "stt");
request.put("data", data);
} catch (JSONException e1) {
e1.printStackTrace();
return NLIresult;
}
params.add(new BasicNameValuePair("rq", request.toString()));
params.add(new BasicNameValuePair("cusid", "asdfghj"));
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost(url);
try {
httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
CloseableHttpResponse response = httpclient.execute(httppost);
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
String contnt = EntityUtils.toString(entity);
NLIresult = JSONObject.parseObject(contnt);
}
} finally {
response.close();
}
} catch (Exception e) {
e.printStackTrace();
return NLIresult;
} finally {
try {
httpclient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return NLIresult;
}
private String generateSign(long timestamp) {
String sign = Appsecret + "api=" + api + "appkey=" + Appkey + "timestamp=" + timestamp + Appsecret;
return MD5String(sign);
}
public String MD5String(String str) {
try {
MessageDigest msgDigest = MessageDigest.getInstance("MD5");
msgDigest.reset();
msgDigest.update(str.getBytes("UTF-8"));
byte[] byteArrary = msgDigest.digest();
StringBuffer md5StrBuff = new StringBuffer();
for (int i = 0; i < byteArrary.length; i++) {
String tmp = Integer.toHexString(0xFF & byteArrary[i]);
if (tmp.length() == 1) {
md5StrBuff.append(0).append(tmp);
} else {
md5StrBuff.append(tmp);
}
}
return md5StrBuff.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}
欢迎大家下载这个小程序的可运行jar包!趣味聊天demo.jar
关于其他根据olami平台开发的小程序还有:
Olami智能语义解析—学习娱乐小能手
根据OLAMI平台开发的日历Demo
用olami开放语义平台做汇率换算应用
微信小程序+OLAMI自然语言API接口制作智能查询工具–快递、聊天、日历等
用语义开放平台olami开发翻译应用
热门自然语言理解和语音API开发平台对比
使用OLAMI SDK和讯飞语音合成制作一个语音回复的短信小助手
告诉你如何使用OLAMI自然语言理解开放平台API制作自己的智能对话助手