java最新版聊天室软件,初学项目者必备!!!
周末写的,私聊,群聊功能基本达到要求,就是服务器端的扩展功能还没优化,时间太急了,实在没心情,希望哪位大神看到后帮我改进。
聊天室服务端主要包括8个文件,它们的功能如下:
(1)ChatServer.java:包含名为ChatServer的public类,其主要功能为定义服务器端的界面,添加事件侦听与事件处理。调用ServerListen类来实现服务端用户上线与下线的侦听,调用ServerReceive类来实现服务器端的消息的收发。
(2)ServerListen.java:该类实现服务端用户上线与下线的侦听。该类对用户上线下线的侦听是通过调用用户链表类(UserLinkList)来实现的,当用户上线与下线情况发生变化时,该类会对主类的界面进行相应的修改。
(3)ServerReceive.java:该类是实现服务器端的消息的收发的类。该类分别定义了向某用户及所有人发送消息的方法,发送的消息会显示在主界面类的界面上。
(4)PortConf.java:该类继承自JDialog,是用户对服务器端侦听端口进行修改配置的类。
(5)Node.java:用户链表的节点类,定义了链表中的用户。该类与前面所讲的链表节点Node类的功能相当。
(6)UserLinkList.java:用户链表节点的具体实现类。该类通过构造函数构造用户链表,定义了添加用户,删除用户、返回用户数、根据用户名查找用户、根据索引查找用户这5个方法。
(7)Help.java:服务端程序的帮助类。
(8)Message.java:对消息进行封装
---------------------------------ChatServer.java-----------------------------
package com.canlong.server;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.ServerSocket;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class ChatServer extends JFrame implements ActionListener {
public static int port = 8888;
private ServerSocket serverSocket;
private UserLinkList userLinkList;
private ServerListen listenThread;
private JComboBox combobox;
private JTextArea messageShow;
private JTextField showStatus;
private JButton startServer;
private JMenuItem startItem;
private JButton stopServer;
private JMenuItem stopItem;
private JButton portSet;
private JMenuItem portItem;
private JButton exitButton;
private JMenuItem exitItem;
private JMenuItem helpItem;
private JButton sysMessage;
private JButton sysMessageButton;
private JPanel leftPane;
private JPanel rightPane;
private JLabel label5; //标示发布消息的状态
private JButton send; //发送按钮
private JTextArea text1; //发送内容
private JLabel label2; //服务器状态
public ChatServer (){
this.setJMenuBar(createMenuBar());
GridBagLayout gbly = new GridBagLayout();
GridBagLayout gblyLeft = new GridBagLayout();
GridBagLayout gblyRight = new GridBagLayout();
this.setLayout(gbly);
GridBagConstraints gc1 = new GridBagConstraints();
GridBagConstraints gc2 = new GridBagConstraints();
gc1.gridwidth = 88;
gc1.gridheight = 1;
gc1.weightx = 0;
gc1.weighty = 1;
gc1.fill = GridBagConstraints.BOTH;
gc2.gridwidth = 2;
gc2.gridheight = 1;
gc2.weightx = 0.7;
gc2.weighty = 1;
gc2.fill = GridBagConstraints.BOTH;
leftPane = new JPanel();
leftPane.setLayout(gblyLeft);
leftPane.setBackground(Color.RED);
leftPane.setOpaque(true);
//leftPane.setSize(200, 480);
rightPane = new JPanel();
rightPane.setLayout(gblyRight);
rightPane.setBackground(Color.BLUE);
rightPane.setOpaque(true);
gbly.setConstraints(leftPane, gc1);
gbly.setConstraints(rightPane, gc2);
this.add(leftPane);
this.add(rightPane);
gc1.fill = GridBagConstraints.NONE;
//gc1.weightx = 0.2;
//gc1.weighty = 0.3;
gc1.gridwidth = 5;
gc1.gridheight = 3;
//gc1.weighty = 2.0;
//左面板
gc1.gridwidth = GridBagConstraints.REMAINDER;
JLabel lb1=new JLabel(" 服务列表 ");
lb1.setFont(new Font("宋体", 1, 22));
gblyLeft.setConstraints(lb1, gc1);
leftPane.add(lb1);
startServer = new JButton("启动服务");
startServer.setFont(new Font("宋体", 0, 18));
gblyLeft.setConstraints(startServer, gc1);
leftPane.add(startServer);
stopServer = new JButton("停止服务");
stopServer.setFont(new Font("宋体", 0, 18));
gblyLeft.setConstraints(stopServer, gc1);
leftPane.add(stopServer);
portSet = new JButton("端口设置");
portSet.setFont(new Font("宋体", 0, 18));
gblyLeft.setConstraints(portSet, gc1);
leftPane.add(portSet);
exitButton = new JButton("关闭退出");
exitButton.setFont(new Font("宋体", 0, 18));
gblyLeft.setConstraints(exitButton, gc1);
leftPane.add(exitButton);
startServer.addActionListener(this);
stopServer.addActionListener(this);
portSet.addActionListener(this);
exitButton.addActionListener(this);
//右面板
gc2.gridwidth = GridBagConstraints.REMAINDER;
JLabel label = new JLabel(" 服务状态:");
label.setFont(new Font("宋体", 1, 22));
gc2.weightx = 1;
gc2.weighty = 0;
gblyRight.setConstraints(label, gc2);
rightPane.add(label);
label2 = new JLabel(" 已停止");
label2.setFont(new Font("宋体", 1, 22));
gc2.weightx = 1;
gc2.weighty = 0;
gblyRight.setConstraints(label2, gc2);
rightPane.add(label2);
JLabel label3 = new JLabel(" ");
label3.setFont(new Font("宋体", 1, 22));
gc2.weightx = 1;
gc2.weighty = 0;
gblyRight.setConstraints(label3, gc2);
rightPane.add(label3);
label5 = new JLabel(" ");
label5.setFont(new Font("宋体", 1, 14));
gc2.fill = GridBagConstraints.NONE;
gc2.weightx = 1;
gc2.weighty = 0;
gblyRight.setConstraints(label5, gc2);
rightPane.add(label5);
JLabel label4 = new JLabel("发布消息");
label4.setFont(new Font("宋体", 1, 14));
label4.setBackground(Color.CYAN);
label4.setOpaque(true);
gc2.fill = GridBagConstraints.BOTH;
gc2.weightx = 1;
gc2.weighty = 0;
gblyRight.setConstraints(label4, gc2);
rightPane.add(label4);
text1 = new JTextArea("");
//JScrollPane js = new JScrollPane(text1);
gc2.weightx = 1;
gc2.weighty = 0.8;
gblyRight.setConstraints(text1, gc2);
rightPane.add(text1);
send = new JButton("发送");
send.addActionListener(this);
send.setFont(new Font("宋体", 1, 18));
gc2.fill = GridBagConstraints.NONE;
gc2.anchor = GridBagConstraints.EAST;
gc2.weightx = 0.2;
gc2.weighty = 0;
gblyRight.setConstraints(send, gc2);
rightPane.add(send);
JPanel right2 = new JPanel();
GridBagLayout gblyRight2 = new GridBagLayout();
right2.setLayout(gblyRight2);
GridBagConstraints gc3 = new GridBagConstraints();
gc3.weightx = 1;
gc3.weighty = 0;
gc3.gridwidth = 2;
gc3.gridheight = 1;
gc3.gridwidth = GridBagConstraints.REMAINDER;
gc3.fill = GridBagConstraints.BOTH;
JLabel ha = new JLabel(" 用户状态 ");
ha.setFont(new Font("宋体", 1, 22));
gblyRight2.setConstraints(ha, gc3);
right2.add(ha);
combobox = new JComboBox();
gc3.weightx = 1;
gc3.weighty = 0.8;
gblyRight2.setConstraints(combobox, gc3);
right2.add(combobox);
messageShow = new JTextArea("无消息");
gblyRight2.setConstraints(messageShow, gc3);
right2.add(messageShow);
showStatus = new JTextField("在线人数0人");
showStatus.setFont(new Font("宋体", 1, 22));
gblyRight2.setConstraints(showStatus, gc3);
right2.add(showStatus);
gbly.setConstraints(right2, gc1);
this.add(right2);
stopServer.setEnabled(false);
stopItem.setEnabled(false);
send.setEnabled(false);
this.setBounds(200, 100, 600, 480);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
String obj = e.getActionCommand();
if (obj == startServer.getText() || obj == startItem.getText()) { // 启动服务端
startService();
} else if (obj == stopServer.getText() || obj == stopItem.getText()) { // 停止服务端
int j = JOptionPane.showConfirmDialog(this, "真的停止服务吗?", "停止服务",
JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE);
if (j == JOptionPane.YES_OPTION) {
stopService();
}
} else if (obj == portSet.getText() || obj == portItem.getText()) { // 端口设置
// 调出端口设置的对话框
PortConf portConf = new PortConf(this);
portConf.setVisible(true);
} else if (obj == exitButton.getText() || obj == exitItem.getText()) { // 退出程序
int j = JOptionPane.showConfirmDialog(this, "真的要退出吗?", "退出",
JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE);
if (j == JOptionPane.YES_OPTION) {
stopService();
System.exit(0);
}
} else if (obj == helpItem.getText()) { // 菜单栏中的帮助
// 调出帮助对话框
Help helpDialog = new Help(this);
helpDialog.setVisible(true);
} else if (obj == sysMessage.getText() || obj == send.getText()) { // 发送系统消息
sendSystemMessage();
}
}
public void startService() {
try {
serverSocket = new ServerSocket(port, 10);
//messageShow.append("服务端已经启动,在" + port + "端口侦听...\n");
label2.setText("正在运行...");
startServer.setEnabled(false);
startItem.setEnabled(false);
portSet.setEnabled(false);
portItem.setEnabled(false);
stopServer.setEnabled(true);
stopItem.setEnabled(true);
send.setEnabled(true);
} catch (Exception e) {
// System.out.println(e);
}
userLinkList = new UserLinkList();
listenThread = new ServerListen(serverSocket, combobox, messageShow,
showStatus, userLinkList);
listenThread.start();
}
public void stopService() {
try {
// 向所有人发送服务器关闭的消息
sendStopToAll();
listenThread.isStop = true;
serverSocket.close();
int count = userLinkList.getCount();
int i = 0;
while (i < count) {
Node node = userLinkList.findUser(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);
send.setEnabled(false);
messageShow.append("服务端已经关闭\n");
showStatus.setText("在线人数0人");
combobox.removeAllItems();
combobox.addItem("所有人");
} catch (Exception e) {
// System.out.println(e);
}
}
public void sendStopToAll() {
int count = userLinkList.getCount();
int i = 0;
while (i < count) {
Node node = userLinkList.findUser(i);
if (node == null) {
i++;
continue;
}
try {
node.output.println("服务关闭");
node.output.flush();
} catch (Exception e) {
// System.out.println("$$$"+e);
}
i++;
}
}
public void sendMsgToAll(String msg) {
int count = userLinkList.getCount();// 用户总数
int i = 0;
while (i < count) {
Node node = userLinkList.findUser(i);
if (node == null) {
i++;
continue;
}
try {
//node.output.println("系统信息");
//node.output.flush();
node.output.println("系统信息:"+msg);
node.output.flush();
} catch (Exception e) {
// System.out.println("@@@"+e);
}
i++;
}
sysMessage.setText("");
}
public void sendSystemMessage() {
String toSomebody = combobox.getSelectedItem().toString();
String message = sysMessage.getText() + "\n";
messageShow.append(message);
// 向所有人发送消息
if (toSomebody.equalsIgnoreCase("所有人")) {
sendMsgToAll(message);
} else {
// 向某个用户发送消息
Node node = userLinkList.findUser(toSomebody);
try {
node.output.println("系统信息:"+message);
node.output.flush();
} catch (Exception e) {
// System.out.println("!!!"+e);
}
sysMessage.setText("");// 将发送消息栏的消息清空
}
}
private JMenuBar createMenuBar(){
JMenu[] m = {new JMenu("开始(B)"),new JMenu("关于(A)")}; //创建两个菜单
JMenuBar mBar = new JMenuBar(); //创建一个菜单栏对象
//this.setJMenuBar(mBar);
mBar.add(m[0]); //为菜单栏添加第一个菜单
mBar.add(m[1]); //为菜单栏添加第二个菜单
m[0].setMnemonic('B'); //设置快捷键
m[1].setMnemonic('A'); //设置快捷键
initMenuBegin(m); //初始化“开始”菜单
initMenuAbout(m); //初始化“关于”菜单
return mBar; //返回创建的菜单栏
}
private void initMenuBegin(JMenu[] m){
startItem = new JMenuItem("启动服务");
stopItem = new JMenuItem("停止服务");
portItem = new JMenuItem("端口设置");
exitItem = new JMenuItem("退出");
JMenuItem [] mI = {startItem,stopItem,portItem,exitItem};
mI[0].addActionListener(this);
mI[1].addActionListener(this);
mI[2].addActionListener(this);
mI[3].addActionListener(this);
m[0].add(mI[0]);
m[0].add(mI[1]);
m[0].add(mI[2]);
m[0].add(mI[3]);
m[0].insertSeparator(1); //插入分隔线
}
private void initMenuAbout(JMenu[] m){
helpItem = new JMenuItem("帮助");
JMenuItem [] mI = {helpItem,new JMenuItem("关于作者(A)")};
mI[0].setMnemonic('H');
mI[1].setMnemonic('A');
mI[0].setAccelerator(KeyStroke.getKeyStroke("F1"));
mI[0].addActionListener(this);
mI[1].addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){//当单击“关于作者”菜单时
String version = "版本: 1.0\n";
String author = "作者: 你青春还有多久\n";
String email = "E-mail: 1164191183@qq.com";
JOptionPane.showMessageDialog(null, version + author + email);
}
}
);
m[1].add(mI[0]);
m[1].add(mI[1]);
}
public static void main(String[] args) {
new ChatServer();
}
}
---------------------------------
Help.java-----------------------------
package com.canlong.server;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Label;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class Help extends JDialog {
JPanel titlePanel = new JPanel();
JPanel contentPanel = new JPanel();
JPanel closePanel = new JPanel();
JButton close = new JButton();
JLabel title = new JLabel("聊天室服务端帮助");
JTextArea help = new JTextArea();
Color bg = new Color(255,255,255);
public Help(JFrame frame) {
super(frame, true);
try {
jbInit();
}
catch (Exception e) {
e.printStackTrace();
}
//设置运行位置,使对话框居中
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation( (int) (screenSize.width - 400) / 2,
(int) (screenSize.height - 320) / 2);
this.setResizable(false);
}
private void jbInit() throws Exception {
this.setSize(new Dimension(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(new Label(" "));
titlePanel.add(title);
titlePanel.add(new Label(" "));
contentPanel.add(help);
closePanel.add(new Label(" "));
closePanel.add(close);
closePanel.add(new Label(" "));
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(titlePanel, BorderLayout.NORTH);
contentPane.add(contentPanel, BorderLayout.CENTER);
contentPane.add(closePanel, BorderLayout.SOUTH);
close.setText("关闭");
//事件处理
close.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
}
}
---------------------------------
Message.java-----------------------------
package com.canlong.server;
public class Message {
private String type; //保存信息的类型,分号之前的部分
private String body; //保存信息的具体内容,分号之后的部分
private boolean valid; //信息是否有效,也就是信息是否含有:
public Message(String messageLine){
valid=false;
type=body=null;
int pos=messageLine.indexOf(":");
if(pos>=0){
type=messageLine.substring(0,pos).toUpperCase();//分号之前的字符串
body=messageLine.substring(pos+1);//分号之后的字符串
valid=true; //信息有效
}else{
type=messageLine;
}
}
public Message(String type,String body){
valid=true;
this.type=type;
this.body=body;
}
public String getType(){
return type;
}
public String getBody(){
return body;
}
public boolean isValid(){
return valid;
}
}
---------------------------------
Node.java-----------------------------
package com.canlong.server;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Node {
String username = null;
Socket socket = null;
PrintWriter output = null;
BufferedReader input = null;
Node next = null;
}
---------------------------------
PortConf.java-----------------------------
package com.canlong.server;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class PortConf extends JDialog {
JPanel panelPort = new JPanel();
JButton save = new JButton();
JButton cancel = new JButton();
public static JLabel DLGINFO=new JLabel("默认端口号为:8888");
JPanel panelSave = new JPanel();
JLabel message = new JLabel();
public static JTextField portNumber ;
public PortConf(JFrame frame) {
super(frame, true);
try {
jbInit();
}
catch (Exception e) {
e.printStackTrace();
}
//设置运行位置,使对话框居中
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation( (int) (screenSize.width - 400) / 2 + 50,
(int) (screenSize.height - 600) / 2 + 150);
this.setResizable(false);
}
private void jbInit() throws Exception {
this.setSize(new Dimension(300, 120));
this.setTitle("端口设置");
message.setText("请输入侦听的端口号:");
portNumber = new JTextField(10);
portNumber.setText(""+ChatServer.port);
save.setText("保存");
cancel.setText("取消");
panelPort.setLayout(new FlowLayout());
panelPort.add(message);
panelPort.add(portNumber);
panelSave.add(new Label(" "));
panelSave.add(save);
panelSave.add(cancel);
panelSave.add(new Label(" "));
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(panelPort, BorderLayout.NORTH);
contentPane.add(DLGINFO, BorderLayout.CENTER);
contentPane.add(panelSave, BorderLayout.SOUTH);
//保存按钮的事件处理
save.addActionListener(
new ActionListener() {
public void actionPerformed (ActionEvent a) {
int savePort;
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(NumberFormatException e){
PortConf.DLGINFO.setText(" 错误的端口号,端口号请填写整数!");
PortConf.portNumber.setText("");
return;
}
}
}
);
//关闭对话框时的操作
this.addWindowListener(
new WindowAdapter(){
public void windowClosing(WindowEvent e){
DLGINFO.setText(" 默认端口号为:8888");
}
}
);
//取消按钮的事件处理
cancel.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
DLGINFO.setText(" 默认端口号为:8888");
dispose();
}
});
}
}
---------------------------------
ServerListen.java-----------------------------
package com.canlong.server;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import javax.swing.JComboBox;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ServerListen extends Thread {
ServerSocket server;
JComboBox combobox;
JTextArea textarea;
JTextField textfield;
UserLinkList userLinkList;// 用户链表
Node client;
ServerReceive recvThread;
public boolean isStop;
public ServerListen(ServerSocket server, JComboBox combobox,
JTextArea textarea, JTextField textfield, UserLinkList userLinkList) {
this.server = server;
this.combobox = combobox;
this.textarea = textarea;
this.textfield = textfield;
this.userLinkList = userLinkList;
isStop = false;
}
public void run() {
while (!isStop && !server.isClosed()) {
try {
client = new Node();
client.socket = server.accept();
client.output = new PrintWriter(client.socket.getOutputStream());;
client.output.flush();
client.input = new BufferedReader(new InputStreamReader(client.socket.getInputStream()));
client.username = client.input.readLine();
// 显示提示信息
combobox.addItem(client.username);
userLinkList.addUser(client);
textarea.append("用户 " + client.username + " 上线" + "\n");
textfield.setText("在线用户" + userLinkList.getCount() + "人\n");
recvThread = new ServerReceive(textarea, textfield, combobox,
client, userLinkList);
recvThread.start();
} catch (Exception e) {
}
}
}
}
---------------------------------
ServerReceive.java-----------------------------
package com.canlong.server;
import java.util.Date;
import javax.swing.JComboBox;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ServerReceive extends Thread {
JTextArea textarea;
JTextField textfield;
JComboBox combobox;
Node client;
UserLinkList userLinkList;//用户链表
public boolean isStop;
public ServerReceive(JTextArea textarea,JTextField textfield,
JComboBox combobox,Node client,UserLinkList userLinkList){
this.textarea = textarea;
this.textfield = textfield;
this.client = client;
this.userLinkList = userLinkList;
this.combobox = combobox;
isStop = false;
}
public void run(){
//向所有人发送用户的列表
sendUserList();
sendToAll("系统信息:"+client.username+"上线了");
while(!isStop && !client.socket.isClosed()){
try{
String str = client.input.readLine();
Message message = new Message(str);
//发给所有人前缀为all,发给某人前缀为name
if(message.isValid()){
if(message.getType().equalsIgnoreCase("聊天信息")){
Message me = new Message(message.getBody());
if(me.getType().equals("所有人")){
sendToAllMes(me.getBody());
}else{
sendSomeBody(me.getType(),me.getBody());
}
}else{
//向某人私聊
}
}else{
//用户下线
Node node = userLinkList.findUser(client.username);
client.input.close();
client.output.close();
client.socket.close();
userLinkList.delUser(node);
String msg = "系统信息:"+"用户:" + client.username + " 下线";
int count = userLinkList.getCount();
combobox.removeAllItems();
combobox.addItem("所有人");
int i = 0;
while(i < count){
node = userLinkList.findUser(i);
if(node == null) {
i ++;
continue;
}
combobox.addItem(node.username);
i++;
}
combobox.setSelectedIndex(0);
textarea.append(msg);
textfield.setText("在线用户" + userLinkList.getCount() + "人\n");
sendToAll(msg);//向所有人发送消息
sendUserList();//重新发送用户列表,刷新
break;
}
// if(type.equalsIgnoreCase("聊天信息")){
// String toSomebody = client.input.readLine();
// String status = client.input.readLine();
// String action = client.input.readLine();
// String message = client.input.readLine();
//
// String msg = 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 (Exception e){
// //System.out.println("###"+e);
// }
//
// Node node = userLinkList.findUser(toSomebody);
//
// if(node != null){
// node.output.writeObject("聊天信息");
// node.output.flush();
// node.output.writeObject(msg);
// node.output.flush();
// }
// }
// }
// else if(type.equalsIgnoreCase("用户下线")){
// Node node = userLinkList.findUser(client.username);
// userLinkList.delUser(node);
//
// String msg = "用户 " + client.username + " 下线\n";
// int count = userLinkList.getCount();
//
// combobox.removeAllItems();
// combobox.addItem("所有人");
// int i = 0;
// while(i < count){
// node = userLinkList.findUser(i);
// if(node == null) {
// i ++;
// continue;
// }
// combobox.addItem(node.username);
// i++;
// }
// combobox.setSelectedIndex(0);
// textarea.append(msg);
// textfield.setText("在线用户" + userLinkList.getCount() + "人\n");
// sendToAll(msg);//向所有人发送消息
// sendUserList();//重新发送用户列表,刷新
//
// break;
// }
}
catch (Exception e){
//System.out.println(e);
}
}
}
public void sendSomeBody(String name, String content) {
Node node = userLinkList.findUser(name);
Message message = new Message(content);
if(node == null) {
return;
}
try{
client.output.println("聊天信息:"+message.getType()+" "+new Date(System.currentTimeMillis()).toLocaleString() + " 对 "+name+" 说");
client.output.flush();
client.output.println("聊天信息:"+message.getBody());
client.output.flush();
node.output.println("聊天信息:"+message.getType()+" "+new Date(System.currentTimeMillis()).toLocaleString() + " 对你说");
node.output.flush();
node.output.println("聊天信息:"+message.getBody());
node.output.flush();
}
catch (Exception e){
//System.out.println(e);
}
}
public void sendToAll(String msg){
int count = userLinkList.getCount();
//System.out.println("haha");
int i = 0;
while(i < count){
Node node = userLinkList.findUser(i);
if(node == null) {
i ++;
continue;
}
try{
//node.output.println("聊天信息");
//node.output.flush();
node.output.println(msg);
node.output.flush();
}
catch (Exception e){
//System.out.println(e);
}
i++;
}
}
public void sendToAllMes(String msg){
Message message = new Message(msg);
if(message.isValid()){
int count = userLinkList.getCount();
int i = 0;
while(i < count){
Node node = userLinkList.findUser(i);
if(node == null) {
i ++;
continue;
}
try{
//node.output.println("聊天信息");
//node.output.flush();
node.output.println("聊天信息:"+message.getType()+" "+new Date(System.currentTimeMillis()).toLocaleString());
node.output.flush();
node.output.println("聊天信息:"+message.getBody());
node.output.flush();
}
catch (Exception e){
//System.out.println(e);
}
i++;
}
}
}
public void sendUserList(){
String userlist = "用户列表:";
int count = userLinkList.getCount();
int i = 0;
while(i < count){
Node node = userLinkList.findUser(i);
if(node == null) {
i ++;
continue;
}
userlist += node.username;
if(i==count-1)
break;
userlist += ":";
i++;
}
i = 0;
while(i < count){
Node node = userLinkList.findUser(i);
if(node == null) {
i ++;
continue;
}
try{
//node.output.println("用户列表");
//node.output.flush();
node.output.println(userlist);
node.output.flush();
}
catch (Exception e){
//System.out.println(e);
}
i++;
}
}
}
---------------------------------
UserLinkList.java-----------------------------
package com.canlong.server;
public class UserLinkList {
Node root;
Node pointer;
int count;
public UserLinkList(){
root = new Node();
root.next = null;
pointer = null;
count = 0;
}
public void addUser(Node n){
pointer = root;
while(pointer.next != null){
pointer = pointer.next;
}
pointer.next = n;
n.next = null;
count++;
}
public void delUser(Node n){
pointer = root;
while(pointer.next != null){
if(pointer.next == n){
pointer.next = n.next;
count --;
break;
}
pointer = pointer.next;
}
}
public int getCount(){
return count;
}
public Node findUser(String username){
if(count == 0) return null;
pointer = root;
while(pointer.next != null){
pointer = pointer.next;
if(pointer.username.equalsIgnoreCase(username)){
return pointer;
}
}
return null;
}
public Node findUser(int index){
if(count == 0) {
return null;
}
if(index <
0) {
return null;
}
pointer = root;
int i = 0;
while(i < index + 1){
if(pointer.next != null){
pointer = pointer.next;
}
else{
return null;
}
i++;
}
return pointer;
}
}
聊天室客户端主要包括6个文件,它们的功能如下:
(1)ChatClient.java:包含名为ChatClient的public类,其主要功能为定义客户端的界面,添加事件侦听与事件处理。该类定义了Connect()与DisConnect()方法实现与服务器的连接与断开连接。当登录到指定的服务器时,调用ClientReceive类实现消息收发,同时该类还定义了SendMessage()方法来向其他用户发送带有表情的消息或者悄悄话。
(2)ClientReceive.java:该类是实现服务器端与客户端消息收发的类。
(3)ConnectConf.java:该类继承自JDialog,是用户对所要连接的服务器IP及侦听端口进行修改配置的类。
(4)UserConf.java:该类继承自JDialog,是用户对连接到服务器所显示的用户名进行修改配置的类。
(5)Help.java:客户端程序的帮助类。
(6)Message.java:对消息进行封装
---------------------------------
ChatClient.java-----------------------------
package com.canlong.client;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Date;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
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.JTextField;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import com.canlong.server.Help;
public class ChatClient extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
String ip = "127.0.0.1";// 连接到服务端的ip地址
int port = 8888;// 连接到服务端的端口号
String userName = "你青春还有多久";// 用户名
int type = 0;// 0表示未连接,1表示已连接
JComboBox combobox;// 选择发送消息的接受者
JTextArea messageShow;// 客户端的信息显示
JScrollPane messageScrollPane;// 信息显示的滚动条
JLabel sendToLabel, messageLabel;
JTextField clientMessage;// 客户端消息的发送
// JCheckBox checkbox;//悄悄话
// JComboBox actionlist;//表情选择
JButton clientMessageButton;// 发送消息
JTextField showStatus;// 显示用户连接状态
Socket socket;
PrintWriter output;// 网络套接字输出流
BufferedReader input;// 网络套接字输入流
ClientReceive recvThread;
// 建立菜单栏
JMenuBar jMenuBar = new JMenuBar();
// 建立菜单组
JMenu operateMenu = new JMenu("操作(O)");
// 建立菜单项
JMenuItem loginItem = new JMenuItem("用户登录(I)");
JMenuItem logoffItem = new JMenuItem("用户注销(L)");
JMenuItem exitItem = new JMenuItem("退出(X)");
JMenu conMenu = new JMenu("设置(C)");
JMenuItem userItem = new JMenuItem("用户设置(U)");
JMenuItem connectItem = new JMenuItem("连接设置(C)");
JMenu helpMenu = new JMenu("帮助(H)");
JMenuItem helpItem = new JMenuItem("帮助(H)");
JMenuItem about = new JMenuItem("关于作者(A)");
// 建立工具栏
JToolBar toolBar = new JToolBar();
// 建立工具栏中的按钮组件
JButton loginButton;// 用户登录
JButton logoffButton;// 用户注销
// JButton userButton;//用户信息的设置
JButton connectButton;// 连接设置
JButton exitButton;// 退出按钮
// 框架的大小
Dimension faceSize = new Dimension(400, 600);
JPanel downPanel;
GridBagLayout girdBag;
GridBagConstraints girdBagCon;
public ChatClient() {
init();// 初始化程序
// 添加框架的关闭事件处理
this.setDefaultCloseOperation
(JFrame.EXIT_ON_CLOSE);
this.pack();
// 设置框架的大小
this.setSize(faceSize);
this.setVisible(true);
setIconImage(getToolkit().getImage("face/love.gif"));
// 设置运行时窗口的位置
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation((int) (screenSize.width - faceSize.getWidth()) / 2,
(int) (screenSize.height - faceSize.getHeight()) / 2);
this.setResizable(false);
this.setTitle("聊天室客户端"); // 设置标题
// 为操作菜单栏设置热键'V'
operateMenu.setMnemonic('O');
// 为用户登录设置快捷键为ctrl+i
loginItem.setMnemonic('I');
loginItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I,
InputEvent.CTRL_MASK));
// 为用户注销快捷键为ctrl+l
logoffItem.setMnemonic('L');
logoffItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L,
InputEvent.CTRL_MASK));
// 为退出快捷键为ctrl+x
exitItem.setMnemonic('X');
exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,
InputEvent.CTRL_MASK));
// 为设置菜单栏设置热键'C'
conMenu.setMnemonic('C');
// 为用户设置设置快捷键为ctrl+u
userItem.setMnemonic('U');
userItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U,
InputEvent.CTRL_MASK));
// 为连接设置设置快捷键为ctrl+c
connectItem.setMnemonic('C');
connectItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
InputEvent.CTRL_MASK));
// 为帮助菜单栏设置热键'H'
helpMenu.setMnemonic('H');
// 为帮助设置快捷键为ctrl+p
helpItem.setMnemonic('H');
helpItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H,
InputEvent.CTRL_MASK));
}
public void init() {
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
// 添加菜单栏
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);
helpMenu.add(about);
jMenuBar.add(helpMenu);
setJMenuBar(jMenuBar);
// 初始化按钮
loginButton = new JButton("登录");
logoffButton = new JButton("注销");
connectButton = new JButton("连接设置");
exitButton = new JButton("退出");
loginButton.setToolTipText("连接到指定的服务器");
logoffButton.setToolTipText("与服务器断开连接");
connectButton.setToolTipText("设置所要连接到的服务器信息");
toolBar.add(connectButton);
toolBar.addSeparator();// 添加分隔栏
toolBar.add(loginButton);
toolBar.add(logoffButton);
toolBar.addSeparator();// 添加分隔栏
toolBar.add(exitButton);
contentPane.add(toolBar, BorderLayout.NORTH);
// 初始时
loginButton.setEnabled(true);
logoffButton.setEnabled(false);
// 为菜单栏添加事件监听
loginItem.addActionListener(this);
logoffItem.addActionListener(this);
exitItem.addActionListener(this);
userItem.addActionListener(this);
connectItem.addActionListener(this);
helpItem.addActionListener(this);
about.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {// 当单击“关于作者”菜单时
String version = "版本: 1.0\n";
String author = "作者: 你青春还有多久\n";
String email = "E-mail: 1164191183@qq.com";
JOptionPane.showMessageDialog(null, version + author + email);
}
});
// 添加按钮的事件侦听
loginButton.addActionListener(this);
logoffButton.addActionListener(this);
// userButton.addActionListener(this);
connectButton.addActionListener(this);
exitButton.addActionListener(this);
combobox = new JComboBox();
combobox.insertItemAt("所有人", 0);
combobox.setSelectedIndex(0);
messageShow = new JTextArea();
messageShow.setEditable(false);
// 添加滚动条
messageScrollPane = new JScrollPane(messageShow,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
messageScrollPane.setPreferredSize(new Dimension(400, 400));
messageScrollPane.revalidate();
clientMessage = new JTextField(23);
clientMessage.setEnabled(false);
clientMessageButton = new JButton();
clientMessageButton.setText("发送");
// 添加系统消息的事件侦听
clientMessage.addActionListener(this);
clientMessageButton.addActionListener(this);
sendToLabel = new JLabel("发送至:");
// express = new JLabel("
表情:
");
messageLabel = new JLabel("发送消息:");
downPanel = new JPanel();
girdBag = new GridBagLayout();
downPanel.setLayout(girdBag);
girdBagCon = new GridBagConstraints();
girdBagCon.gridx = 0;
girdBagCon.gridy = 0;
girdBagCon.gridwidth = 5;
girdBagCon.gridheight = 2;
girdBagCon.ipadx = 5;
girdBagCon.ipady = 5;
JLabel none = new JLabel("
");
girdBag.setConstraints(none, girdBagCon);
downPanel.add(none);
girdBagCon = new GridBagConstraints();
girdBagCon.gridx = 0;
girdBagCon.gridy = 2;
girdBagCon.insets = new Insets(1, 0, 0, 0);
// girdBagCon.ipadx = 5;
// girdBagCon.ipady = 5;
girdBag.setConstraints(sendToLabel, girdBagCon);
downPanel.add(sendToLabel);
girdBagCon = new GridBagConstraints();
girdBagCon.gridx = 1;
girdBagCon.gridy = 2;
girdBagCon.anchor = GridBagConstraints.LINE_START;
girdBag.setConstraints(combobox, girdBagCon);
downPanel.add(combobox);
girdBagCon = new GridBagConstraints();
girdBagCon.gridx = 2;
girdBagCon.gridy = 2;
girdBagCon.anchor = GridBagConstraints.LINE_END;
girdBagCon = new GridBagConstraints();
girdBagCon.gridx = 3;
girdBagCon.gridy = 2;
girdBagCon.anchor = GridBagConstraints.LINE_START;
girdBagCon = new GridBagConstraints();
girdBagCon.gridx = 4;
girdBagCon.gridy = 2;
girdBagCon.insets = new Insets(1, 0, 0, 0);
girdBagCon = new GridBagConstraints();
girdBagCon.gridx = 0;
girdBagCon.gridy = 3;
girdBag.setConstraints(messageLabel, girdBagCon);
downPanel.add(messageLabel);
girdBagCon = new GridBagConstraints();
girdBagCon.gridx = 1;
girdBagCon.gridy = 3;
girdBagCon.gridwidth = 3;
girdBagCon.gridheight = 1;
girdBag.setConstraints(clientMessage, girdBagCon);
downPanel.add(clientMessage);
girdBagCon = new GridBagConstraints();
girdBagCon.gridx = 4;
girdBagCon.gridy = 3;
girdBag.setConstraints(clientMessageButton, girdBagCon);
downPanel.add(clientMessageButton);
showStatus = new JTextField(35);
showStatus.setEditable(false);
girdBagCon = new GridBagConstraints();
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(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
if (type == 1) {
DisConnect();
}
System.exit(0);
}
});
}
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj == connectItem || obj == connectButton) { // 连接服务端设置
// 调出连接设置对话框
ConnectConf conConf = new ConnectConf(this, ip, port);
conConf.setVisible(true);
ip = conConf.userInputIp;
port = conConf.userInputPort;
} else if (obj == loginItem || obj == loginButton) { // 登录
UserConf userConf = new UserConf(this, userName);
userConf.setVisible(true);
} else if (obj == logoffItem || obj == logoffButton) { // 注销
DisConnect();
showStatus.setText("");
} else if (obj == clientMessage || obj == clientMessageButton) { // 发送消息
SendMessage();
clientMessage.setText("");
} else if (obj == exitButton || obj == exitItem) { // 退出
int j = JOptionPane.showConfirmDialog(this, "真的要退出吗?", "退出",
JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE);
if (j == JOptionPane.YES_OPTION) {
if (type == 1) {
DisConnect();
}
System.exit(0);
}
} else if (obj == helpItem) { // 菜单栏中的帮助
// 调出帮助对话框
Help helpDialog = new Help(this);
helpDialog.setVisible(true);
}
}
public void Connect() {
try {
socket = new Socket(ip, port);
} catch (Exception e) {
JOptionPane.showConfirmDialog(this, "不能连接到指定的服务器。\n请确认连接设置是否正确。",
"提示", JOptionPane.DEFAULT_OPTION,
JOptionPane.WARNING_MESSAGE);
return;
}
try {
output = new PrintWriter(socket.getOutputStream());
output.flush();
input = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
output.println(userName);
output.flush();
recvThread = new ClientReceive(socket, output, input, combobox,
messageShow, showStatus, this);
recvThread.start();
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 (Exception e) {
System.out.println(e);
return;
}
}
public void DisConnect() {
loginButton.setEnabled(true);
loginItem.setEnabled(true);
userItem.setEnabled(true);
connectButton.setEnabled(true);
connectItem.setEnabled(true);
logoffButton.setEnabled(false);
logoffItem.setEnabled(false);
clientMessage.setEnabled(false);
if (socket.isClosed()) {
return;
}
try {
output.println("用户下线");
output.flush();
input.close();
output.close();
socket.close();
messageShow.append("已经与服务器断开连接...\n");
type = 0;// 标志位设为未连接
} catch (Exception e) {
//
System.out.println("aaa");
}
}
public void SendMessage() {
String toSomebody = combobox.getSelectedItem().toString();
String status = "";
String message = userName + ":" + clientMessage.getText();
if (socket.isClosed()) {
return;
}
try {
output.println("聊天信息:" + toSomebody + ":" + message);
output.flush();
} catch (Exception e) {
}
}
public static void main(String[] args) {
new ChatClient();
}
}
---------------------------------
ClientReceive.java-----------------------------
package com.canlong.client;
import java.io.BufferedReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JComboBox;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ClientReceive extends Thread {
private JComboBox combobox;
private JTextArea textarea;
Socket socket;
PrintWriter output;
BufferedReader input;
JTextField showStatus;
ChatClient chatClient;
public ClientReceive(Socket socket, PrintWriter output,
BufferedReader input, JComboBox combobox, JTextArea textarea,
JTextField showStatusm,ChatClient chatClient) {
this.socket = socket;
this.output = output;
this.input = input;
this.combobox = combobox;
this.textarea = textarea;
this.showStatus = showStatus;
this.chatClient = chatClient;
}
public void run() {
while (!socket.isClosed()) {
try {
String type = input.readLine();
System.out.println(type);
Message mesg = new Message(type);
if (mesg.isValid()) {
if (mesg.getType().equalsIgnoreCase("聊天信息")) {
textarea.append(mesg.getBody() + "\n");
} else if (mesg.getType().equalsIgnoreCase("用户列表")) {
String usernames[] = mesg.getBody().split(":");
combobox.removeAllItems();
int i = 0;
combobox.addItem("所有人");
while (i < usernames.length) {
combobox.addItem(usernames[i]);
i++;
}
combobox.setSelectedIndex(0);
showStatus.setText("在线用户 " + usernames.length + " 人");
} else if (mesg.getType().equalsIgnoreCase("系统信息")) {
textarea.append("系统信息: " + mesg.getBody() + "\n");
}
// textarea.append(mesg.getBody());
} else {
textarea.append("系统信息: 服务器关闭!连接断开!!\n");
chatClient.loginButton.setEnabled(true);
chatClient.loginItem.setEnabled(true);
//chatClient.userButton.setEnabled(true);
chatClient.userItem.setEnabled(true);
chatClient.connectButton.setEnabled(true);
chatClient.connectItem.setEnabled(true);
chatClient.logoffButton.setEnabled(false);
chatClient.logoffItem.setEnabled(false);
chatClient.clientMessage.setEnabled(false);
if(socket.isClosed()){
//System.out.println("123");
return ;
}
output.close();
input.close();
socket.close();
}
} catch (Exception e) {
System.out.println(e);
}
}
}
}
---------------------------------
ConnectConf.java-----------------------------
package com.canlong.client;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ConnectConf extends JDialog {
private static final long serialVersionUID = 1L;
JPanel panelUserConf = new JPanel();
JButton save = new JButton();
JButton cancel = new JButton();
JLabel DLGINFO=new JLabel(" 默认连接设置为 127.0.0.1:8888");
JPanel panelSave = new JPanel();
JLabel message = new JLabel();
String userInputIp;
int userInputPort;
JTextField inputIp;
JTextField inputPort;
public ConnectConf(JFrame frame,String ip,int port) {
super(frame, true);
this.userInputIp = ip;
this.userInputPort = port;
try {
jbInit();
}
catch (Exception e) {
e.printStackTrace();
}
//设置运行位置,使对话框居中
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation( (int) (screenSize.width - 400) / 2 + 50,
(int) (screenSize.height - 600) / 2 + 150);
this.setResizable(false);
}
private void jbInit() throws Exception {
this.setSize(new Dimension(300, 130));
this.setTitle("连接设置");
message.setText(" 请输入服务器的IP地址:");
inputIp = new JTextField(10);
inputIp.setText(userInputIp);
inputPort = new JTextField(4);
inputPort.setText(""+userInputPort);
save.setText("保存");
cancel.setText("取消");
panelUserConf.setLayout(new GridLayout(2,2,1,1));
panelUserConf.add(message);
panelUserConf.add(inputIp);
panelUserConf.add(new JLabel(" 请输入服务器的端口号:"));
panelUserConf.add(inputPort);
panelSave.add(new Label(" "));
panelSave.add(save);
panelSave.add(cancel);
panelSave.add(new Label(" "));
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(panelUserConf, BorderLayout.NORTH);
contentPane.add(DLGINFO, BorderLayout.CENTER);
contentPane.add(panelSave, BorderLayout.SOUTH);
//保存按钮的事件处理
save.addActionListener(
new ActionListener() {
public void actionPerformed (ActionEvent a) {
int savePort;
//判断端口号是否合法
try{
userInputIp = "" + InetAddress.getByName(inputIp.getText());
userInputIp = userInputIp.substring(1);
}
catch(UnknownHostException e){
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(NumberFormatException e){
DLGINFO.setText(" 错误的端口号,端口号请填写整数!");
inputPort.setText("");
return;
}
}
}
);
//关闭对话框时的操作
this.addWindowListener(
new WindowAdapter(){
public void windowClosing(WindowEvent e){
DLGINFO.setText(" 默认连接设置为 127.0.0.1:8888");
}
}
);
//取消按钮的事件处理
cancel.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
DLGINFO.setText(" 默认连接设置为 127.0.0.1:8888");
dispose();
}
});
}
}
---------------------------------
Help.java-----------------------------
package com.canlong.client;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Label;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class Help extends JDialog {
private static final long serialVersionUID = 1L;
JPanel titlePanel = new JPanel();
JPanel contentPanel = new JPanel();
JPanel closePanel = new JPanel();
JButton close = new JButton();
JLabel title = new JLabel("聊天室客户端帮助");
JTextArea help = new JTextArea();
Color bg = new Color(255,255,255);
public Help(JFrame frame) {
super(frame, true);
try {
jbInit();
}
catch (Exception e) {
e.printStackTrace();
}
//设置运行位置,使对话框居中
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation( (int) (screenSize.width - 400) / 2 + 25,
(int) (screenSize.height - 320) / 2);
this.setResizable(false);
}
private void jbInit() throws Exception {
this.setSize(new Dimension(350, 270));
this.setTitle("帮助");
titlePanel.setBackground(bg);;
contentPanel.setBackground(bg);
closePanel.setBackground(bg);
help.setText("1、设置所要连接服务端的IP地址和端口"+
"(默认设置为\n 127.0.0.1:8888)。\n"+
"2、输入你的用户名(默认设置为:狂狂)。\n"+
"3、点击“登录”便可以连接到指定的服务器;\n"+
" 点击“注销”可以和服务器端开连接。\n"+
"4、选择需要接受消息的用户,在消息栏中写入消息,\n"+
" 同时选择表情,之后便可发送消息。\n");
help.setEditable(false);
titlePanel.add(new Label(" "));
titlePanel.add(title);
titlePanel.add(new Label(" "));
contentPanel.add(help);
closePanel.add(new Label(" "));
closePanel.add(close);
closePanel.add(new Label(" "));
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(titlePanel, BorderLayout.NORTH);
contentPane.add(contentPanel, BorderLayout.CENTER);
contentPane.add(closePanel, BorderLayout.SOUTH);
close.setText("关闭");
//事件处理
close.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
}
}
---------------------------------
Message.java-----------------------------
package com.canlong.client;
//type="用户上线||用户下线||系统消息||聊天消息||列表更新"
//对于聊天消息body格式为name:content
public class Message {
private String type; //保存信息的类型,分号之前的部分
private String body; //保存信息的具体内容,分号之后的部分
private boolean valid; //信息是否有效,也就是信息是否含有:
public Message(String messageLine){
valid=false;
type=body=null;
int pos=messageLine.indexOf(":");
if(pos>=0){
type=messageLine.substring(0,pos).toUpperCase();//分号之前的字符串
body=messageLine.substring(pos+1);//分号之后的字符串
valid=true; //信息有效
}else{
type=messageLine;
}
}
public Message(String type,String body){
valid=true;
this.type=type;
this.body=body;
}
public String getType(){
return type;
}
public String getBody(){
return body;
}
public boolean isValid(){
return valid;
}
}
---------------------------------
UserConf.java-----------------------------
package com.canlong.client;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class UserConf extends JDialog {
private static final long serialVersionUID = 1L;
JPanel panelUserConf = new JPanel();
JButton save = new JButton();
JButton cancel = new JButton();
JLabel DLGINFO=new JLabel(" 默认用户名为:你青春还有多久");
JPanel panelSave = new JPanel();
JLabel message = new JLabel();
String userInputName;
ChatClient chatClient;
JTextField userName ;
public UserConf(ChatClient frame,String str) {
super(frame, true);
this.chatClient = frame;
this.userInputName = str;
try {
jbInit();
}
catch (Exception e) {
e.printStackTrace();
}
//设置运行位置,使对话框居中
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation( (int) (screenSize.width - 400) / 2 + 50,
(int) (screenSize.height - 600) / 2 + 150);
this.setResizable(false);
}
private void jbInit() throws Exception {
this.setSize(new Dimension(300, 120));
this.setTitle("用户设置");
message.setText("请输入用户名:");
userName = new JTextField(10);
userName.setText(userInputName);
userName.requestFocus();
userName.selectAll();
save.setText("确定");
cancel.setText("取消");
panelUserConf.setLayout(new FlowLayout());
panelUserConf.add(message);
panelUserConf.add(userName);
panelSave.add(new Label(" "));
panelSave.add(save);
panelSave.add(cancel);
panelSave.add(new Label(" "));
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(panelUserConf, BorderLayout.NORTH);
contentPane.add(DLGINFO, BorderLayout.CENTER);
contentPane.add(panelSave, BorderLayout.SOUTH);
//保存按钮的事件处理
save.addActionListener(
new ActionListener() {
public void actionPerformed (ActionEvent a) {
if(userName.getText().equals("")){
DLGINFO.setText(
" 用户名不能为空!");
userName.setText(userInputName);
return;
}
else if(userName.getText().length() > 15){
DLGINFO.setText(" 用户名长度不能大于15个字符!");
userName.setText(userInputName);
return;
}
userInputName = userName.getText();
chatClient.userName = userInputName;
chatClient.Connect();
dispose();
}
}
);
//关闭对话框时的操作
this.addWindowListener(
new WindowAdapter(){
public void windowClosing(WindowEvent e){
DLGINFO.setText(" 默认用户名为:
你青春还有多久
");
}
}
);
//取消按钮的事件处理
cancel.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
DLGINFO.setText(" 默认用户名为:你青春还有多久");
dispose();
}
});
}
}