Java聊天软件服务器+客户端源码---…

java最新版聊天室软件,初学项目必备!!!

周末写的,私聊,群聊功能基本达到要求,就是服务器端的扩展功能还没优化,时间太急了,实在没心情,希望哪位大神看到后帮我改进。


聊天室服务端主要包括8个文件,它们的功能如下:

1ChatServer.java:包含名为ChatServerpublic类,其主要功能为定义服务器端的界面,添加事件侦听与事件处理。调用ServerListen类来实现服务端用户上线与下线的侦听,调用ServerReceive类来实现服务器端的消息的收发。

2ServerListen.java:该类实现服务端用户上线与下线的侦听。该类对用户上线下线的侦听是通过调用用户链表类(UserLinkList)来实现的,当用户上线与下线情况发生变化时,该类会对主类的界面进行相应的修改。

3ServerReceive.java:该类是实现服务器端的消息的收发的类。该类分别定义了向某用户及所有人发送消息的方法,发送的消息会显示在主界面类的界面上。

4PortConf.java:该类继承自JDialog,是用户对服务器端侦听端口进行修改配置的类。

5Node.java:用户链表的节点类,定义了链表中的用户。该类与前面所讲的链表节点Node类的功能相当。

6UserLinkList.java:用户链表节点的具体实现类。该类通过构造函数构造用户链表,定义了添加用户,删除用户、返回用户数、根据用户名查找用户、根据索引查找用户这5个方法。

7Help.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个文件,它们的功能如下:

1ChatClient.java:包含名为ChatClientpublic类,其主要功能为定义客户端的界面,添加事件侦听与事件处理。该类定义了Connect()DisConnect()方法实现与服务器的连接与断开连接。当登录到指定的服务器时,调用ClientReceive类实现消息收发,同时该类还定义了SendMessage()方法来向其他用户发送带有表情的消息或者悄悄话。

2ClientReceive.java:该类是实现服务器端与客户端消息收发的类。

3ConnectConf.java:该类继承自JDialog,是用户对所要连接的服务器IP及侦听端口进行修改配置的类。

4UserConf.java:该类继承自JDialog,是用户对连接到服务器所显示的用户名进行修改配置的类。

5Help.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();
}
});
}
}



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值