网络聊天应用程序Word下载.docx
《网络聊天应用程序Word下载.docx》由会员分享,可在线阅读,更多相关《网络聊天应用程序Word下载.docx(18页珍藏版)》请在冰点文库上搜索。
详细设计
创建多线程方法为
newThread(newReceiveThread()).start();
classReceiveTreadimplementsRunnable{
@Override
publicvoidrun(){
///线程要执行的内容
}
DatagramSocket类实现网络通信
DatagramSocketds=newDatagramSocket(port);
表示监听本机的port端口
DatagramPacket类能封装发送或者接收的数据
接收数据
DatagramPacketdp=newDatagramPacket(b,size);
ds.receive(dp);
byte[]b=dp.getData();
Stringstr=newString(b);
byteb=“content”.getBytes();
DatagramPacketdp=newDatagramPacket(b,b.length,InetAddress.getByName(host),port);
ds.send(dp);
显示
privateJButtonsendButton;
//发送按钮
privateJTextAreasendArea;
//发送区域
privateTextAreashowArea;
//接收区域
往显示区域添加消息
showArea.append(message);
从发送区域获得要发送的字符
Stringstr=sendArea.getText();
给发送区域添加键盘监听,用于实现快捷键发送
sendArea.addKeyListener(newKeyAdapter());
给发送按钮添加活动监听,当点击时发送消息
sendButton.addActionListener(newActionListener());
程序代码
Chat.java
packagecn.hnist.main;
importjavax.swing.JFrame;
importjavax.swing.UIManager;
importcn.hnist.controller.Controller;
publicclassChat{
publicstaticvoidmain(String[]args){
//设置字体
try{
UIManager.put("
swing.boldMetal"
Boolean.FALSE);
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(Exceptione){
e.printStackTrace();
}
//初始化窗口
JFrameframe=newJFrame("
聊天"
);
//设置关闭窗体时退出程序
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//初始化一个Controller类,继承了JPanel
Controllercontroller=newController();
//往窗体上加主面板
frame.add(controller);
//设置窗体
frame.setBounds(120,100,controller.getSize().width+20,controller.getSize().height+10);
//设置窗体无法调整大小
frame.setResizable(false);
//设置窗体可见
frame.setVisible(true);
}
Controller.java
packagecn.hnist.controller;
importjava.awt.Color;
importjava.awt.Font;
importjava.awt.TextArea;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.awt.event.KeyAdapter;
importjava.awt.event.KeyEvent;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.io.IOException;
importjava.io.InputStream;
import.DatagramPacket;
import.DatagramSocket;
import.InetAddress;
import.UnknownHostException;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importjava.util.Properties;
importjavax.swing.GroupLayout;
importjavax.swing.JButton;
importjavax.swing.JOptionPane;
importjavax.swing.JScrollPane;
importjavax.swing.JTextArea;
importjavax.swing.LayoutStyle.ComponentPlacement;
publicclassControllerextendsjavax.swing.JPanel{
//消除警告
privatestaticfinallongserialVersionUID=1L;
//接收方主机
privateStringhost;
//接收方端口
privateintsendPort;
//监听本机的端口
privateintmyPort;
//昵称
privateStringnickname;
privateJButtonsendButton;
privateJScrollPanescrollPane;
//滚动条
privateJTextAreasendArea;
privateTextAreashowArea;
privateDatagramSocketds;
//发送和接收数据报包的套接字
privateDatagramPacketreceiveDp;
//接收数据报包
privatebyte[]receiveBuf;
//接收缓冲区
publicController(){
//初始化配置
initConfig();
//初始化显示面板
initComponents();
/*异常处理
*try{
}catch(Exceptione){
**/
//在本机某个端口监听intmyPort,myPort的值从配置文件里读取
ds=newDatagramSocket(myPort);
//初始化byte数组
receiveBuf=newbyte[1024];
//初始化接收的数据报包,缓冲区为receiveBuf
receiveDp=newDatagramPacket(receiveBuf,receiveBuf.length);
}catch(Exceptione){
//后台打印异常信息
//弹出对话框
JOptionPane.showMessageDialog(this,"
或发送主机错误端口冲突"
//抛出运行是异常
thrownewRuntimeException("
配置文件不存在"
//开一个新的线程,监听本机某个端口,用于接收信息收
newThread(newReceiveThread()).start();
privatevoidinitConfig(){
/*配置文件格式
host=localhost
myPort=10000
sendPort=10002
nickname=xudan
*/
Propertiespro=newProperties();
InputStreamin=newFileInputStream("
config.ini"
pro.load(in);
//host=localhost,拿到host的值
host=pro.getProperty("
host"
//由于端口号是int型,将字符串转换成数字
sendPort=Integer.parseInt(pro.getProperty("
sendPort"
));
myPort=Integer.parseInt(pro.getProperty("
myPort"
/*解决昵称为中文的乱码问题
*由于配置文件类型是ANSI,而Java默认码表是ISO8859-1,
所以先用ISO8859-1解码再用gb2312编码成string类型
*/
nickname=newString(pro.getProperty("
nickname"
).getBytes("
ISO8859-1"
),"
gb2312"
//关流
in.close();
}catch(FileNotFoundExceptione){
配置文件不存在,无法启动"
配置文件错误"
privatevoidsend(){
Stringstr=sendArea.getText();
//获得发送区域的文字
if(str==null||"
"
.equals(str))//如果为空则返回
return;
byte[]b=str.getBytes();
DatagramPacketdp=newDatagramPacket(b,b.length,
InetAddress.getByName(host),sendPort);
addMessage(str);
ds.send(dp);
sendArea.setText("
//发送玩清空
}catch(UnknownHostExceptione){
}catch(IOExceptione){
//由于被两个线程访问,所以必须加synchronized关键字修饰为同步方法,保证线程安全
privatesynchronizedvoidaddMessage(Stringmessage){
//获得当前系统时间
Datedate=newDate();
//以hh:
:
mm:
ss格式格式化时间,hh代表时,mm代表分,ss代表秒
SimpleDateFormatsdf=newSimpleDateFormat("
hh:
ss"
Stringtime=sdf.format(date);
//在消息面板上添加消息
showArea.append(nickname+"
"
+time+"
\n"
+message);
//添加换行
showArea.append("
privateclassReceiveThreadimplementsRunnable{
@Override
publicvoidrun(){
Stringstr;
try{
while(true){
ds.receive(receiveDp);
//阻塞式方法,将接收到的信息保存到receiveDp中
str=newString(receiveDp.getData(),0,receiveDp.getLength());
//添加消息方法
addMessage(str);
}
}catch(Exceptione){
e.printStackTrace();
}
//初始话面板,由工具生成
privatevoidinitComponents(){
showArea=newTextArea();
scrollPane=newJScrollPane();
sendArea=newJTextArea();
sendButton=newJButton();
showArea.setBackground(newColor(153,255,204));
showArea.setEditable(false);
showArea.setFont(newFont("
黑体"
1,14));
sendArea.setBackground(newColor(153,153,255));
sendArea.setColumns(20);
sendArea.setFont(newFont("
楷体"
1,18));
sendArea.setRows(3);
//给输入框添加键盘监听
sendArea.addKeyListener(newKeyAdapter(){
@Override
publicvoidkeyPressed(KeyEvente){
//当按下Ctrl+Enter时发送消息
if(e.getKeyChar()==KeyEvent.VK_ENTER){
//发送方法
send();
});
scrollPane.setViewportView(sendArea);
//设置button的内容
sendButton.setText("
发送"
sendButton.addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEventevt){
send();
//设置布局
GroupLayoutlayout=newGroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).
addGroup(GroupLayout.Alignment.TRAILING,layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
.addComponent(showArea,GroupLayout.Alignment.LEADING,
GroupLayout.DEFAULT_SIZE,390,Short.MAX_VALUE)
.addComponent(scrollPane,GroupLayout.DEFAULT_SIZE,390,Short.MAX_VALUE))
.addContainerGap()).addGroup(
GroupLayout.Alignment.TRAILING,layout.createSequentialGroup()
.addContainerGap(325,Short.MAX_VALUE)
.addComponent(sendButton).addGap(20,20,20)));
layout.setVerticalGroup(layout.createParallelGroup(
GroupLayout.Alignment.LEADING).addGroup(
layout.createSequentialGroup()
.addComponent(showArea,GroupLayout.PREFERRED_SIZE,
275,GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(scrollPane,GroupLayout.PREFERRED_SIZE,
91,GroupLayout.PREFERRED_SIZE)
.addGap(14,14,14)
.addComponent(sendButton,GroupLayout.PREFERRED_SIZE,
25,GroupLayout.PREFERRED_SIZE)
.addContainerGap()));
//设置面板大小
this.setSize(500,450);