JavaGUI版聊天室
刚接触Java中的GUI编程和网络编程时觉得很有意思,所以就结合了这两个方面并结合IO、多线程的知识,做了一个GUI版的聊天室。
这个聊天室是两端开发,服务器端和客户端
服务器端功能:
- 开启和关闭服务器
- 总览聊天室内的聊天内容
- 监听连接对象
- 转发给客户端聊天信息
客户端功能:
- 输入基本信息,服务器IP地址和端口号即可连接服务器。
- 查看聊天室和接收聊天室的消息记录
- 查看了聊天室在线成员
- 给服务器发送聊天信息
开发工具:
eclipse、WindowBuilder插件
顺便附上WindowBuilder快速教程:https://www.jianshu.com/p/232f72f55d79
基本思路:
服务器端:由服务器监听连接,每接收到一个连接就创建一个服务端线程,在服务端线程中,一是读取信息文件,并将读取到的信息发送给客户端,二是开启user线程,用于将此用户添加至在线用户的集合中。
客户端:用户登录完成时,与服务器建立连接,并发送用户输入的用户信息,服务端将聊天信息和连接信息发送给客户端,由客户端接送并显示信息。
目录结构:
效果展示:
基本的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);
}
});
}
}
不足之处:
- 由于当时基础学的不扎实,刚开始做的时候存放socket和对应的user时没有选择恰当的数据结构。。。ー( ̄~ ̄)ξ 做了一半才发现应该用map集合的。
- 可能是因为端口的问题,导致客户端无法多开,好伤啊,找了半天也不知道如何修改,所以演示的时候只演示了一个客户端,如果想要实现一对多,只能在另一台电脑再运行一个客户端了。
- 程序编写的不是很清晰,可阅读性还是太差了
总而言之,作为一名初学者,自己掌握的东西还是很缺乏的,希望自己能通过编写一些大一点的项目,增加自己的编程经验,加油! ↖(ω)↗