JavaGUI版聊天室

JavaGUI版聊天室

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

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

服务器端功能:

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

客户端功能:

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

开发工具:

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);
			}
		});
	}
}

不足之处:

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

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

最后

源码可以在我的GitHub上下载:git@github.com:hehewocao00544/java.git 中的ChatRoomGUI
或CSDN下载:https://download.csdn.net/download/qq_42080839/11383338

至此就是JavaGUI版的聊天室全部内容。

  • 6
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值