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集合的。
- 可能是因爲端口的問題,導致客戶端無法多開,好傷啊,找了半天也不知道如何修改,所以演示的時候只演示了一個客戶端,如果想要實現一對多,只能在另一臺電腦再運行一個客戶端了。
- 程序編寫的不是很清晰,可閱讀性還是太差了
總而言之,作爲一名初學者,自己掌握的東西還是很缺乏的,希望自己能通過編寫一些大一點的項目,增加自己的編程經驗,加油! ↖(ω)↗
最後
源碼可以在我的GitHub上下載:[email protected]:hehewocao00544/java.git 中的ChatRoomGUI
或CSDN下載:https://download.csdn.net/download/qq_42080839/11383338
至此就是JavaGUI版的聊天室全部內容。