JavaGUI版聊天室

刚接触Java中的GUI编程和网络编程时觉得很有意思,所以就结合了这两个方面并结合IO、多线程的知识,做了一个GUI版的聊天室。

这个聊天室是两端开发,服务器端和客户端

服务器端功能:

  1. 开启和关闭服务器
  2. 总览聊天室内的聊天内容
  3. 监听连接对象
  4. 转发给客户端聊天信息

客户端功能:

  1. 输入基本信息,服务器IP地址和端口号即可连接服务器。
  2. 查看聊天室和接收聊天室的消息记录
  3. 查看了聊天室在线成员
  4. 给服务器发送聊天信息

开发工具:

eclipse、WindowBuilder插件

顺便附上WindowBuilder快速教程:https://www.jianshu.com/p/232f72f55d79

基本思路:

服务器端:由服务器监听连接,每接收到一个连接就创建一个服务端线程,在服务端线程中,一是读取信息文件,并将读取到的信息发送给客户端,二是开启user线程,用于将此用户添加至在线用户的集合中。

客户端:用户登录完成时,与服务器建立连接,并发送用户输入的用户信息,服务端将聊天信息和连接信息发送给客户端,由客户端接送并显示信息。

目录结构:

JavaGUI版聊天室_网络编程

效果展示:

JavaGUI版聊天室_IO_02

JavaGUI版聊天室_IO_03

JavaGUI版聊天室_网络编程_04

JavaGUI版聊天室_聊天室_05

JavaGUI版聊天室_GUI_06

基本的User类

package cn.hehewocao_User;

public class User {


private String username;
private String sex;

public User() {

}

public User( String username, String sex) {

this.username = username;
this.sex = sex;

}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}
}

服务器监听类:ServerAcceptThread

package cn.hehewocao_Server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import cn.hehewocao_ServerTools.ServerTools;
import cn.hehewocao_User.User;
import cn.hehewocao_User.UserThread;

public class ServerAcceptThread implements Runnable {

private ServerSocket ss;
public static ArrayList<Socket> arraySocket = new ArrayList<Socket>();
public static ArrayList<String> arrayUser = new ArrayList<String>();
public static int i = 1;

public ServerAcceptThread(ServerSocket ss) {
this.ss = ss;
}

@Override
public void run() {

while (true) {
try {
Socket s = ss.accept();
arraySocket.add(s);
String IP = s.getInetAddress().getHostAddress();
System.out.println("IP:" + IP + " 已连接服务器!");
ServerThread st = new ServerThread(s);
Thread thread = new Thread(st);
thread.start();

} catch (IOException e) {
JOptionPane.showMessageDialog(null, "服务器接收连接出现异常!");
}

}
}
}

服务器线程类:

package cn.hehewocao_Server;

import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import cn.hehewocao_ServerTools.ServerTools;

public class ServerThread implements Runnable {

private static Socket socket;
private String username;
public ServerThread(Socket socket) {
this.socket = socket;

}

@Override
public void run() {

try {
start();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}

}

public static void start() throws IOException {
Socket s = socket;
ServerReciveThread srt = new ServerReciveThread(s);
Thread rt = new Thread(srt);
rt.start();

}
}

服务器发送信息线程:ServerReciveThread

package cn.hehewocao_Server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ListIterator;

import javax.swing.JOptionPane;

import cn.hehewocao_ServerTools.ServerTools;
import cn.hehewocao_User.UserThread;
import cn.hehewocao_Windows.WindowClientChatRoom;
import cn.hehewocao_Windows.WindowServer;

public class ServerReciveThread implements Runnable {

private Socket socket;

public ServerReciveThread(Socket socket) {
this.socket = socket;
}

@Override
public void run() {

Socket s = socket;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String ns = ServerAcceptThread.i + "=" + br.readLine();
ServerAcceptThread.arrayUser.add(ns);
ServerAcceptThread.i++;

ServerTools.ServerSendMessage(ServerAcceptThread.arraySocket);

// 开启用户连接线程
UserThread ut = new UserThread(ServerAcceptThread.arraySocket);
Thread t = new Thread(ut);
t.start();

String Messagestr = null;
while ((Messagestr = br.readLine()) != null) {
String[] close = Messagestr.split("=");
//多增加一个判断,防止下标越界异常
if (close.length!=1 && close[1].equals("Socket is closed!")) {

ServerAcceptThread.arraySocket.remove(s);
ListIterator<String> lit = ServerAcceptThread.arrayUser.listIterator();
while (lit.hasNext()) {
String[] userinfo = lit.next().split("=");
if (userinfo[1].equals(close[0])) {
lit.remove();
}
}

UserThread ut1 = new UserThread(ServerAcceptThread.arraySocket);
Thread t1 = new Thread(ut1);
t1.start();
return;
}
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式
String time = df.format(new Date());
String IP = s.getInetAddress().getHostAddress();
String displayMessagestr = time + " " + Messagestr;

Messagestr = time + "=" + IP + "=" + Messagestr;
writerFile(Messagestr);

System.out.println("收到客户端数据:" + Messagestr);

WindowServer.infortextArea.append(displayMessagestr);
WindowServer.infortextArea.append("\n");
//设置光标在末尾
WindowServer.infortextArea.setCaretPosition(WindowServer.infortextArea.getText().length());
ServerTools.ServerSendMessage(ServerAcceptThread.arraySocket);
}
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "接收数据失败!");
}
}

public boolean writerFile(String str) {

try {
BufferedWriter bw = new BufferedWriter(new FileWriter("MessageRecord.txt", true));
bw.write(str);
bw.newLine();
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}

}

**服务器工具类:ServerTools **

package cn.hehewocao_ServerTools;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Vector;

import javax.swing.JOptionPane;

import cn.hehewocao_Server.ServerAcceptThread;
import cn.hehewocao_User.UserThread;
import cn.hehewocao_Windows.WindowServer;

public class ServerTools {

public static void ServerSendMessage(ArrayList<Socket> arraySocket) {

try {
ListIterator<Socket> it = arraySocket.listIterator();
while (it.hasNext()) {
Socket socket = it.next();
Socket s = new Socket(socket.getInetAddress().getHostAddress(), 5555);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
BufferedReader br = new BufferedReader(new FileReader("MessageRecord.txt"));
String message = null;
while ((message = br.readLine()) != null) {
String[] str = message.split("=");

String newMessage = null;
try {
newMessage = str[0] + " " + str[2];
} catch (Exception e) {
ServerAcceptThread.arraySocket.remove(s);
UserThread ut1 = new UserThread(ServerAcceptThread.arraySocket);
Thread t1 = new Thread(ut1);
t1.start();
return;
}
bw.write(newMessage);
bw.newLine();
bw.flush();
}
br.close();
bw.close();
}
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "服务器发送数据失败!");
}

}

// 服务器发送连接信息
public static void ServerSendLink(ArrayList<Socket> arraySocket) {

try {
ListIterator<Socket> it = arraySocket.listIterator();
while (it.hasNext()) {
Socket socket = it.next();
Socket s = new Socket(socket.getInetAddress().getHostAddress(), 1111);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

// 获取table内的数据
ArrayList<String> array = new ArrayList<String>();

for (int i = 0; i < WindowServer.table.getRowCount(); i++) {
String info = null;
for (int j = 0; j < 4; j++) {
if (info == null) {
info = (String) WindowServer.table.getValueAt(i, j);
} else {
info = info + "=" + (String) WindowServer.table.getValueAt(i, j);
}
}
array.add(info);
}
// 发送数据
ListIterator<String> Lit = array.listIterator();
while (Lit.hasNext()) {
bw.write(Lit.next());
bw.newLine();
bw.flush();
}
s.close();
}

} catch (IOException e) {
// JOptionPane.showMessageDialog(null, "服务器发送连接数据失败!");
e.printStackTrace();
}

}

public static boolean writerFile() {

try {
BufferedWriter bw = new BufferedWriter(new FileWriter("MessageRecord.txt"));
bw.write("");
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
}

**用户线程类:UserThread **

package cn.hehewocao_User;

import java.net.Socket;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Vector;

import cn.hehewocao_Server.ServerAcceptThread;
import cn.hehewocao_ServerTools.ServerTools;
import cn.hehewocao_Windows.WindowServer;

public class UserThread implements Runnable{

private static ArrayList<Socket> arraySocket;

public UserThread(ArrayList<Socket> arraySocket) {
this.arraySocket = arraySocket;
}

@Override
public void run() {

countUser();
}

public static void countUser() {

WindowServer.model.setRowCount(0);
Vector<Vector> row = new Vector<Vector>();
Vector<String> columnNames = new Vector<String>();
columnNames.add("连接编号");
columnNames.add("连接IP");
columnNames.add("昵称");
columnNames.add("性别");
System.out.println("共有" + arraySocket.size() + "个用户连接!");
ListIterator<Socket> it = arraySocket.listIterator();
int i = 0;
while(it.hasNext()) {
Socket socket = it.next();
Vector<String> rowData = new Vector<String>();
String[] userinfo = ServerAcceptThread.arrayUser.get(i).split("=");
rowData.add(userinfo[0]);
rowData.add(socket.getInetAddress().getHostAddress());
rowData.add(userinfo[1]);
rowData.add(userinfo[2]);
row.add(rowData);
WindowServer.model.setDataVector(row, columnNames);
i++;
}

ServerTools.ServerSendLink(arraySocket);
}
}

用户工具类:UserTools

package cn.hehewocao_User;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JOptionPane;



public class UserTools {

public static ArrayList<User> fileReader(String filename) {

ArrayList<User> array = new ArrayList<User>();

try {
BufferedReader br = new BufferedReader(new FileReader(filename));
String info = null;
while ((info = br.readLine()) != null) {
String[] s = info.split("=");
User user = new User(s[1], s[2]);
array.add(user);
}
br.close();
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "用户文件读取失败!");
return null;
}
return array;
}
}

客户端接收聊天记录线程:ClientReciveThread

package cn.hehewocao_Client;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JOptionPane;

import cn.hehewocao_Windows.WindowClient;
import cn.hehewocao_Windows.WindowClientChatRoom;

public class ClientReciveThread implements Runnable {

private Socket socket;

public ClientReciveThread(Socket socket) {
this.socket = socket;
}

public void run() {
try {

//接收服务器的消息记录
ServerSocket ss = new ServerSocket(5555);
while (true) {
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String message = null;
String allMessage = null;
while ((message = br.readLine()) != null) {
System.out.println(message);
if(allMessage == null) {
allMessage = message + "\n";
}else {
allMessage = allMessage + message + "\n";
}
WindowClientChatRoom.infotextArea.setText(allMessage);
//设置光标在末尾
WindowClientChatRoom.infotextArea.setCaretPosition(WindowClientChatRoom.infotextArea.getText().length());
}
}

} catch (IOException e) {
try {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write(WindowClient.name + "=Socket is closed!");
bw.flush();
socket.close();
} catch (IOException e1) {
JOptionPane.showMessageDialog(null, "服务器已关闭!");
}
JOptionPane.showMessageDialog(null, "该程序不支持多开鸭~");
System.exit(0);
}
}

}

客户端接收连接信息线程:ClientReciveLinkInfoThread

package cn.hehewocao_Client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;

import javax.swing.JOptionPane;

import cn.hehewocao_Windows.WindowClientChatRoom;

public class ClientReciveLinkInfoThread implements Runnable {

@Override
public void run() {
WindowClientChatRoom.model.setRowCount(0);
try {
ServerSocket ss = new ServerSocket(1111);
while (true) {
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String LinkInfo = null;
Vector<Vector> row = new Vector<Vector>();
Vector<String> columnNames = new Vector<String>();
columnNames.add("连接编号");
columnNames.add("昵称");
columnNames.add("性别");
while((LinkInfo = br.readLine()) != null) {
Vector<String> rowData = new Vector<String>();
String[] info = LinkInfo.split("=");
rowData.add(info[0]);
rowData.add(info[2]);
rowData.add(info[3]);
row.add(rowData);
WindowClientChatRoom.model.setDataVector(row, columnNames);
}

}
} catch (IOException e) {

}
}
}

客户端登录(启动)类:WindowClient

package cn.hehewocao_Windows;

import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class WindowClient extends JFrame {

private JPanel contentPane;
private JTextField usernametextField;
private JButton cencleButton;
private JTextField IPtextField;
private JTextField PORTtextField_1;
public static String name;
public static String sex;
public static Socket s;

public static void main(String[] args) {
/**
* Launch the application.
*/
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
WindowClient frame = new WindowClient();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});

/**
* Create the frame.
*/
}

public WindowClient() {
setTitle("加入聊天室");
setResizable(false);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
int width = Toolkit.getDefaultToolkit().getScreenSize().width;
int height = Toolkit.getDefaultToolkit().getScreenSize().height;

setBounds((width - 570) / 2, (height - 400) / 2, 570, 400);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);

JLabel usernameLabel = new JLabel("昵称:");
usernameLabel.setBounds(138, 54, 72, 18);
contentPane.add(usernameLabel);

JLabel sexLabel = new JLabel("性别:");
sexLabel.setBounds(138, 100, 72, 18);
contentPane.add(sexLabel);

usernametextField = new JTextField();
usernametextField.setBounds(224, 51, 204, 24);
contentPane.add(usernametextField);
usernametextField.setColumns(10);

JButton yesButton = new JButton("加入聊天");
yesButton.setBounds(377, 283, 113, 27);

contentPane.add(yesButton);

cencleButton = new JButton("退出");
cencleButton.setBounds(97, 283, 113, 27);
contentPane.add(cencleButton);

JLabel lblip = new JLabel("服务器IP:");
lblip.setBounds(122, 155, 88, 18);
contentPane.add(lblip);

IPtextField = new JTextField();
IPtextField.setColumns(10);
IPtextField.setBounds(224, 152, 204, 24);
contentPane.add(IPtextField);

JLabel label_1 = new JLabel("端口号:");
label_1.setBounds(126, 211, 72, 21);
contentPane.add(label_1);

PORTtextField_1 = new JTextField();
PORTtextField_1.setBounds(224, 209, 204, 24);
contentPane.add(PORTtextField_1);
PORTtextField_1.setColumns(10);

JComboBox sexcomboBox = new JComboBox();
sexcomboBox.setBounds(224, 97, 98, 24);
contentPane.add(sexcomboBox);
sexcomboBox.addItem("男");
sexcomboBox.addItem("女");

// 加入聊天室按钮动作
yesButton.addActionListener(new ActionListener() {

// 如果连接成功,打开聊天室窗口界面!
@Override
public void actionPerformed(ActionEvent e) {

name = usernametextField.getText().trim();
sex = sexcomboBox.getSelectedItem().toString();
String IP = IPtextField.getText().trim();
String port = PORTtextField_1.getText().trim();
int PORT = -1;
try {
PORT = Integer.parseInt(port);
} catch (Exception e1) {
JOptionPane.showMessageDialog(contentPane, "端口号输入不合法!");
}

if (name.length() == 0) {
JOptionPane.showMessageDialog(contentPane, "昵称不能为空!");
} else if (IP.length() == 0) {
JOptionPane.showMessageDialog(contentPane, "服务器IP不能为空!");
} else if (port.length() == 0 || PORT == -1) {
JOptionPane.showMessageDialog(contentPane, "端口号不能为空!");
} else {

try {
//创建与服务器的连接
s = new Socket(IP, PORT);
dispose();
//JOptionPane.showMessageDialog(contentPane, "登陆成功!");
// 这里调用客户端聊天室窗口

/**
* Launch the application.
*/
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
WindowClientChatRoom frame = new WindowClientChatRoom();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});

/**
* Create the frame.
*/

} catch (Exception e1) {
JOptionPane.showMessageDialog(contentPane, "连接服务器超时!");
}

}

}
});

cencleButton.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
dispose();
}
});
}
}

客户端聊天室界面类:WindowClientChatRoom

package cn.hehewocao_Windows;

import java.awt.EventQueue;
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.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;

import cn.hehewocao_Client.ClientReciveLinkInfoThread;
import cn.hehewocao_Client.ClientReciveThread;

public class WindowClientChatRoom extends JFrame {

private JPanel contentPane;
private JTable friendtable;
private String presendmessage;
public static JTextArea infotextArea;
public static JTextArea inputtextArea;
public static BufferedWriter bw;
public static DefaultTableModel model;

/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
WindowClientChatRoom frame = new WindowClientChatRoom();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Create the frame.
*/
public WindowClientChatRoom() {

setTitle("聊天室");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int width = Toolkit.getDefaultToolkit().getScreenSize().width;
int height = Toolkit.getDefaultToolkit().getScreenSize().height;
setBounds((width - 830) / 2, (height - 600) / 2, 830, 600);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);

infotextArea = new JTextArea();
infotextArea.setBounds(45, 71, 483, 283);
JScrollPane scrollPane_1 = new JScrollPane();
scrollPane_1.setBounds(45, 71, 483, 283);
contentPane.add(scrollPane_1);
scrollPane_1.setViewportView(infotextArea);
//contentPane.add(infotextArea);

JLabel label = new JLabel("消息记录:");
label.setBounds(45, 27, 85, 18);
contentPane.add(label);

JLabel label_1 = new JLabel("在线好友:");
label_1.setBounds(611, 27, 91, 18);
contentPane.add(label_1);

inputtextArea = new JTextArea();
inputtextArea.setBounds(45, 394, 490, 107);
JScrollPane scrollPane_2 = new JScrollPane();
scrollPane_2.setBounds(45, 394, 490, 107);
contentPane.add(scrollPane_2);
scrollPane_2.setViewportView(inputtextArea);
//contentPane.add(inputtextArea);

JButton clearbutton = new JButton("清除");
clearbutton.setBounds(621, 385, 138, 41);
contentPane.add(clearbutton);

JButton sendbutton = new JButton("发送");
sendbutton.setBounds(621, 458, 138, 43);
contentPane.add(sendbutton);

JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(560, 72, 226, 282);
model = new DefaultTableModel();
friendtable = new JTable(model);
scrollPane.setViewportView(friendtable);
contentPane.add(scrollPane);
Socket s = WindowClient.s;

try {
bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bw.write(WindowClient.name + "=" + WindowClient.sex);
bw.newLine();
bw.flush();
} catch (IOException e) {
JOptionPane.showMessageDialog(contentPane, "用户信息发送失败!");
}

addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub
super.windowClosing(e);

try {
bw.write(WindowClient.name + "=Socket is closed!");
bw.flush();
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(null, "服务器已关闭!");
}
}
});
// 开启客户端接收进程
ClientReciveThread crt = new ClientReciveThread(s);
Thread rt = new Thread(crt);
rt.start();

// 开启客户端接收连接信息线程
ClientReciveLinkInfoThread crlit = new ClientReciveLinkInfoThread();
Thread rlit = new Thread(crlit);
rlit.start();

// 发送按钮动作
sendbutton.addActionListener(new ActionListener() {

private BufferedWriter bw = WindowClientChatRoom.bw;

@Override
public void actionPerformed(ActionEvent e) {

try {
String str = inputtextArea.getText().trim();
bw.write(WindowClient.name + "说:" + str);
bw.newLine();
bw.flush();
} catch (IOException e1) {
JOptionPane.showMessageDialog(null, "与服务器的连接断开,您已经被强制下线!");
System.exit(0);
}
inputtextArea.setText("");
}
});

// 清除按钮动作
clearbutton.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
inputtextArea.setText("");
}
});
}
}

服务端启动类:WindowServer

package cn.hehewocao_Windows;

import java.awt.EventQueue;
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.awt.event.WindowListener;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;

import cn.hehewocao_Server.ServerAcceptThread;
import cn.hehewocao_ServerTools.ServerTools;

import java.awt.Color;
import javax.swing.JScrollPane;

public class WindowServer extends JFrame {

private JPanel contentPane;
public static JTable connectTable;
final int port = 8868;
private ServerSocket ss;
private Thread at;

public static DefaultTableModel model;
public static JTextArea infortextArea;
public static JTable table;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
WindowServer frame = new WindowServer();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Create the frame.
*/
public WindowServer() {
setTitle("聊天室服务器");
setResizable(false);
//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int width = Toolkit.getDefaultToolkit().getScreenSize().width;
int height = Toolkit.getDefaultToolkit().getScreenSize().height;

setBounds((width - 900) / 2, (height - 600) / 2, 900, 600);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);

infortextArea = new JTextArea();
infortextArea.setBounds(32, 102, 406, 390);
JScrollPane scrollPane_1 = new JScrollPane();
scrollPane_1.setBounds(32, 102, 406, 390);
contentPane.add(scrollPane_1);
scrollPane_1.setViewportView(infortextArea);
//contentPane.add(infortextArea);

JLabel label = new JLabel("聊天信息");
label.setBounds(195, 78, 72, 18);
contentPane.add(label);

JLabel label_1 = new JLabel("连接信息");
label_1.setBounds(610, 78, 72, 18);
contentPane.add(label_1);

JButton startbutton = new JButton("启动服务器");
startbutton.setBounds(161, 522, 119, 27);
contentPane.add(startbutton);

JButton closebutton = new JButton("关闭服务器");
closebutton.setBounds(576, 522, 119, 27);
contentPane.add(closebutton);

JLabel stateinfolabel = new JLabel("服务器未开启!");
stateinfolabel.setForeground(Color.RED);
stateinfolabel.setBounds(257, 30, 425, 18);
contentPane.add(stateinfolabel);

JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(472, 102, 394, 390);

model = new DefaultTableModel();
table = new JTable(model);
scrollPane.setViewportView(table);
contentPane.add(scrollPane);

addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub
ServerTools.writerFile();
}
});



// 开启服务器按钮动作
startbutton.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {

try {
//ServerSocket ss = new ServerSocket(port);
ss = new ServerSocket(port);
InetAddress addr = InetAddress.getLocalHost();
String hostip = addr.getHostAddress().toString(); // 获取本机IP
stateinfolabel.setText("服务器已开启!服务器IP:" + hostip + " 端口号:" + ss.getLocalPort());
JOptionPane.showMessageDialog(null, "服务器已开启!服务器IP:" + hostip + " 端口号:" + ss.getLocalPort());
// 开启监听客户端连接
ServerAcceptThread sat = new ServerAcceptThread(ss);
//Thread at = new Thread(sat);
at = new Thread(sat);
at.start();
} catch (Exception e1) {
JOptionPane.showMessageDialog(null, "服务器已开启!");
}
}

});

//关闭服务器按钮动作!
closebutton.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
ServerTools.writerFile();
System.exit(0);
}
});
}
}

不足之处:

  1. 由于当时基础学的不扎实,刚开始做的时候存放socket和对应的user时没有选择恰当的数据结构。。。ー( ̄~ ̄)ξ 做了一半才发现应该用map集合的。
  2. 可能是因为端口的问题,导致客户端无法多开,好伤啊,找了半天也不知道如何修改,所以演示的时候只演示了一个客户端,如果想要实现一对多,只能在另一台电脑再运行一个客户端了
  3. 程序编写的不是很清晰,可阅读性还是太差了

总而言之,作为一名初学者,自己掌握的东西还是很缺乏的,希望自己能通过编写一些大一点的项目,增加自己的编程经验,加油! ↖(ω)↗