陕西师范大学网络教育学院
课程名称JAVA程序设计学习中心(点):专层姓批
业次名次
::::
计算机科学与技术专
学校
JAVA聊天室程序设计
目
录
前言..............................................................................................................................................21.需求分析.........................................................................................................................................2
1.1需求分析.................................................................................................................................21.2功能设计.................................................................................................................................32.概要设计.........................................................................................................................................3
2.1程序设计思路.........................................................................................................................32.2程序运行界面.........................................................................................................................42.3流程图.....................................................................................................................................43.各模块的功能及程序说明.............................................................................................................6
3.1系统功能模块.........................................................................................................................6
3.2模块功能说明.........................................................................................................................6
3.2.1聊天室服务器端功能说明..........................................................................................63.2.2聊天室客户端功能说明..............................................................................................7
4.系统测试分析.................................................................................................................................75.源程序清单...................................................................................................................................12
5.1服务器端源程序..........................................................................................................12(1)ChatServer.java:.....................................................................................................12(2)ServerListen.java:......................................................................................................23(3)ServerReceive.java。................................................................................................24(4)PortConf.java。........................................................................................................28(5)Node.java。..............................................................................................................31(6)UserLinkList.java。..................................................................................................31(7)Help.java。...............................................................................................................335.1客户端源程序..............................................................................................................35(1)ChatClient.java。......................................................................................................35(2)ClientReceive.java。................................................................................................46(3)ConnectConf.java。..................................................................................................47(4)UserConf.java。.......................................................................................................51(5)Help.java。...............................................................................................................53
6.课程设计总结...............................................................................................................................55参考文献............................................................................................................................................56
第1页
JAVA聊天程序设计
前
言
Java语言是当今计算机行业最先进,应用最为广泛的一门新兴语言,现在很多的软件公司都在采用Java语言作为专门的开发语言。它所具有的平台无关性,面向对象性等先进性的特点,使它逐步成为越来越重要的一门计算机语言。有人预言:Java将是网络上的\"世界语\",今后所有的用其他语言编写的软件统统都要用Java语言来改写。
Java是由SunMicrosystems公司于1995年5月推出的Java程序设计语言(以下简称Java语言)和Java平台的总称。用Java实现的HotJava浏览器(支持Javaapplet)显示了Java的魅力:跨平台、动感的Web、Internet计算。从此,Java被广泛接受并推动了Web的迅速发展,常用的浏览器现在均支持Javaapplet。另一方面,Java技术也不断更新。
Java平台由Java虚拟机(JavaVirtualMachine)和Java应用编程接口(ApplicationProgrammingInterface、简称API)构成。Java应用编程接口为Java应用提供了一个独立于操作系统的标准接口,可分为基本部分和扩展部分。在硬件或操作系统平台上安装一个Java平台之后,Java应用程序就可运行。现在Java平台已经嵌入了几乎所有的操作系统。这样Java程序可以只编译一次,就可以在各种系统中运行。目前常用的Java平台基于Java1.6。
Java分为三个体系JavaSE(Java2PlatformStandardEdition,java平台标准版),JavaEE(Java2Platform,EnterpriseEdition,java平台企业版),JavaME(Java2PlatformMicroEdition,java平台微型版)。
Java语言是一个支持网络计算的面向对象程序设计语言。Java语言吸收了Smalltalk语言和C++语言的优点,并增加了其它特性,如支持并发程序设计、网络通信、和多媒体数据控制等。
1.需求分析
1.1需求分析
聊天程序是使用Java程序设计语言编写的,要求如下:(1)使用图形用户界面实现。(2)能实现一个聊天室中多人聊天。
第2页
(3)可以两人私聊。
1.2功能设计
根据需求分析可知,本程序要构建的聊天程序其功能应该有服务器端和客户端两个方面:
1、服务器端的主要功能如下:
(1)在特定端口上进行侦听,等待客户端连接
(2)用户可以配置服务端的侦听端口,默认端口为8888.(3)向已经连接到服务端的用户发送系统消息。(4)统计在线人数
(5)当停止服务时,断开所有的用户连接。2、客户端的主要功能如下:
(1)连接到已经开启的聊天服务的服务端。
(2)用户可以配置要连接服务器端的IP地址和端口号。(3)用户可以配置连接后显示的用户名。
(4)当服务器端开启的时候,用户可以随时登录和注销。(5)用户可以向所有人或者某一个人发送消息。
2.概要设计
2.1程序设计思路
1、Java聊天室程序是图形界面、Socket等技术的综合应用。2、图形界面调用java.swing和java.awt包进行图形界面处理和
java.swing.event与java.awt.event事件的侦听处理。
3、套接字通信(Socket)是网络的基本通信单元,又称为端口,通常用来实现客户方和服务方的连接。网络上的两个程序通过双向的连接实现数据的交换,实现双方通信前链路的每一端都建立一个socket,通过对socket的读写操作实现网络的通信功能。
socket通信的过程主要有:创建socket,打开连接到socket的输入流和输出流,按照一定的协议对socket进行读写操作,关闭socket这四个步骤,
第3页
通过这四步可完成一般的socket通信。为了完成socket通信,java.net包中提供了socket和serverSocket这两个类,它们分别用来表示双向连接的客户端和服务器端。
4、聊天室共分为服务器端和客户端两个部分,服务器端程序主要负责侦听客户端发来的消息,客户端需要登录到服务器端才能实现正常的聊天功能。
2.2程序运行界面
1.操作系统:WindowsXP2.开发语言:JAVA3.开发工具:MyEclipse
4.运行界面:服务器端运行界面如图1所示,客户端如图2所示:
图1服务器端运行界面图2客户端运行界面
2.3流程图
第4页
服务器端和客户端的流程图是不同的,分别如图3、图4所示:
开始建立窗口按钮选择启动服务器关闭服务器客户连接结束接受信息保存信息发送信息关闭连接图3服务器端流程图
开始建立窗体客户登录运行线程建立连接和窗体发送信息接受信息关闭连接输出信息结束图4客户端流程图
第5页
3.各模块的功能及程序说明
3.1系统功能模块
1、服务器共有四大模块,分别为:窗体、客户连接、启动与关闭、线程(客户信息处理)。
①窗体:可视化,能了解服务器运行状况,知道客户连接数。②客户连接:为客户建立连接线程。③启动与关闭:控制服务器启动与关闭。
④线程(客户信息处理):接收客户发来的信息,并判断,做相应的处理。2、客户机共有三大模块,分别为:登录、聊天窗口、线程。①登录:为客户输入用户名,及服务器的IP地址。②聊天窗口:可视化窗体,方便客户使用系统。
③线程:处理客户要发送的信息,接收服务器发来的信息!
3.2模块功能说明
3.2.1聊天室服务器端功能说明
聊天室服务端主要包括7个文件,它们的功能如下:
1、ChatServer.java:包含名为ChatServer的public类,其主要功能为定义服务器端的界面,添加事件侦听与事件处理。调用ServerListen类来实现服务端用户上线与下线的侦听,调用ServerReceive类来实现服务器端的消息的收发。
2、ServerListen.java:该类实现服务端用户上线与下线的侦听。该类对用户上线下线的侦听是通过调用用户链表类(UserLinkList)来实现的,当用户上线与下线情况发生变化时,该类会对主类的界面进行相应的修改。
3、ServerReceive.java:该类是实现服务器端的消息的收发的类。该类分别定义了向某用户及所有人发送消息的方法,发送的消息会显示在主界面类的界面上。
4、PortConf.java:该类继承自JDialog,是用户对服务器端侦听端口进行
第6页
修改配置的类。
5、Node.java:用户链表的节点类,定义了链表中的用户。该类与前面所讲的链表节点Node类的功能相当。
6、UserLinkList.java:用户链表节点的具体实现类。该类通过构造函数构造用户链表,定义了添加用户,删除用户、返回用户数、根据用户名查找用户、根据索引查找用户这5个方法。
7、Help.java:服务端程序的帮助类。
3.2.2聊天室客户端功能说明
聊天室客户端主要包括5个文件,它们的功能如下:
1、ChatClient.java:包含名为ChatClient的public类,其主要功能为定义客户端的界面,添加事件侦听与事件处理。该类定义了Connect()与DisConnect()方法实现与服务器的连接与断开连接。当登录到指定的服务器时,调用ClientReceive类实现消息收发,同时该类还定义了SendMessage()方法来向其他用户发送带有表情的消息或者悄悄话。
2、ClientReceive.java:该类是实现服务器端与客户端消息收发的类。3、ConnectConf.java:该类继承自JDialog,是用户对所要连接的服务器IP及侦听端口进行修改配置的类。
4、UserConf.java:该类继承自JDialog,是用户对连接到服务器所显示的用户名进行修改配置的类。
5、Help.java:客户端程序的帮助类。
4.系统测试分析
1、在Myeclipse下运行源程序ChatServer.Java,启动服务器端进行监听:运行情况如图5所示。
2、在Myeclipse下运行源程序ChatClient.Java,客户端登录服务器端,运行情况如图6所示。
第7页
图5服务器端进行监听
3、客户端通信情况如图7所示。
图6客户端连接服务器端
图7客户端通信情况
第8页
4、服务器端实时画面情况如图8所示。
图8服务器端通信情况
第9页
5、服务器端服务。如图9所示。
图9服务器端设置
第10页
6、客户端设置用户和连接。如图10所示。
图10客户端设置
第11页
7、图11显示了服务器程序退出的情况。
图11退出程序
5.源程序清单
5.1服务器端源程序(1)ChatServer.java:
importimportimportimportimportimport
java.awt.*;
java.awt.event.*;javax.swing.*;
javax.swing.event.*;java.net.*;java.io.*;
/*
*聊天服务端的主框架类*/
publicclassChatServerextendsJFrameimplementsActionListener{
第12页
publicstaticintport=8888;//服务端的侦听端口ServerSocketserverSocket;//服务端SocketImageicon;//程序图标
JComboBoxcombobox;//选择发送消息的接受者JTextAreamessageShow;//服务端的信息显示
JScrollPanemessageScrollPane;//信息显示的滚动条JTextFieldshowStatus;//显示用户连接状态JLabelsendToLabel,messageLabel;
JTextFieldsysMessage;//服务端消息的发送
JButtonsysMessageButton;//服务端消息的发送按钮UserLinkListuserLinkList;//用户链表
//建立菜单栏
JMenuBarjMenuBar=newJMenuBar();//建立菜单组
JMenuserviceMenu=newJMenu(\"服务(V)\");//建立菜单项JMenuItemportItem=newJMenuItem(\"端口设置ImageIcon(\"face/98.gif\"));
JMenuItemstartItem=newJMenuItem(\"启动
服务ImageIcon(\"face/icon.gif\"));
JMenuItemstopItem=newJMenuItem(\"停止
服
务
ImageIcon(\"face/Uabrand.gif\"));
JMenuItemexitItem=newJMenuItem(\"
退出
ImageIcon(\"face/messenger_big.gif\"));
JMenuhelpMenu=newJMenu(\"帮助(H)\");JMenuItemhelpItem=newJMenuItem(\"帮助ImageIcon(\"face/HelpCenter.gif\"));
//建立工具栏
JToolBartoolBar=newJToolBar();//建立工具栏中的按钮组件
JButtonportSet;//启动服务端侦听JButtonstartServer;//启动服务端侦听JButtonstopServer;//关闭服务端侦听JButtonexitButton;//退出按钮
//框架的大小
DimensionfaceSize=newDimension(400,600);
第13页
(P)\(S)\(T)\(X)\
(H)\
ServerListenlistenThread;JPaneldownPanel;
GridBagLayoutgirdBag;
GridBagConstraintsgirdBagCon;/**
*服务端构造函数*/
publicChatServer(){
init();//初始化程序
//添加框架的关闭事件处理
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.pack();
//设置框架的大小
this.setSize(faceSize);this.setVisible(true);
//设置运行时窗口的位置
DimensionscreenSize=Toolkit.getDefaultToolkit().getScreenSize();this.setLocation((int)(screenSize.width-faceSize.getWidth())/2,
(int)(screenSize.height-faceSize.getHeight())/2);
this.setResizable(false);
this.setTitle(\"聊天室服务端\");//设置标题//为服务菜单栏设置热键'V'serviceMenu.setMnemonic('V');
//为端口设置快捷键为ctrl+pportItem.setMnemonic('P');portItem.setAccelerator
(KeyEvent.VK_P,InputEvent.CTRL_MASK));//为启动服务快捷键为ctrl+sstartItem.setMnemonic('S');startItem.setAccelerator
(KeyEvent.VK_S,InputEvent.CTRL_MASK));//为端口设置快捷键为ctrl+TstopItem.setMnemonic('T');stopItem.setAccelerator
(KeyEvent.VK_T,InputEvent.CTRL_MASK));
//为退出设置快捷键为ctrl+xexitItem.setMnemonic('X');
(KeyStroke.getKeyStroke
(KeyStroke.getKeyStroke
(KeyStroke.getKeyStroke
第14页
exitItem.setAccelerator
(KeyEvent.VK_X,InputEvent.CTRL_MASK));
//为帮助菜单栏设置热键'H'helpMenu.setMnemonic('H');
//为帮助设置快捷键为ctrl+phelpItem.setMnemonic('H');helpItem.setAccelerator
(KeyEvent.VK_H,InputEvent.CTRL_MASK));
}
/**
*程序初始化函数*/
publicvoidinit(){
ContainercontentPane=getContentPane();contentPane.setLayout(newBorderLayout());
//添加菜单栏
serviceMenu.add(portItem);serviceMenu.add(startItem);serviceMenu.addSeparator();serviceMenu.add(stopItem);serviceMenu.addSeparator();serviceMenu.add(exitItem);jMenuBar.add(serviceMenu);helpMenu.add(helpItem);jMenuBar.add(helpMenu);setJMenuBar(jMenuBar);
//初始化按钮
portSet=newJButton(\"端口设置\");startServer=newJButton(\"启动服务\");stopServer=newJButton(\"停止服务\");exitButton=newJButton(\"退出\");//将按钮添加到工具栏toolBar.add(portSet);
toolBar.addSeparator();//添加分隔栏toolBar.add(startServer);toolBar.add(stopServer);
toolBar.addSeparator();//添加分隔栏
第15页
(KeyStroke.getKeyStroke
(KeyStroke.getKeyStroke
toolBar.add(exitButton);
contentPane.add(toolBar,BorderLayout.NORTH);//初始时,令停止服务按钮不可用stopServer.setEnabled(false);stopItem.setEnabled(false);//为菜单栏添加事件监听
portItem.addActionListener(this);startItem.addActionListener(this);stopItem.addActionListener(this);exitItem.addActionListener(this);helpItem.addActionListener(this);//添加按钮的事件侦听
portSet.addActionListener(this);startServer.addActionListener(this);stopServer.addActionListener(this);exitButton.addActionListener(this);combobox=newJComboBox();
combobox.insertItemAt(\"所有人\combobox.setSelectedIndex(0);
messageShow=newJTextArea();messageShow.setEditable(false);//添加滚动条
messageScrollPane=newJScrollPane(messageShow,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
messageScrollPane.setPreferredSize(newDimension(400,400));messageScrollPane.revalidate();showStatus=newJTextField(35);showStatus.setEditable(false);sysMessage=newJTextField(24);sysMessage.setEnabled(false);sysMessageButton=newJButton();sysMessageButton.setText(\"发送\");//添加系统消息的事件侦听
sysMessage.addActionListener(this);
第16页
sysMessageButton.addActionListener(this);sendToLabel=newJLabel(\"发送至:\");messageLabel=newJLabel(\"发送消息:\");downPanel=newJPanel();
girdBag=newGridBagLayout();downPanel.setLayout(girdBag);
girdBagCon=newGridBagConstraints();girdBagCon.gridx=0;girdBagCon.gridy=0;
girdBagCon.gridwidth=3;girdBagCon.gridheight=2;girdBagCon.ipadx=5;girdBagCon.ipady=5;
JLabelnone=newJLabel(\"\");
girdBag.setConstraints(none,girdBagCon);downPanel.add(none);
girdBagCon=newGridBagConstraints();girdBagCon.gridx=0;girdBagCon.gridy=2;
girdBagCon.insets=newInsets(1,0,0,0);girdBagCon.ipadx=5;girdBagCon.ipady=5;
girdBag.setConstraints(sendToLabel,girdBagCon);downPanel.add(sendToLabel);
girdBagCon=newGridBagConstraints();girdBagCon.gridx=1;girdBagCon.gridy=2;
girdBagCon.anchor=GridBagConstraints.LINE_START;girdBag.setConstraints(combobox,girdBagCon);downPanel.add(combobox);
girdBagCon=newGridBagConstraints();girdBagCon.gridx=0;girdBagCon.gridy=3;
girdBag.setConstraints(messageLabel,girdBagCon);downPanel.add(messageLabel);
girdBagCon=newGridBagConstraints();girdBagCon.gridx=1;
第17页
girdBagCon.gridy=3;
girdBag.setConstraints(sysMessage,girdBagCon);downPanel.add(sysMessage);
girdBagCon=newGridBagConstraints();girdBagCon.gridx=2;girdBagCon.gridy=3;
girdBag.setConstraints(sysMessageButton,girdBagCon);downPanel.add(sysMessageButton);
girdBagCon=newGridBagConstraints();girdBagCon.gridx=0;girdBagCon.gridy=4;
girdBagCon.gridwidth=3;
girdBag.setConstraints(showStatus,girdBagCon);downPanel.add(showStatus);
contentPane.add(messageScrollPane,BorderLayout.CENTER);contentPane.add(downPanel,BorderLayout.SOUTH);//关闭程序时的操作
this.addWindowListener(
newWindowAdapter(){
publicvoidwindowClosing(WindowEvente){
stopService();System.exit(0);}});
}/**
*事件处理*/
publicvoidactionPerformed(ActionEvente){
Objectobj=e.getSource();
if(obj==startServer||obj==startItem){//启动服务端
startService();}
elseif(obj==stopServer||obj==stopItem){//停止服务端
intj=JOptionPane.showConfirmDialog(
this,\"真的停止服务吗?\
JOptionPane.YES_OPTION,JOptionPane.QUESTION_MESSAGE);
第18页
if(j==JOptionPane.YES_OPTION){
stopService();}
}
elseif(obj==portSet||obj==portItem){//端口设置
//调出端口设置的对话框
PortConfportConf=newPortConf(this);portConf.show();}
elseif(obj==exitButton||obj==exitItem){//退出程序
intj=JOptionPane.showConfirmDialog(
this,\"真的要退出吗?\
JOptionPane.YES_OPTION,JOptionPane.QUESTION_MESSAGE);
if(j==JOptionPane.YES_OPTION){
stopService();System.exit(0);}
}
elseif(obj==helpItem){//菜单栏中的帮助
//调出帮助对话框
HelphelpDialog=newHelp(this);helpDialog.show();}
elseif(obj==sysMessage||obj==sysMessageButton){//发送系统消息
sendSystemMessage();}
}/**
*启动服务端*/
publicvoidstartService(){
try{
serverSocket=newServerSocket(port,10);
messageShow.append(\"服务端已经启动,在\"+port+\"端口侦听...\\n\");
startServer.setEnabled(false);startItem.setEnabled(false);portSet.setEnabled(false);portItem.setEnabled(false);stopServer.setEnabled(true);stopItem.setEnabled(true);
第19页
sysMessage.setEnabled(true);}
catch(Exceptione){
//System.out.println(e);}
userLinkList=newUserLinkList();
listenThread=newServerListen(serverSocket,combobox,
messageShow,showStatus,userLinkList);listenThread.start();
}/**
*关闭服务端*/
publicvoidstopService(){
try{
//向所有人发送服务器关闭的消息sendStopToAll();
listenThread.isStop=true;serverSocket.close();
intcount=userLinkList.getCount();inti=0;
while(i node.input.close();node.output.close();node.socket.close();i++; } stopServer.setEnabled(false);stopItem.setEnabled(false);startServer.setEnabled(true);startItem.setEnabled(true);portSet.setEnabled(true);portItem.setEnabled(true);sysMessage.setEnabled(false); messageShow.append(\"服务端已经关闭\\n\");combobox.removeAllItems();combobox.addItem(\"所有人\"); 第20页 } catch(Exceptione){ //System.out.println(e);} }/** *向所有人发送服务器关闭的消息*/ publicvoidsendStopToAll(){ intcount=userLinkList.getCount();inti=0; while(i i++;continue;}try{ node.output.writeObject(\"服务关闭\");node.output.flush();} catch(Exceptione){ //System.out.println(\"$$$\"+e);} i++;} }/** *向所有人发送消息*/ publicvoidsendMsgToAll(Stringmsg){ intcount=userLinkList.getCount();//用户总数inti=0; while(i i++;continue;}try{ node.output.writeObject(\"系统信息\");node.output.flush(); 第21页 node.output.writeObject(msg);node.output.flush(); } catch(Exceptione){ //System.out.println(\"@@@\"+e);}i++; } sysMessage.setText(\"\"); }/** *向客户端用户发送消息*/ publicvoidsendSystemMessage(){ StringtoSomebody=combobox.getSelectedItem().toString();Stringmessage=sysMessage.getText()+\"\\n\";messageShow.append(message);//向所有人发送消息 if(toSomebody.equalsIgnoreCase(\"所有人\")){ sendMsgToAll(message);} else{ //向某个用户发送消息 Nodenode=userLinkList.findUser(toSomebody); try{ node.output.writeObject(\"系统信息\");node.output.flush(); node.output.writeObject(message);node.output.flush();} catch(Exceptione){ //System.out.println(\"!!!\"+e);} sysMessage.setText(\"\");//将发送消息栏的消息清空} } publicstaticvoidmain(String[]args){ ChatServerapp=newChatServer();}} 第22页 (2)ServerListen.java: importjava.awt.*; importjava.awt.event.*;importjavax.swing.*; importjavax.swing.event.*;importjava.io.*;importjava.net.*;/* *服务端的侦听类*/ publicclassServerListenextendsThread{ ServerSocketserver; JComboBoxcombobox;JTextAreatextarea;JTextFieldtextfield; UserLinkListuserLinkList;//用户链表Nodeclient; ServerReceiverecvThread; publicbooleanisStop;/* *聊天服务端的用户上线于下线侦听类*/ publicServerListen(ServerSocketserver,JComboBoxcombobox, JTextAreatextarea,JTextFieldtextfield,UserLinkListuserLinkList){ this.server=server;this.combobox=combobox;this.textarea=textarea;this.textfield=textfield; this.userLinkList=userLinkList;isStop=false; } publicvoidrun(){ while(!isStop&&!server.isClosed()){ try{ client=newNode(); client.socket=server.accept();client.output ObjectOutputStream(client.socket.getOutputStream()); =new 第23页 client.output.flush();client.input= ObjectInputStream(client.socket.getInputStream()); client.username=(String)client.input.readObject(); new //显示提示信息 combobox.addItem(client.username);userLinkList.addUser(client); textarea.append(\"用户\"+client.username+\"上线\"+\"\\n\");textfield.setText(\"在线用户\"+userLinkList.getCount()+\"人 \\n\"); recvThread=newServerReceive(textarea,textfield, combobox,client,userLinkList);recvThread.start();} catch(Exceptione){}}}} (3)ServerReceive.java。 importjavax.swing.*;importjava.io.*;importjava.net.*; /* *服务器收发消息的类*/ publicclassServerReceiveextendsThread{ JTextAreatextarea;JTextFieldtextfield;JComboBoxcombobox;Nodeclient; UserLinkListuserLinkList;//用户链表publicbooleanisStop; publicServerReceive(JTextAreatextarea,JTextFieldtextfield, JComboBoxcombobox,Nodeclient,UserLinkListuserLinkList){this.textarea=textarea;this.textfield=textfield; 第24页 this.client=client; this.userLinkList=userLinkList;this.combobox=combobox;isStop=false; } publicvoidrun(){ //向所有人发送用户的列表sendUserList(); while(!isStop&&!client.socket.isClosed()){ try{ Stringtype=(String)client.input.readObject();if(type.equalsIgnoreCase(\"聊天信息\")){ StringtoSomebody=(String)client.input.readObject();Stringstatus=(String)client.input.readObject();Stringaction=(String)client.input.readObject();Stringmessage=(String)client.input.readObject(); Stringmsg=client.username +\"\"+action+\"对\" +toSomebody+\"说:\"+message+\"\\n\"; if(status.equalsIgnoreCase(\"悄悄话\")){ msg=\"[悄悄话]\"+msg;} textarea.append(msg); if(toSomebody.equalsIgnoreCase(\"所有人\")){ sendToAll(msg);//向所有人发送消息} else{ try{ client.output.writeObject(\"聊天信息\");client.output.flush(); client.output.writeObject(msg);client.output.flush();} catch(Exceptione){ //System.out.println(\"###\"+e); 第25页 人\\n\"); } Nodenode=userLinkList.findUser(toSomebody);if(node!=null){ node.output.writeObject(\"聊天信息\");node.output.flush(); node.output.writeObject(msg);node.output.flush();}} } elseif(type.equalsIgnoreCase(\"用户下线\")){ Nodenode=userLinkList.findUser(client.username);userLinkList.delUser(node); Stringmsg=\"用户\"+client.username+\"下线\\n\";intcount=userLinkList.getCount(); combobox.removeAllItems();combobox.addItem(\"所有人\");inti=0; while(i i++;continue;} combobox.addItem(node.username);i++;} combobox.setSelectedIndex(0);textarea.append(msg); textfield.setText(\"在线用户\"+userLinkList.getCount()+\" sendToAll(msg);//向所有人发送消息 sendUserList();//重新发送用户列表,刷新break;} } catch(Exceptione){ //System.out.println(e); 第26页 }}} /* *向所有人发送消息*/ publicvoidsendToAll(Stringmsg){ intcount=userLinkList.getCount(); inti=0; while(i i++;continue;}try{ node.output.writeObject(\"聊天信息\");node.output.flush(); node.output.writeObject(msg);node.output.flush();} catch(Exceptione){ //System.out.println(e);} i++;} }/* *向所有人发送用户的列表*/ publicvoidsendUserList(){ Stringuserlist=\"\"; intcount=userLinkList.getCount();inti=0; while(i i++;continue;} 第27页 userlist+=node.username;userlist+='\\n';i++; } i=0; while(i i++;continue;}try{ node.output.writeObject(\"用户列表\");node.output.flush(); node.output.writeObject(userlist);node.output.flush();} catch(Exceptione){ //System.out.println(e);}i++;}}} (4)PortConf.java。 importjava.awt.*; importjavax.swing.border.*;importjava.net.*;importjavax.swing.*;importjava.awt.event.*;/** *生成端口设置对话框的类*/ publicclassPortConfextendsJDialog{ JPanelpanelPort=newJPanel();JButtonsave=newJButton();JButtoncancel=newJButton(); publicstaticJLabelDLGINFO=newJLabel( \"默认端口号为:8888\");JPanelpanelSave=newJPanel();JLabelmessage=newJLabel(); 第28页 publicstaticJTextFieldportNumber; publicPortConf(JFrameframe){ super(frame,true);try{ jbInit();} catch(Exceptione){ e.printStackTrace();} //设置运行位置,使对话框居中 DimensionscreenSize=Toolkit.getDefaultToolkit().getScreenSize();this.setLocation((int)(screenSize.width-400)/2+50, (int)(screenSize.height-600)/2+150); this.setResizable(false);} privatevoidjbInit()throwsException{ this.setSize(newDimension(300,120));this.setTitle(\"端口设置\"); message.setText(\"请输入侦听的端口号:\");portNumber=newJTextField(10); portNumber.setText(\"\"+ChatServer.port);save.setText(\"保存\");cancel.setText(\"取消\"); panelPort.setLayout(newFlowLayout());panelPort.add(message);panelPort.add(portNumber);panelSave.add(newLabel(\"panelSave.add(save);panelSave.add(cancel);panelSave.add(newLabel(\" \")); \")); ContainercontentPane=getContentPane();contentPane.setLayout(newBorderLayout()); contentPane.add(panelPort,BorderLayout.NORTH);contentPane.add(DLGINFO,BorderLayout.CENTER);contentPane.add(panelSave,BorderLayout.SOUTH);//保存按钮的事件处理save.addActionListener( newActionListener(){ 第29页 publicvoidactionPerformed(ActionEventa){ intsavePort;try{ savePort=Integer.parseInt(PortConf.portNumber.getText());if(savePort<1||savePort>65535){ PortConf.DLGINFO.setText(\" 口必须是0-65535之间的整数!\"); PortConf.portNumber.setText(\"\");return;} ChatServer.port=savePort;dispose();} catch(NumberFormatExceptione){ PortConf.DLGINFO.setText(\" 号,端口号请填写整数!\"); PortConf.portNumber.setText(\"\");return;}}}); //关闭对话框时的操作this.addWindowListener( newWindowAdapter(){ publicvoidwindowClosing(WindowEvente){ DLGINFO.setText(\" 号为:8888\"); }}); //取消按钮的事件处理 cancel.addActionListener( newActionListener(){ publicvoidactionPerformed(ActionEvente){ DLGINFO.setText(\" 号为:8888\"); dispose();}}); 第30页 侦听端 错误的端口 默认端口 默认端口 }} (5)Node.java。 importjava.net.*;importjava.io.*;/** *用户链表的结点类*/ publicclassNode{ Stringusername=null;Socketsocket=null; ObjectOutputStreamoutput=null;ObjectInputStreaminput=null;Nodenext=null;} (6)UserLinkList.java。 /** *用户链表*/ publicclassUserLinkList{ Noderoot;Nodepointer;intcount;/** *构造用户链表*/ publicUserLinkList(){ root=newNode();root.next=null;pointer=null;count=0;}/** *添加用户*/ publicvoidaddUser(Noden){ pointer=root; while(pointer.next!=null){ pointer=pointer.next; 第31页 } pointer.next=n;n.next=null;count++; }/** *删除用户*/ publicvoiddelUser(Noden){ pointer=root; while(pointer.next!=null){ if(pointer.next==n){ pointer.next=n.next;count--; break; } pointer=pointer.next;} }/** *返回用户数*/ publicintgetCount(){ returncount;}/** *根据用户名查找用户*/ publicNodefindUser(Stringusername){ if(count==0)returnnull;pointer=root; while(pointer.next!=null){ pointer=pointer.next; if(pointer.username.equalsIgnoreCase(username)){ returnpointer;}} returnnull;}/** *根据索引查找用户 第32页 */ publicNodefindUser(intindex){ if(count==0){ returnnull;} if(index<0){ returnnull;} pointer=root;inti=0; while(i pointer=pointer.next;} else{ returnnull;}i++;} returnpointer;}} (7)Help.java。 importjava.awt.*; importjavax.swing.border.*;importjava.net.*;importjavax.swing.*;importjava.awt.event.*;/** *生成设置对话框的类*/ publicclassHelpextendsJDialog{ JPaneltitlePanel=newJPanel();JPanelcontentPanel=newJPanel();JPanelclosePanel=newJPanel();JButtonclose=newJButton(); JLabeltitle=newJLabel(\"聊天室服务端帮助\");JTextAreahelp=newJTextArea();Colorbg=newColor(255,255,255);publicHelp(JFrameframe){ super(frame,true); 第33页 try{ jbInit();} catch(Exceptione){ e.printStackTrace();} //设置运行位置,使对话框居中 DimensionscreenSize=Toolkit.getDefaultToolkit().getScreenSize();this.setLocation((int)(screenSize.width-400)/2, (int)(screenSize.height-320)/2); this.setResizable(false); } privatevoidjbInit()throwsException{ this.setSize(newDimension(400,200));this.setTitle(\"帮助\"); titlePanel.setBackground(bg);;contentPanel.setBackground(bg);closePanel.setBackground(bg); help.setText(\"1、设置服务端的侦听端口(默认端口为8888)。\\n\"+ \"2、点击启动服务按钮便可在指定的端口启动服务。\\n\"+ \"3、选择需要接受消息的用户,在消息栏中写入消息,之后便可发送消息。 \\n\"+ \"4、信息状态栏中显示服务器当前的启动与停止状态、\"+\"用户发送的消息和\\n服务器端发送的系统消息。\");help.setEditable(false);titlePanel.add(newLabel(\"\"));titlePanel.add(title);titlePanel.add(newLabel(\"\"));contentPanel.add(help);closePanel.add(newLabel(\"\"));closePanel.add(close);closePanel.add(newLabel(\"\"));ContainercontentPane=getContentPane();contentPane.setLayout(newBorderLayout()); contentPane.add(titlePanel,BorderLayout.NORTH);contentPane.add(contentPanel,BorderLayout.CENTER);contentPane.add(closePanel,BorderLayout.SOUTH);close.setText(\"关闭\");//事件处理 close.addActionListener( newActionListener(){ publicvoidactionPerformed(ActionEvente){ dispose(); 第34页 }}); }} 5.1客户端源程序(1)ChatClient.java。 //packageClient;importjava.awt.*; importjava.awt.event.*;importjavax.swing.*;importjava.io.*;importjava.net.*;/* *聊天客户端的主框架类*/ publicclassChatClientextendsJFrameimplementsActionListener{ /****/ privatestaticfinallongserialVersionUID=1L;Stringip=\"127.0.0.1\";//连接到服务端的ip地址intport=8888;//连接到服务端的端口号StringuserName=\"匆匆过客\";//用户名inttype=0;//0表示未连接,1表示已连接JComboBoxcombobox;//选择发送消息的接受者JTextAreamessageShow;//客户端的信息显示 JScrollPanemessageScrollPane;//信息显示的滚动条JLabelexpress,sendToLabel,messageLabel;JTextFieldclientMessage;//客户端消息的发送JCheckBoxcheckbox;//悄悄话JComboBoxactionlist;//表情选择 JButtonclientMessageButton;//发送消息JTextFieldshowStatus;//显示用户连接状态Socketsocket; ObjectOutputStreamoutput;//网络套接字输出流ObjectInputStreaminput;//网络套接字输入流ClientReceiverecvThread;//建立菜单栏 JMenuBarjMenuBar=newJMenuBar();//建立菜单组 JMenuoperateMenu=newJMenu(\"操作(O)\"); 第35页 //建立菜单项 JMenuItemloginItem=newJMenuItem(\"用户登录(I)\ ImageIcon(\"face/98.gif\")); JMenuItemlogoffItem=newJMenuItem(\"用户注销(L)\ ImageIcon(\"face/icon.gif\")); JMenuItemexitItem=newJMenuItem(\"退出ImageIcon(\"face/smile.gif\")); JMenuconMenu=newJMenu(\"设置(C)\");JMenuItemuserItem=newJMenuItem(\"用户设置ImageIcon(\"face/messenger_big.gif\")); JMenuItemconnectItem=newJMenuItem(\"连接设置ImageIcon(\"face/Uabrand.gif\")); JMenuhelpMenu=newJMenu(\"帮助(H)\");JMenuItemhelpItem=newJMenuItem(\"帮助 ImageIcon(\"face/HelpCenter.gif\")); //建立工具栏 JToolBartoolBar=newJToolBar();//建立工具栏中的按钮组件 JButtonloginButton;//用户登录JButtonlogoffButton;//用户注销 JButtonuserButton;//用户信息的设置JButtonconnectButton;//连接设置JButtonexitButton;//退出按钮//框架的大小 DimensionfaceSize=newDimension(400,600);JPaneldownPanel; GridBagLayoutgirdBag; GridBagConstraintsgirdBagCon;publicChatClient(){ init();//初始化程序 //添加框架的关闭事件处理 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.pack(); //设置框架的大小 this.setSize(faceSize);this.setVisible(true); setIconImage(getToolkit().getImage(\"face/love.gif\"));//设置运行时窗口的位置DimensionscreenSize Toolkit.getDefaultToolkit().getScreenSize(); 第36页 (X)\ (U)\ (C)\ (H)\ = this.setLocation((int)(screenSize.width-faceSize.getWidth())/ 2, (int)(screenSize.height-faceSize.getHeight()) /2); this.setResizable(false); this.setTitle(\"聊天室客户端\");//设置标题//为操作菜单栏设置热键'V'operateMenu.setMnemonic('O'); //为用户登录设置快捷键为ctrl+iloginItem.setMnemonic('I');loginItem.setAccelerator (KeyEvent.VK_I,InputEvent.CTRL_MASK));//为用户注销快捷键为ctrl+llogoffItem.setMnemonic('L');logoffItem.setAccelerator (KeyEvent.VK_L,InputEvent.CTRL_MASK));//为退出快捷键为ctrl+x exitItem.setMnemonic('X');exitItem.setAccelerator (KeyEvent.VK_X,InputEvent.CTRL_MASK)); //为设置菜单栏设置热键'C'conMenu.setMnemonic('C'); //为用户设置设置快捷键为ctrl+uuserItem.setMnemonic('U');userItem.setAccelerator (KeyEvent.VK_U,InputEvent.CTRL_MASK));//为连接设置设置快捷键为ctrl+cconnectItem.setMnemonic('C');connectItem.setAccelerator (KeyEvent.VK_C,InputEvent.CTRL_MASK)); //为帮助菜单栏设置热键'H'helpMenu.setMnemonic('H');//为帮助设置快捷键为ctrl+phelpItem.setMnemonic('H'); 第37页 (KeyStroke.getKeyStroke (KeyStroke.getKeyStroke (KeyStroke.getKeyStroke (KeyStroke.getKeyStroke (KeyStroke.getKeyStroke helpItem.setAccelerator(KeyStroke.getKeyStroke (KeyEvent.VK_H,InputEvent.CTRL_MASK)); }/** *程序初始化函数*/ publicvoidinit(){ ContainercontentPane=getContentPane();contentPane.setLayout(newBorderLayout()); //添加菜单栏 operateMenu.add(loginItem);operateMenu.add(logoffItem);operateMenu.addSeparator();operateMenu.add(exitItem);jMenuBar.add(operateMenu);conMenu.add(userItem);conMenu.addSeparator();conMenu.add(connectItem);jMenuBar.add(conMenu);helpMenu.add(helpItem);jMenuBar.add(helpMenu);setJMenuBar(jMenuBar); //初始化按钮 loginButton=newJButton(\"登录\");logoffButton=newJButton(\"注销\");userButton=newJButton(\"用户设置\");connectButton=newJButton(\"连接设置\");exitButton=newJButton(\"退出\");//当鼠标放上显示信息 loginButton.setToolTipText(\"连接到指定的服务器\");logoffButton.setToolTipText(\"与服务器断开连接\");userButton.setToolTipText(\"设置用户信息\"); connectButton.setToolTipText(\"设置所要连接到的服务器信息\");//将按钮添加到工具栏 toolBar.add(userButton);toolBar.add(connectButton); toolBar.addSeparator();//添加分隔栏toolBar.add(loginButton);toolBar.add(logoffButton); toolBar.addSeparator();//添加分隔栏toolBar.add(exitButton); 第38页 contentPane.add(toolBar,BorderLayout.NORTH);checkbox=newJCheckBox(\"悄悄话\");checkbox.setSelected(false);actionlist=newJComboBox();actionlist.addItem(\"微笑地\");actionlist.addItem(\"高兴地\");actionlist.addItem(\"轻轻地\");actionlist.addItem(\"生气地\");actionlist.setSelectedIndex(0);//初始时 loginButton.setEnabled(true);logoffButton.setEnabled(false);//为菜单栏添加事件监听 loginItem.addActionListener(this);logoffItem.addActionListener(this);exitItem.addActionListener(this);userItem.addActionListener(this);connectItem.addActionListener(this);helpItem.addActionListener(this);//添加按钮的事件侦听 loginButton.addActionListener(this);logoffButton.addActionListener(this);userButton.addActionListener(this);connectButton.addActionListener(this);exitButton.addActionListener(this);combobox=newJComboBox(); combobox.insertItemAt(\"所有人\combobox.setSelectedIndex(0); messageShow=newJTextArea();messageShow.setEditable(false);//添加滚动条 messageScrollPane=newJScrollPane(messageShow, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); messageScrollPane.setPreferredSize(newDimension(400,400));messageScrollPane.revalidate(); 第39页 clientMessage=newJTextField(23);clientMessage.setEnabled(false);clientMessageButton=newJButton();clientMessageButton.setText(\"发送\");//添加系统消息的事件侦听 clientMessage.addActionListener(this); clientMessageButton.addActionListener(this);sendToLabel=newJLabel(\"发送至:\");express=newJLabel(\"表情:\");messageLabel=newJLabel(\"发送消息:\");downPanel=newJPanel(); girdBag=newGridBagLayout();downPanel.setLayout(girdBag); girdBagCon=newGridBagConstraints();girdBagCon.gridx=0;girdBagCon.gridy=0; girdBagCon.gridwidth=5;girdBagCon.gridheight=2;girdBagCon.ipadx=5;girdBagCon.ipady=5; JLabelnone=newJLabel(\"\"); girdBag.setConstraints(none,girdBagCon);downPanel.add(none); girdBagCon=newGridBagConstraints();girdBagCon.gridx=0;girdBagCon.gridy=2; girdBagCon.insets=newInsets(1,0,0,0);//girdBagCon.ipadx=5;//girdBagCon.ipady=5; girdBag.setConstraints(sendToLabel,girdBagCon);downPanel.add(sendToLabel); girdBagCon=newGridBagConstraints();girdBagCon.gridx=1;girdBagCon.gridy=2; girdBagCon.anchor=GridBagConstraints.LINE_START;girdBag.setConstraints(combobox,girdBagCon);downPanel.add(combobox); 第40页 girdBagCon=newGridBagConstraints();girdBagCon.gridx=2;girdBagCon.gridy=2; girdBagCon.anchor=GridBagConstraints.LINE_END;girdBag.setConstraints(express,girdBagCon);downPanel.add(express); girdBagCon=newGridBagConstraints();girdBagCon.gridx=3;girdBagCon.gridy=2; girdBagCon.anchor=GridBagConstraints.LINE_START;//girdBagCon.insets=newInsets(1,0,0,0);//girdBagCon.ipadx=5;//girdBagCon.ipady=5; girdBag.setConstraints(actionlist,girdBagCon);downPanel.add(actionlist); girdBagCon=newGridBagConstraints();girdBagCon.gridx=4;girdBagCon.gridy=2; girdBagCon.insets=newInsets(1,0,0,0);//girdBagCon.ipadx=5;//girdBagCon.ipady=5; girdBag.setConstraints(checkbox,girdBagCon);downPanel.add(checkbox); girdBagCon=newGridBagConstraints();girdBagCon.gridx=0;girdBagCon.gridy=3; girdBag.setConstraints(messageLabel,girdBagCon);downPanel.add(messageLabel); girdBagCon=newGridBagConstraints();girdBagCon.gridx=1;girdBagCon.gridy=3; girdBagCon.gridwidth=3;girdBagCon.gridheight=1; girdBag.setConstraints(clientMessage,girdBagCon);downPanel.add(clientMessage); girdBagCon=newGridBagConstraints();girdBagCon.gridx=4;girdBagCon.gridy=3; 第41页 girdBag.setConstraints(clientMessageButton,girdBagCon);downPanel.add(clientMessageButton); showStatus=newJTextField(35);showStatus.setEditable(false); girdBagCon=newGridBagConstraints();girdBagCon.gridx=0;girdBagCon.gridy=5; girdBagCon.gridwidth=5; girdBag.setConstraints(showStatus,girdBagCon);downPanel.add(showStatus); contentPane.add(messageScrollPane,BorderLayout.CENTER);contentPane.add(downPanel,BorderLayout.SOUTH);//关闭程序时的操作 this.addWindowListener( newWindowAdapter(){ publicvoidwindowClosing(WindowEvente){ if(type==1){ DisConnect();} System.exit(0);}}); }/** *事件处理*/ publicvoidactionPerformed(ActionEvente){ Objectobj=e.getSource(); if(obj==userItem||obj==userButton){//用户信息设置 //调出用户信息设置对话框 UserConfuserConf=newUserConf(this,userName);userConf.setVisible(true); userName=userConf.userInputName;} elseif(obj==connectItem||obj==connectButton){//连接服务 端设置 //调出连接设置对话框 ConnectConfconConf=newConnectConf(this,ip,port);conConf.setVisible(true);ip=conConf.userInputIp; 第42页 port=conConf.userInputPort; } elseif(obj==loginItem||obj==loginButton){//登录 Connect();} elseif(obj==logoffItem||obj==logoffButton){//注销 DisConnect(); showStatus.setText(\"\");} elseif(obj==clientMessage||obj==clientMessageButton){// 发送消息 SendMessage(); clientMessage.setText(\"\"); } elseif(obj==exitButton||obj==exitItem){//退出 intj=JOptionPane.showConfirmDialog( this,\"真的要退出吗?\ JOptionPane.YES_OPTION,JOptionPane.QUESTION_MESSAGE);if(j==JOptionPane.YES_OPTION){ if(type==1){ DisConnect();} System.exit(0);}} elseif(obj==helpItem){//菜单栏中的帮助 //调出帮助对话框 HelphelpDialog=newHelp(this);helpDialog.setVisible(true);}} publicvoidConnect(){ try{ socket=newSocket(ip,port);} catch(Exceptione){ JOptionPane.showConfirmDialog( this,\"不能连接到指定的服务器。\\n请确认连接设置是否正确。\ 提示\ JOptionPane.DEFAULT_OPTION,JOptionPane.WARNING_MESSAGE);return;} 第43页 try{ output=newObjectOutputStream(socket.getOutputStream());output.flush(); input=newObjectInputStream(socket.getInputStream());output.writeObject(userName);output.flush(); recvThread= ClientReceive(socket,output,input,combobox,messageShow,showStatus); recvThread.start(); new loginButton.setEnabled(false);loginItem.setEnabled(false);userButton.setEnabled(false);userItem.setEnabled(false); connectButton.setEnabled(false);connectItem.setEnabled(false);logoffButton.setEnabled(true);logoffItem.setEnabled(true);clientMessage.setEnabled(true); messageShow.append(\"连接服务器\"+ip+\":\"+port+\"成功...\\n\");type=1;//标志位设为已连接} catch(Exceptione){ System.out.println(e);return;} } publicvoidDisConnect(){ loginButton.setEnabled(true);loginItem.setEnabled(true);userButton.setEnabled(true);userItem.setEnabled(true); connectButton.setEnabled(true);connectItem.setEnabled(true);logoffButton.setEnabled(false);logoffItem.setEnabled(false);clientMessage.setEnabled(false);if(socket.isClosed()){ return;} 第44页 try{ output.writeObject(\"用户下线\");output.flush(); input.close();output.close();socket.close(); messageShow.append(\"已经与服务器断开连接...\\n\");type=0;//标志位设为未连接} catch(Exceptione){ //} } publicvoidSendMessage(){ StringtoSomebody=combobox.getSelectedItem().toString();Stringstatus=\"\"; if(checkbox.isSelected()){ status=\"悄悄话\";} Iconface=newImageIcon(\"face/smile.gif\"); Stringaction=actionlist.getSelectedItem().toString();Stringmessage=clientMessage.getText();if(socket.isClosed()){ return;}try{ output.writeObject(\"聊天信息\");output.flush(); output.writeObject(toSomebody);output.flush(); output.writeObject(action);output.flush(); output.writeObject(action);output.flush(); output.writeObject(message);output.flush();} catch(Exceptione){ // 第45页 } } publicstaticvoidmain(String[]args){ newChatClient();}} (2)ClientReceive.java。 importjavax.swing.*;importjava.io.*;importjava.net.*;/* *聊天客户端消息收发类*/ publicclassClientReceiveextendsThread{ privateJComboBoxcombobox;privateJTextAreatextarea; Socketsocket; ObjectOutputStreamoutput;ObjectInputStreaminput;JTextFieldshowStatus; publicClientReceive(Socketsocket,ObjectOutputStreamoutput, ObjectInputStreaminput,JComboBoxcombobox,JTextArea textarea,JTextFieldshowStatus){ this.socket=socket;this.output=output;this.input=input; this.combobox=combobox;this.textarea=textarea; this.showStatus=showStatus;} publicvoidrun(){ while(!socket.isClosed()){ try{ Stringtype=(String)input.readObject(); 第46页 if(type.equalsIgnoreCase(\"系统信息\")){ Stringsysmsg=(String)input.readObject();textarea.append(\"系统信息:\"+sysmsg);} elseif(type.equalsIgnoreCase(\"服务关闭\")){ output.close();input.close();socket.close(); textarea.append(\"服务器已关闭!\\n\");break; } elseif(type.equalsIgnoreCase(\"聊天信息\")){ Stringmessage=(String)input.readObject();textarea.append(message);} elseif(type.equalsIgnoreCase(\"用户列表\")){ Stringuserlist=(String)input.readObject();Stringusernames[]=userlist.split(\"\\n\");combobox.removeAllItems();inti=0; combobox.addItem(\"所有人\");while(i combobox.setSelectedIndex(0); showStatus.setText(\"在线用户\"+usernames.length+\"人 \"); } } catch(Exceptione){ System.out.println(e);}}}} (3)ConnectConf.java。 第47页 importjava.awt.*;importjava.net.*;importjavax.swing.*;importjava.awt.event.*;/** *生成连接信息输入的对话框 *让用户输入连接服务器的IP和端口*/ publicclassConnectConfextendsJDialog{ /****/ privatestaticfinallongserialVersionUID=1L;JPanelpanelUserConf=newJPanel();JButtonsave=newJButton();JButtoncancel=newJButton();JLabelDLGINFO=newJLabel(\" 127.0.0.1:8888\"); JPanelpanelSave=newJPanel();JLabelmessage=newJLabel();StringuserInputIp;intuserInputPort;JTextFieldinputIp;JTextFieldinputPort; publicConnectConf(JFrameframe,Stringip,intport){ super(frame,true);this.userInputIp=ip; this.userInputPort=port;try{ jbInit();} catch(Exceptione){ e.printStackTrace();} //设置运行位置,使对话框居中DimensionscreenSize Toolkit.getDefaultToolkit().getScreenSize(); this.setLocation((int)(screenSize.width-400)/2+50, 默认连接设置为 = 第48页 (int)(screenSize.height-600)/2+150); this.setResizable(false);} privatevoidjbInit()throwsException{ this.setSize(newDimension(300,130));this.setTitle(\"连接设置\"); message.setText(\"请输入服务器的IP地址:\");inputIp=newJTextField(10);inputIp.setText(userInputIp);inputPort=newJTextField(4); inputPort.setText(\"\"+userInputPort);save.setText(\"保存\");cancel.setText(\"取消\"); panelUserConf.setLayout(newGridLayout(2,2,1,1));panelUserConf.add(message);panelUserConf.add(inputIp); panelUserConf.add(newJLabel(\"请输入服务器的端口号:\"));panelUserConf.add(inputPort);panelSave.add(newLabel(\"\")); panelSave.add(save);panelSave.add(cancel);panelSave.add(newLabel(\" \")); ContainercontentPane=getContentPane();contentPane.setLayout(newBorderLayout()); contentPane.add(panelUserConf,BorderLayout.NORTH);contentPane.add(DLGINFO,BorderLayout.CENTER);contentPane.add(panelSave,BorderLayout.SOUTH); //保存按钮的事件处理save.addActionListener( newActionListener(){ publicvoidactionPerformed(ActionEventa){ intsavePort; //判断端口号是否合法try{ userInputIp=\"\" InetAddress.getByName(inputIp.getText()); userInputIp=userInputIp.substring(1);} 第49页 + catch(UnknownHostExceptione){ DLGINFO.setText( \" IP地址!\"); return; } //userInputIp=inputIP; //判断端口号是否合法try{ savePort=Integer.parseInt(inputPort.getText()); if(savePort<1||savePort>65535){ DLGINFO.setText(\" 是0-65535之间的整数!\"); inputPort.setText(\"\");return; } userInputPort=savePort;dispose(); } catch(NumberFormatExceptione){ DLGINFO.setText(\" 口号请填写整数!\"); inputPort.setText(\"\");return;}}} ); //关闭对话框时的操作this.addWindowListener( newWindowAdapter(){ publicvoidwindowClosing(WindowEvente){ DLGINFO.setText(\"默认连接设置为 127.0.0.1:8888\"); }}); //取消按钮的事件处理 cancel.addActionListener( 错误的 侦听端口必须 错误的端口号,端 第50页 newActionListener(){ publicvoidactionPerformed(ActionEvente){ DLGINFO.setText(\"127.0.0.1:8888\"); dispose();}}); }} (4)UserConf.java。 importjava.awt.*;importjavax.swing.*;importjava.awt.event.*;/** *生成用户信息输入对话框的类*让用户输入自己的用户名*/ publicclassUserConfextendsJDialog{ /****/ privatestaticfinallongserialVersionUID=1L;JPanelpanelUserConf=newJPanel();JButtonsave=newJButton();JButtoncancel=newJButton();JLabelDLGINFO=newJLabel(\" 匆过客\"); JPanelpanelSave=newJPanel();JLabelmessage=newJLabel();StringuserInputName; JTextFielduserName; publicUserConf(JFrameframe,Stringstr){ super(frame,true); this.userInputName=str;try{ jbInit();} catch(Exceptione){ 第51页 默认连接设置为 默认用户名为:匆 e.printStackTrace(); } //设置运行位置,使对话框居中DimensionscreenSize Toolkit.getDefaultToolkit().getScreenSize(); this.setLocation((int)(screenSize.width-400)/2+50, (int)(screenSize.height-600)/2+150); = this.setResizable(false);} privatevoidjbInit()throwsException{ this.setSize(newDimension(300,120));this.setTitle(\"用户设置\"); message.setText(\"请输入用户名:\");userName=newJTextField(10);userName.setText(userInputName);save.setText(\"保存\");cancel.setText(\"取消\"); panelUserConf.setLayout(newFlowLayout());panelUserConf.add(message);panelUserConf.add(userName);panelSave.add(newLabel(\"\")); panelSave.add(save);panelSave.add(cancel);panelSave.add(newLabel(\" \")); ContainercontentPane=getContentPane();contentPane.setLayout(newBorderLayout()); contentPane.add(panelUserConf,BorderLayout.NORTH);contentPane.add(DLGINFO,BorderLayout.CENTER);contentPane.add(panelSave,BorderLayout.SOUTH); //保存按钮的事件处理save.addActionListener( newActionListener(){ publicvoidactionPerformed(ActionEventa){ if(userName.getText().equals(\"\")){ DLGINFO.setText( \"为空!\"); userName.setText(userInputName); 第52页 用户名不能 return; } elseif(userName.getText().length()>15){ DLGINFO.setText(\"不能大于15个字符!\"); userName.setText(userInputName);return; } userInputName=userName.getText();dispose();}}); //关闭对话框时的操作this.addWindowListener( newWindowAdapter(){ publicvoidwindowClosing(WindowEvente){ DLGINFO.setText(\" 为:匆匆过客\"); }});//取消按钮的事件处理 cancel.addActionListener( newActionListener(){ publicvoidactionPerformed(ActionEvente){ DLGINFO.setText(\" 为:匆匆过客\"); dispose();}}); }} (5)Help.java。 importjava.awt.*;importjavax.swing.*;importjava.awt.event.*;/** *生成设置对话框的类 第53页 用户名长度 默认用户名 默认用户名 */ publicclassHelpextendsJDialog{ /****/ privatestaticfinallongserialVersionUID=1L; JPaneltitlePanel=newJPanel();JPanelcontentPanel=newJPanel();JPanelclosePanel=newJPanel(); JButtonclose=newJButton(); JLabeltitle=newJLabel(\"聊天室客户端帮助\");JTextAreahelp=newJTextArea();Colorbg=newColor(255,255,255); publicHelp(JFrameframe){ super(frame,true);try{ jbInit();} catch(Exceptione){ e.printStackTrace();} //设置运行位置,使对话框居中DimensionscreenSize Toolkit.getDefaultToolkit().getScreenSize(); this.setLocation((int)(screenSize.width-400)/2+25, (int)(screenSize.height-320)/2); this.setResizable(false);} privatevoidjbInit()throwsException{ this.setSize(newDimension(350,270));this.setTitle(\"帮助\"); titlePanel.setBackground(bg);;contentPanel.setBackground(bg);closePanel.setBackground(bg); help.setText(\"1、设置所要连接服务端的IP地址和端口\"+ \"(默认设置为\\n127.0.0.1:8888)。\\n\"+ 第54页 = \"2、输入你的用户名(默认设置为:匆匆过客)。\\n\"+\"3、点击“登录”便可以连接到指定的服务器;\\n\"+\"点击“注销”可以和服务器端开连接。\\n\"+ \"4、选择需要接受消息的用户,在消息栏中写入消息,\\n\"+\"同时选择表情,之后便可发送消息。\\n\");help.setEditable(false);titlePanel.add(newLabel(\"titlePanel.add(title);titlePanel.add(newLabel(\"contentPanel.add(help);closePanel.add(newLabel(\"closePanel.add(close);closePanel.add(newLabel(\" \"));\"));\"));\")); ContainercontentPane=getContentPane();contentPane.setLayout(newBorderLayout()); contentPane.add(titlePanel,BorderLayout.NORTH);contentPane.add(contentPanel,BorderLayout.CENTER);contentPane.add(closePanel,BorderLayout.SOUTH);close.setText(\"关闭\");//事件处理 close.addActionListener( newActionListener(){ publicvoidactionPerformed(ActionEvente){ dispose();}});}} 6.课程设计总结 (1)选题目的:本次课程设计为给定设计题目任选两题进行设计。我在记事本程序的设计与实现后,又做了这个聊天室程序。考虑到本学期时间少课程内容多,JAVA课程基础内容掌握并不是很抓实,而对于聊天室程序,由于其功能较复杂,对于我个人而言是个挑战,通过设计这样的一个程序,也能使自己对JAVA的 第55页 一些基础知识掌握的更加牢固。 (2)对于本程序的设计,首先考虑其功能有哪些,需要显示什么,如何进行窗体构建布局,需要用哪些知识点,如相关的类和对象等;其次如何用Socket通信是个较麻烦的问题。最后,就是根据初步设计的功能和布局构架,考虑用源代码进行实现了。 (3)为了完成好这次课程设计,我提前做了较多的准备,一边上网查找相关资料,另一方面查阅相关书籍。经过差不多两个星期的反复编写调试,基本上完成我的Java课程设计—聊天室程序,其中部分内容参考了网上的分析和设计,部分代码来自于网上,自己又改了一部分,期间经过多次分析、查看代码、查看资料,一步一步修改,总结错误经验和修改经验,基本上实现了我在需求分析时所预期的功能。通过这次的课程设计,在把书本上的知识给系统的复习了一下的同时,同时也发现了自己的太多不足,对JAVA语言整体知识构架不够熟悉,不能灵活地运用所学的知识点,自己的编程能力也不是太好,总结自己的一些弯路和应对经验如下: ①一次编写一大串代码后才测试,运行是出现了错误,Myeclipse查找错误语句过多。解决:每编写一定代码后就测试一次。 ②经过多次检查语句,还是有错误出现。可能没有倒入包或定义未初始化(如数组)。 ③客户机没有接收到服务器发送的信息。设计过程中缺少部分代码、客户机或服务器出现异常、设计思路错误。 ④修改客户机、服务器代码很多次,测试还是有问题。先做好服务器(或客户机),再做客户机(或服务器)。防止错误时,即有修改服务器又有修改客户机,容易错乱。 参考文献 [1].孙全党王吴迪赵枫朝,Java程序设计应用教程,电子工业出版社,2006.2[2].雷之宇,Java项目开发实践—网络篇,中国铁道出版社,2005.5 第56页 [3].赵玉阳,Java从入门到精通,清华大学出版社,2006.8[4].李茏怡,Java编程实例讲解,高等教育出版社,2005.11[5].曾令明索出版社,2007.8 望甘 刚 宋 波,Java程序设计教程,西安电子科技大学 第57页 因篇幅问题不能全部显示,请点此查看更多更全内容