1 概述聊天室 2
2. 设计依据 2
2.1 设计平台 2
2.2 设计思想 3
3. 各模块功能简介 3
4. 结构分析 4
5. 界面设计 5
6. 附录源代码 6
1概述聊天室系统
聊天室系统使用JAVA+SQL完成,ECLIPSE完成代码编写,JIGLOO完成界面设计,SQL SERVER完成数据库管理。聊天室通过输入的对方IP,将JTextField中的内容发送到拥有此IP的主机(前提是对方也启动了聊天室程序)。网络的通信使用UDP协议,即时搜寻网络上的短消息,并可恢复对方消息。
数据库的表只有一个User_Info,用户通过用户管理模块登录,注册,修改密码。系统有三个类,MainWin、ChatRoom、jdbcodbc。MainWin是程序的入口类,界面是登陆,注册,修改密码的JFrame窗口。ChatRoom是聊天室的主窗口,负责搜发消息。jdbcodbc负责数据库的连接,有一个构造函数,一个查询方法,一个更新方法,三个返回方法。三个类都放在Com包里,Com包在Chat项目里。
2. 设计依据
本系统要求实现一个两人聊天室的Java 图形用户界面界面程序,主要包括如下功能:
1.主人可以根据输入的IP寻找要聊天的对象。
2.主人和客人之间可以互相发送短消息进行即时聊天。
2.1 设计平台
设计平台是j2se
J2se 是一个开放源代码的 Java 的可扩展开发平台。编写代码和运行软件都很方便。编写过程中要是有错误就有提示,非常方便用户修改代码。
2.2 设计思想
程序分为三个部分:数据库连接,聊天室管理,用户管理。其中用户管理分为用户注册,用户登录,用户修改密码。
3. 各模块功能简介
程序功能模块图
4. 结构分析
主窗口对象
MainWin()方法:构造函数,调用initGUI()方法以及父类JFRAME的构造函数。
main()方法:程序的入口。
initGUI()方法:加载窗口的各个组件以及事件处理。
数据库连接对象
jdbcodbc():构造函数,加载数据库驱动,建立数据库连接。
CheckInfo():将查询语句得到的数据库内容赋给数据集。
UpdateInfo():用插入语句使数据库更新。
聊天室对象
ChatRoom():构造函数,调用initGUI()方法以及父类JFRAME的构造函数。并用循环实现实时接受数据包里的消息。
initGUI():加载窗口的各个组件以及事件处理。
5.界面设计
用户界面的设计是整个系统设计中比较关键的一环。通过用户界面能更清晰的显示出本系统所具有的功能、简单的错误警告及处理能力。用户界面的友好设计,可以使操作人员更迅速的掌握其操作步骤,便于操作。
客户端窗口
聊天室界面设计
内嵌“私聊”窗口
实验总结
由于能力及时间的关系,这个Java聊天室程序没能达到其要求,很有点失望,很有点遗憾。在建立通信和连接数据库时,虽然很认真地在做,可总还是失败,这也导致了整个聊天室的无法运作(只有界面而已)。事实如此,不再赘言了。
这次Java实习,似乎量上过大,然而坚持做下来,还有很有意义和收获的。也许我的所得,对他人而言,可谓不值一提,但对我来说,它们的确让我在思想和能力上,更上了一层楼。下面我就谈谈我的体会:
Jave与C语言编程相比,有着本质的不同.前者面向对象,即面向问题而设计程序,后者则是分析问题后,面向问题解决的过程而设计程序.本质的不同,导致程序设计的明显差异.Java设计的程序,通过划分类,通常都显得通俗易懂,条理清晰,而且很简捷.这是C语言所无法比拟的,除非它有很好的数据结构,但必须承认,就算如此,还是难以与之平行的.用Jave编聊天室,其实也不是那么复杂,但要是换用C语言,我真不知道其工作量有多大了。由此,我看到了Java的优越性,更坚定了我学好Java的决心.
用Java解决实际问题,分析问题是至关重要的。分析要合理、全面,只有这样,划分的类就不至于过大或过小。一个复杂的问题,就象这个聊天室吧,一开始不是什么都会做,先就完成简单、容易的,然后再带着小有的成就感,去征服难弄的部分。这种思想是处处适用的。
想说的,我已经说完了。最后再说一句:虽然目前我的编程能力很差劲,可我心中已有了目标,也许我走不到终点,但我一定会前进,绝不轻易放弃!梦想来之不易!
6. 附录源代码
程序主界面设计
建立服务端窗口类:窗口程序如下
import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.List;
import java.awt.TextArea;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
public class chatroomW {
JFrame f=new JFrame("局域网聊天室");
JLabel label1=new JLabel("端口");
JLabel label2=new JLabel("发送");
Button button1=new Button("启动服务");
Button button2=new Button("发送");
Button button3=new Button("刷新用户列表");
JTextField text1=new JTextField(5);
JTextField text2=new JTextField(25);
TextArea area1=new TextArea(26,84);
List userList=new List(27);
JScrollPane scro1,scro2;
public chatroomW(){
chat();
}
public void chat(){
area1.setBackground(new Color(204,255,255));
area1.setForeground(Color.black);
userList.setBackground(Color.gray);
userList.setForeground(Color.white);
f.setLayout(new FlowLayout());
f.add(area1);
f.add(userList);
f.add(label1);
f.add(text1);
f.add(button1);
f.add(text2);
f.add(button2);
f.add(button3);
f.setBounds(300,200,750,485);
f.setResizable(false);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
area1.setEditable(false);
text1.setText("10000");
myEvent();
}
public static void main(String args[]){
new chatroomW();
}
public void myEvent(){}
}
建立客户端窗口
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.TextArea;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
public class ClientW {
JFrame f=new JFrame("聊天室");
JScrollPane js;
TextArea area=new TextArea(19,67);
JTextField text1=new JTextField(12);
JTextField text2=new JTextField(5);
JTextField text3=new JTextField(5);
JTextField text4=new JTextField(20);
JButton button1=new JButton("连接");
JButton button2=new JButton("发送");
JButton button3=new JButton("私聊");
JLabel label1=new JLabel("服务器地址");
JLabel label2=new JLabel("服务器端口");
JLabel label3=new JLabel("昵称");
public ClientW(){
chat();
}
public void chat(){
area.setBackground(new Color(204,255,255));
// area.setForeground(Color.black);
f.setLayout(new FlowLayout());
f.setBounds(300,200,500,410);
f.add(label1);
f.add(text1);
f.add(label2);
f.add(text2);
f.add(button1);
f.add(area);
f.add(label3);
f.add(text3);
f.add(text4);
f.add(button2);
f.add(button3);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
area.setEditable(false);
text2.setText("10000");
text4.setText(null);
myEvent();
}
public void myEvent(){}
public static void main(String args[]){
new ClientW();
}
}
class netchat{
JFrame f=new JFrame("私聊");
JLabel label1,label2,label3;
Button button1,button2;
JTextField text1,text2,text3,text4;
TextArea textarea;
public netchat(){
f.setLayout(new FlowLayout());
f.setBounds(300,200,400,310); //设置窗口大小和位置;
f.setResizable(false); //让窗口大小固定;
label1=new JLabel("对方主机");
label2=new JLabel("本地端口");
label3=new JLabel("对方端口");
button1=new Button("连接");
button2=new Button("发送");
text1=new JTextField(7);
text2=new JTextField(3);
text3=new JTextField(3);
text4=new JTextField(20);
textarea=new TextArea(13,53);
textarea.setEditable(false);
textarea.setBackground(new Color(204,250,255));
f.add(label1);
f.add(text1);
f.add(label2);
f.add(text2);
f.add(label3);
f.add(text3);
f.add(button1);
f.add(textarea);
f.add(text4);
f.add(button2);
f.setVisible(true);
// f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);//关闭窗口程序同时关闭;
myEvent();
}
客服端类继承客户端窗口类,并内嵌私聊程序
import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class Client extends ClientW{
Socket s=null;
public Client(){}
public void myEvent(){
button1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
try{
s=new Socket(text1.getText().toString(),Integer.parseInt(text2.getText()));
new Thread(new LinkC()).start();
area.append("[系统消息]:连接成功\\n");
}catch(Exception ex){area.append("[系统消息]:连接失败\\n");}
}
});
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
new SentC();
}
});
button3.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
new netchat();
}
});
}
public static void main(String args[]){
new Client();
}
class LinkC implements Runnable{
public void run(){
try{
BufferedReader bufIn=
new BufferedReader(new InputStreamReader(s.getInputStream()));
String msg=null;
PrintStream ps=new PrintStream(s.getOutputStream());
ps.println(text3.getText());
while(true){
try{
while((msg=bufIn.readLine())!=null){
area.append(msg+"\\n");
}
}catch(Exception ex){break;}
}
}catch(Exception e){}
}
}
class SentC {
public SentC(){
try{
PrintStream ps=new PrintStream(s.getOutputStream());
if(!text4.getText().equals("")){
ps.println(text4.getText());
// area.append(text4.getText()); //服务器自动会返回
text4.setText("");
}
}catch(Exception e){}
}
}
//私聊类
class netchat{
JFrame f=new JFrame("私聊");
JLabel label1,label2,label3;
Button button1,button2;
JTextField text1,text2,text3,text4;
TextArea textarea;
public netchat(){
f.setLayout(new FlowLayout());
f.setBounds(300,200,400,310); //设置窗口大小和位置;
f.setResizable(false); //让窗口大小固定;
label1=new JLabel("对方主机");
label2=new JLabel("本地端口");
label3=new JLabel("对方端口");
button1=new Button("连接");
button2=new Button("发送");
text1=new JTextField(7);
text2=new JTextField(3);
text3=new JTextField(3);
text4=new JTextField(20);
textarea=new TextArea(13,53);
textarea.setEditable(false);
textarea.setBackground(new Color(204,250,255));
text2.setText("10000");
text3.setText("10000");
f.add(label1);
f.add(text1);
f.add(label2);
f.add(text2);
f.add(label3);
f.add(text3);
f.add(button1);
f.add(textarea);
f.add(text4);
f.add(button2);
f.setVisible(true);
// f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);//关闭窗口程序同时关闭;
myEvent();
}
public void myEvent(){
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e){
try{
DatagramSocket ds=new DatagramSocket();
byte[] buf="对方已下线".getBytes();
DatagramPacket dp=
new DatagramPacket(buf,buf.length,InetAddress.getByName(text1.getText()),Integer.parseInt(text3.getText()));
ds.send(dp);
ds.close();
}catch(Exception ex){}
}
});
button2.addActionListener(new ActionListener()//事件源是button2
{
public void actionPerformed(ActionEvent e)
{
if(!text4.getText().equals(""))
new Thread(new Send()).start();
}
});
button1.addActionListener(new ActionListener()//事件源是button1
{
public void actionPerformed(ActionEvent e)
{
new Thread(new Rece()).start();
}
});
}
class Send implements Runnable{
public void run(){ try{UdpSend();}catch(Exception e){textarea.append("[系统消息]:发送失败\\n");}}
public void UdpSend()throws Exception{
DatagramSocket ds=new DatagramSocket();
byte[] buf=text4.getText().getBytes();
DatagramPacket dp=
new DatagramPacket(buf,buf.length,InetAddress.getByName(text1.getText()),Integer.parseInt(text3.getText()));
textarea.append("[我]: "+text4.getText()+"\\n");
text4.setText("");
ds.send(dp);
ds.close();
}
}
class Rece implements Runnable{
int index=0;
public void run(){
try{
UdpRece();
}catch(Exception e){
textarea.append("[系统消息]:连接失败\\n");
}
}
public void UdpRece()throws Exception{
while(true){
DatagramSocket ds=new DatagramSocket(Integer.parseInt(text2.getText()));
if(index==0){textarea.append("[系统消息]:连接成功\\n");}
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,buf.length);
ds.receive(dp);
String data=new String(dp.getData(),0,dp.getLength());
textarea.append(dp.getAddress()+" "+data+"\\n");
index++;
ds.close();
}
}
}
}
}
参考文献
[1] 耿祥义,Java2 实用教程,清华大学出版社,2008
[2] 辛运帏 .Java程序设计.北京:清华大学出版社, 2004
[3] 许文宪 懂子建. Java程序设计教程与实训. 北京:北京大学出版社,2005.