毕业设计 - 基于Java的聊天室系统设计与实现【源码+论文】_java聊天室的设计与实现-程序员宅基地

技术标签: 毕业设计  java  web  java web  管理系统  


前言

今天学长向大家分享一个 java 设计项目:

基于Java聊天室系统的设计与实现

一、项目设计

1. 模块设计

在这里插入图片描述
在这里插入图片描述

服务器模块设计

服务端的功能主要如下:

  • 一:能够开启和关闭服务器。
  • 二:等待着客户端从特殊端口发送的请求。
  • 三:监听的端口并不是固定的,服务端的端口是能够自定义的。
  • 四:能够广播消息向所有连接到服务器的用户。

客户端和服务器之间通过socket套接字进行连接,socket的使用在java当中并不复杂,十分的简单。API提供了一个专门的类来处理,让编写程序变得十分简单。多线程的技术在服务器端得到了充分的体现,服务器能够同时处理来自不同IP的客户端的请求。通过循环调用serversocket对象的方法来监听是否有来自客户端的请求。

客户端模块设计

客户端的功能主要如下:

  • 一:能够和服务端进行连接。
  • 二:新的用户能够注册账号。
  • 三:通过用户名以及密码完成用户的登陆,连接到聊天室。
  • 四:用户能够在聊天室发送消息。

客户端通过socket与服务器建立连接。通过java对象的流来进行信息的传递,服务器接受请求返回对象,然后返回给客户端信息。不同的客户端的信息在服务端能够进行不同的处理。

2. 实现效果

服务器界面
在这里插入图片描述
登录界面
在这里插入图片描述

在这里插入图片描述

用户聊天界面
在这里插入图片描述

二、部分源码

部分代码示例:

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import java.util.*;

public class ChatRoom extends Thread implements ActionListener {
    
	static JFrame frmChat;

	JPanel pnlChat;

	JButton btnCls, btnExit, btnSend, btnClear, btnSave;

	JLabel lblUserList, lblUserMessage, lblSendMessage, lblChatUser;

	JLabel lblUserTotal, lblCount, lblBack;

	JTextField txtMessage;

	java.awt.List lstUserList;

	TextArea taUserMessage;

	JComboBox cmbUser;

	JCheckBox chPrivateChat;

	String strServerIp, strLoginName;

	Thread thread;

	final JLabel headLabel = new JLabel();

	Dimension scrnsize;

	Toolkit toolkit = Toolkit.getDefaultToolkit();

	Message messobj = null;

	String serverMessage = "";

	// ���췽��
	public ChatRoom(String name, String ip) {
    
		strServerIp = ip;
		strLoginName = name;
		frmChat = new JFrame("������" + "[�û�:" + name + "]");
		pnlChat = new JPanel();
		frmChat.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmChat.getContentPane().add(pnlChat);

		Font fntDisp1 = new Font("����", Font.PLAIN, 12);

		String list[] = {
     "������" };
		btnCls = new JButton("����");
		btnExit = new JButton("�˳�");
		btnSend = new JButton("����");
		btnSave = new JButton("����");
		lblUserList = new JLabel("�������û��б���");
		lblUserMessage = new JLabel("��������Ϣ��");
		lblSendMessage = new JLabel("��������:");
		lblChatUser = new JLabel("���:");
		lblUserTotal = new JLabel("��������:");
		lblCount = new JLabel("0");
		lstUserList = new java.awt.List();
		txtMessage = new JTextField(170);
		cmbUser = new JComboBox(list);
		cmbUser.addItemListener(new ItemListener() {
    
			public void itemStateChanged(ItemEvent arg0) {
    
				freshHead();
			}
		});
		chPrivateChat = new JCheckBox("˽��");
		taUserMessage = new TextArea("", 300, 200,
				TextArea.SCROLLBARS_VERTICAL_ONLY);// ֻ�����¹���
		taUserMessage.setForeground(new Color(0, 0, 0));
		taUserMessage.setEditable(false); // �����

		pnlChat.setLayout(null);
		pnlChat.setBackground(new Color(52, 130, 203));
		btnSave.setBounds(500, 330, 80, 25);
		btnCls.setBounds(400, 330, 80, 25);
		btnExit.setBounds(500, 360, 80, 25);
		btnSend.setBounds(500, 300, 80, 25);

		lblUserList.setBounds(5, 0, 120, 40);
		lblUserTotal.setBounds(130, 0, 60, 40);
		lblCount.setBounds(190, 0, 60, 40);
		lblUserMessage.setBounds(225, 0, 180, 40);
		lblChatUser.setBounds(10, 290, 40, 40);
		lblSendMessage.setBounds(210, 290, 60, 40);

		lstUserList.setBounds(5, 40, 210, 255);
		taUserMessage.setBounds(225, 40, 360, 255);
		txtMessage.setBounds(270, 300, 210, 25);
		cmbUser.setBounds(50, 300, 80, 25);
		chPrivateChat.setBounds(333, 336, 60, 20);
		btnCls.setFont(fntDisp1);
		btnExit.setFont(fntDisp1);
		btnSend.setFont(fntDisp1);
		btnSave.setFont(fntDisp1);
		lblUserList.setFont(fntDisp1);
		lblUserMessage.setFont(fntDisp1);
		lblChatUser.setFont(fntDisp1);
		lblSendMessage.setFont(fntDisp1);
		lblUserTotal.setFont(fntDisp1);
		lblCount.setFont(fntDisp1);
		cmbUser.setFont(fntDisp1);
		chPrivateChat.setFont(fntDisp1);

		lblUserList.setForeground(Color.YELLOW);
		lblUserMessage.setForeground(Color.YELLOW);
		lblSendMessage.setForeground(Color.black);
		lblChatUser.setForeground(Color.black);
		lblSendMessage.setForeground(Color.black);
		lblUserTotal.setForeground(Color.YELLOW);
		lblCount.setForeground(Color.YELLOW);
		cmbUser.setForeground(Color.black);
		chPrivateChat.setForeground(Color.black);
		lstUserList.setBackground(Color.white);
		taUserMessage.setBackground(Color.white);
		btnCls.setBackground(Color.ORANGE);
		btnExit.setBackground(Color.ORANGE);
		btnSend.setBackground(Color.PINK);
		btnSave.setBackground(Color.ORANGE);
		pnlChat.add(btnCls);
		pnlChat.add(btnExit);
		pnlChat.add(btnSend);
		pnlChat.add(btnSave);
		pnlChat.add(lblUserList);
		pnlChat.add(lblUserMessage);
		pnlChat.add(lblSendMessage);
		pnlChat.add(lblChatUser);
		pnlChat.add(lblUserTotal);
		pnlChat.add(lblCount);
		pnlChat.add(lstUserList);
		pnlChat.add(taUserMessage);
		pnlChat.add(txtMessage);
		pnlChat.add(cmbUser);
		pnlChat.add(chPrivateChat);

		frmChat.addWindowListener(new Windowclose());
		btnCls.addActionListener(this);
		btnExit.addActionListener(this);
		btnSend.addActionListener(this);
		btnSave.addActionListener(this);
		lstUserList.addActionListener(this);
		txtMessage.addActionListener(this);

		headLabel.setHorizontalAlignment(SwingConstants.CENTER);
		headLabel.setIcon(new ImageIcon("face//1.JPG"));
		headLabel.setBounds(15, 335, 70, 60);
		pnlChat.add(headLabel);

		// ��������ҳ����Ϣˢ���߳�
		Thread thread = new Thread(this);
		thread.start();

		frmChat.setSize(600, 420);
		frmChat.setVisible(true);
		frmChat.setResizable(false);

		// �����ڶ�λ����Ļ����
		scrnsize = toolkit.getScreenSize();
		frmChat.setLocation(scrnsize.width / 2 - frmChat.getWidth() / 2,
				scrnsize.height / 2 - frmChat.getHeight() / 2);
		Image img = toolkit.getImage("images\\appico.jpg");
		frmChat.setIconImage(img);

	} // ���췽������

	@SuppressWarnings("deprecation")
	public void run() {
    
		int intMessageCounter = 0;
		int intUserTotal = 0;
		boolean isFirstLogin = true; // �ж��Ƿ�յ�½
		boolean isFound; // �ж��Ƿ��ҵ��û�
		Vector user_exit = new Vector();

		try {
    
			for (;;) {
    
				Socket toServer;
				toServer = new Socket(strServerIp, 1001);
				// ����Ϣ����������
				messobj = new Message();
				ObjectOutputStream streamtoserver = new ObjectOutputStream(
						toServer.getOutputStream());
				streamtoserver.writeObject((Message) messobj);
				// �����Է���������Ϣ
				ObjectInputStream streamfromserver = new ObjectInputStream(
						toServer.getInputStream());
				messobj = (Message) streamfromserver.readObject();
				// //ˢ��������Ϣ�б�//
				if (isFirstLogin) // ����յ�½
				{
    
					intMessageCounter = messobj.chat.size(); // ���θ��û���½ǰ����������
					isFirstLogin = false;
				}
				if (!serverMessage.equals(messobj.serverMessage)) {
    
					serverMessage = messobj.serverMessage;
					taUserMessage.append("[ϵͳ��Ϣ]��" + serverMessage+"\n");
				}
				for (int i = intMessageCounter; i < messobj.chat.size(); i++) {
    
					Chat temp = (Chat) messobj.chat.elementAt(i);

					String temp_message;
					if (temp.chatUser.equals(strLoginName)) {
    
						if (temp.chatToUser.equals(strLoginName)) {
    
							temp_message = "ϵͳ��ʾ�����벻Ҫ�������" + "\n";
						} else {
    
							if (!temp.whisper) // �������Ļ�
							{
    
								temp_message = "���㡿�ԡ�" + temp.chatToUser + "��"
										+ "˵��" + temp.chatMessage
										+ "\n";
							} else {
    
								temp_message = "���㡿���Ķԡ�" + temp.chatToUser
										+ "��" + "˵��" + temp.chatMessage
										+ "\n";
							}
						}
					} else {
    
						if (temp.chatToUser.equals(strLoginName)) {
    
							if (!temp.whisper) // �������Ļ�
							{
    
								temp_message = "��" + temp.chatUser + "���ԡ��㡿"
										+ "˵��" + temp.chatMessage
										+ "\n";
							} else {
    
								temp_message = "��" + temp.chatUser + "�����Ķԡ��㡿"
										+ "˵��" + temp.chatMessage
										+ "\n";
							}
						} else {
    
							if (!temp.chatUser.equals(temp.chatToUser)) // �Է�û����������
							{
    
								if (!temp.whisper) // �������Ļ�
								{
    
									temp_message = "��" + temp.chatUser + "���ԡ�"
											+ temp.chatToUser + "��"
											+ "˵��" + temp.chatMessage + "\n";
								} else {
    
									temp_message = "";
								}
							} else {
    
								temp_message = "";
							}
						}
					}
					taUserMessage.append(temp_message);
					intMessageCounter++;
				}

				// //ˢ�������û�//
				lstUserList.clear();
				for (int i = 0; i < messobj.userOnLine.size(); i++) {
    
					String User = ((Customer) messobj.userOnLine.elementAt(i)).custName;
					lstUserList.addItem(User);
				}
				Integer a = new Integer(messobj.userOnLine.size());
				lblCount.setText(a.toString());
				// ��ʾ�û����������ҵ���Ϣ
				if (messobj.userOnLine.size() > intUserTotal) {
    
					String tempstr = ((Customer) messobj.userOnLine
							.elementAt(messobj.userOnLine.size() - 1)).custName;
					if (!tempstr.equals(strLoginName)) {
    
						taUserMessage.append("��" + tempstr + "������" + "\n");
					}
				}
				if (messobj.userOnLine.size() < intUserTotal) {
    
					for (int b = 0; b < user_exit.size(); b++) {
    
						isFound = false;
						for (int c = 0; c < messobj.userOnLine.size(); c++) {
    
							String tempstr = ((Customer) user_exit.elementAt(b)).custName;

							if (tempstr.equals(((Customer) messobj.userOnLine
									.elementAt(c)).custName)) {
    
								isFound = true;
								break;
							}
						}
						if (!isFound) // û�з��ָ��û�
						{
    
							String tempstr = ((Customer) user_exit.elementAt(b)).custName;

							if (!tempstr.equals(strLoginName)) {
    
								taUserMessage.append("��" + tempstr + "������"
										+ "\n");
							}
						}
					}
				}
				user_exit = messobj.userOnLine;
				intUserTotal = messobj.userOnLine.size();
				streamtoserver.close();
				streamfromserver.close();
				toServer.close();
				Thread.sleep(3000);
			}

		} catch (Exception e) {
    
			@SuppressWarnings("unused")
			JOptionPane jop = new JOptionPane();
			JOptionPane.showMessageDialog(null, "�������ӷ�������");
			e.printStackTrace();
			frmChat.dispose();
		}

	} // run()����

	private void exitChatRoom() {
    
		exit();
	}

	// /������ť��Ӧ//
	public void actionPerformed(ActionEvent ae) {
    
		Object source = (Object) ae.getSource();
		if (source.equals(btnCls)) {
    
			clearMessage();
		}
		if (source.equals(btnExit)) {
    
			exit();
		}
		if (source.equals(btnSend)) {
    
			sendMessage();
		}
		if (source.equals(btnSave)) {
    
			saveMessage();
		}
		if (source.equals(lstUserList)) // ˫���б���
		{
    
			changeUser();
		}
	} // actionPerformed()����

	// /�������ڹر���Ӧ//
	class Windowclose extends WindowAdapter {
    
		public void windowClosing(WindowEvent e) {
    
			exit();
		}
	}

	// "����"��ť
	public void clearMessage() {
    
		taUserMessage.setText("");
	}

	// "�˳�"��ť
	public void exit() {
    
		Exit exit = new Exit();
		exit.exitname = strLoginName;
		// �����˳���Ϣ
		try {
    
			Socket toServer = new Socket(strServerIp, 1001);
			// �������������Ϣ
			ObjectOutputStream outObj = new ObjectOutputStream(toServer
					.getOutputStream());
			outObj.writeObject(exit);
			outObj.close();
			toServer.close();

			frmChat.dispose();
		} catch (Exception e) {
    
		}

	} // exit()����

	// "����"��ť
	public void sendMessage() {
    
		Chat chatobj = new Chat();
		chatobj.chatUser = strLoginName;
		chatobj.chatMessage = txtMessage.getText();
		chatobj.chatToUser = String.valueOf(cmbUser.getSelectedItem());
		chatobj.whisper = chPrivateChat.isSelected() ? true : false;
		try {
    
			Socket toServer = new Socket(strServerIp, 1001);
			ObjectOutputStream outObj = new ObjectOutputStream(toServer
					.getOutputStream());
			outObj.writeObject(chatobj);
			txtMessage.setText(""); // ����ı���
			outObj.close();
			toServer.close();
		} catch (Exception e) {
    
		}
	}

	// "����"��ť
	public void saveMessage() {
    
		try {
    
			FileOutputStream fileoutput = new FileOutputStream(
					this.strLoginName + "_message.txt", true);
			String temp = taUserMessage.getText();
			fileoutput.write(temp.getBytes());
			fileoutput.close();
			JOptionPane.showMessageDialog(null, "�����¼������" + this.strLoginName
					+ "_message.txt");
		} catch (Exception e) {
    
			System.out.println(e);
		}

	}

	// ����ѡ�û����ӵ�cmbUser��
	public void changeUser() {
    

		boolean key = true;
		String selected = lstUserList.getSelectedItem();
		for (int i = 0; i < cmbUser.getItemCount(); i++) {
    
			if (selected.equals(cmbUser.getItemAt(i))) {
    
				key = false;
				break;
			}
		}
		if (key == true) {
    
			cmbUser.insertItemAt(selected, 0);
		}
		String head = getUserHead(lstUserList.getSelectedItem());
		cmbUser.setSelectedItem(selected);

		headLabel.setIcon(new ImageIcon("face//" + head + ".JPG"));
	}

	protected void freshHead() {
    
		String head = getUserHead(cmbUser.getSelectedItem().toString());
		headLabel.setIcon(new ImageIcon("face//" + head + ".JPG"));
	}

	private String getUserHead(String selectedItem) {
    
		String head = "oo";
		for (int i = 0; i < messobj.userOnLine.size(); i++) {
    
			String User = ((Customer) messobj.userOnLine.elementAt(i)).custName;
			head = ((Customer) messobj.userOnLine.elementAt(i)).custHead;
			if (User.equals(selectedItem)) {
    
				break;
			}
		}
		return head;
	}

	public static void main(String args[]) {
    
		new ChatRoom("�����û�", "127.0.0.1");
	}

}

项目源码

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/WEB_DC/article/details/125367767

智能推荐

JSX的基本使用_jsx 在什么环境中运行-程序员宅基地

文章浏览阅读577次。简介JSX是JavaScript XML的简写,表示在JavaScript代码中写XML格式的代码优点:声明式语法更加直观、与HTML结构相同,降低了学习成本,提升开发效率。为什么脚手架中可以使用JSX语法?1.JSX不是标准的ECMAScript语法,它是ECMASeript的语法拓展。2.需要使用babel编译处理后,才能在浏览器环境中使用3.create-react-app 脚手架中已经默认有该配置使用步骤1.使用JSX语法创建react元素const title_jsx 在什么环境中运行

Spring中Bean的生命周期详解_spring bean加载过程(简述bean的生命周期)-程序员宅基地

文章浏览阅读135次。Spring中Bean的生命周期详解Spring最重要的功能就是帮助程序员创建对象(也就是IOC),而启动Spring就是为创建Bean对象做准备,所以我们先明白Spring到底是怎么去创建Bean的,也就是先弄明白Bean的生命周期。Bean的生命周期就是指:在Spring中,一个Bean是如何生成的,如何销毁的?..._spring bean加载过程(简述bean的生命周期)

ps新手秒变大师必备的Ps插件全在这!(mac版本)_delicious retouch 5 mac-程序员宅基地

文章浏览阅读3k次。作为设计师Photoshop可谓神器,不论你是何种设计师多多少少都会用到它。随着时代的发展,对效率越来越注重,ps虽功能强大,但不是大神级别的炉火纯青,用起来还是比较浪费时间的,这是设计公司永远不会说的秘密。 今天专为使用Mac的同学们带来的是10款必备常用ps扩展插件合集!美工修图必备!1.Delicious Retouch 5.0 (DR5)白金版Delicious Retouch5 白金版 for mac(PS磨皮插件DR5)立即下载Delicious Retouch5 白金版 for mac_delicious retouch 5 mac

如何将图像从 React Native 上传到 Laravel API_react native launchimagelibrary 如何上传图片-程序员宅基地

文章浏览阅读410次。聚优影视TV双播盒子,内置多个资源接口,开源TVBOX制作!如今,开发人员同时处理前端和后端项目是很常见的。根据最近的一项开发人员调查,React Native 是全球最流行的用于构建跨平台移动应用程序的框架之一。Laravel 是一个 PHP Web 框架,具有优雅的代码结构,开发人员可以使用它来创建 REST API。Laravel 目前有71k 的 GitHub 星数,证明了它在开发者社区中的受欢迎程度。_react native launchimagelibrary 如何上传图片

sql函数--05---SQL----coalesce函数详解_sql coalesce-程序员宅基地

文章浏览阅读1.8k次,点赞4次,收藏5次。提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录coalesce函数背景:语法:COALESCE ( expression,value1,value2……,valuen)流程:举例:应用 1 :进行空值处理查询学生成绩,如果查不到,则赋值为0应用 2 :进行默认处理返回人员的“重要日期”if( , ,)函数也可以coalesce函数背景:主流数据库系统都支持COALESCE()函数, MYSQL、MSSQLServer、DB2、Oracle:这个函数主要用来进行空值处_sql coalesce

vue项目中 实现复制功能_vue 复制dom元素-程序员宅基地

文章浏览阅读1.5k次。vue使用插件vue 可使用 vue-clipboard 插件npm i vue-clipboard2 -S 安装插件在main.js 中引入import VueClipboard from ‘vue-clipboard2’Vue.use(VueClipboard)<el-input v-model="input" size="mini" placeholder="请输入内容"></el-input><el-button type="text" icon="_vue 复制dom元素

随便推点

轻轻松松制作与众不同的黑白照片_黑白照片自动生成-程序员宅基地

文章浏览阅读279次。无论摄影技术如何发展,黑白照片都能保持它独特的吸引力,但如果你亲手试过把彩色照片直接调成黑白照片,那你想必会发现,转换后的效果好像就是差了一点。不用担心,今天小编给大家推荐三款好用的黑白照片处理软件,操作简单,功能实用,让你轻轻松松就制作与众不同的黑白照片,快跟着小编一起来看看吧~1.PhotosRevive for mac(黑白照着色工具)PhotosRevive for mac(黑白照着色工具)立即下载PhotosRevive for mac(黑白照着色工具)Mac哪款黑白照着色工具好用呢?_黑白照片自动生成

LeetCode刷题Python Day1 Q35:搜索插入位置-程序员宅基地

文章浏览阅读96次。题目如下:35. 搜索插入位置难度简单1029收藏分享切换为英文接收动态反馈给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为O(log n)的算法。示例 1:输入: nums = [1,3,5,6], target = 5输出: 2示例2:输入: nums = [1,3,5,6], target = 2输出: 1示例 3:输入: nums = [1,3...

oracle 存储过程 带游标作为OUT参数输出_oracle存储过程 行变量入参-程序员宅基地

文章浏览阅读9.2k次。包中带过程 要自己定义一个type [cur_name] is ref cursor游标,返回的时候就直接 procedure AAA(变量名 out [cur_name])如此申明OUT变量 存储过程 用系统默认的 sys_refcursor 游标类型 定义变量就OK了 Sql代码 --PL/SQL Code (包中带过程) 过程带游标的OUT参数,返回游标(ref curs_oracle存储过程 行变量入参

AES-NI指令集-程序员宅基地

文章浏览阅读1.6k次。对于intel的AES-NI新指令集,需要i5处理器及以上的相关硬件支持.在编译时,可能会出现/usr/lib/gcc/x86_64-linux-gnu/4.8/include/wmmintrin.h:34:3: error: #error "AES/PCLMUL instructions not enabled"很显然,可以通过查其头文件,定位到#if !defined (__AES..._aes-ni指令集的下载与使用

Bug基础-程序员宅基地

文章浏览阅读131次。1.缺陷报告的定义软件不正常的错误或者是代码行错误等均衡成为缺陷2.缺陷的种类:功能不正常软件在使用上感觉不方便软件的结构未做良好规划提供的功能不充分与软件操作者的互动不良使用性能不佳未做好错误处理边界错误计算错误使用一段时间所产生的错误控制流程的错误在大数据量压力下所产生的错误在不同硬件环境下产生的错误版本控制不良导致的错误软件文档的错误3.将缺陷按照严重程度划分系统崩溃,严重,一般,次要,建议4.解决bug的优先级高,中,低5.按照测试种类分:逻辑功能类性_bug基础

macOS高端使用技巧_mac指标高级运用?-程序员宅基地

文章浏览阅读185次。Macos 的占有量不如 Windows,两者之间当操作方式也有很大的不同,当很多人熱悉 Windows 的操作之后,再接触 macos,觉得难上手,其实是习惯问题。如果你学习一些技巧,会觉得 macos 其实也不错,某些方面,甚至远远优于 Windows。很多人说 macos 这效率上会优于 Windows,这点必须承认,毕竟 macos 包括其平台下的软件,有很多的快捷键,并且感觉苹果也有意让大家多多利用快捷键。那么多的快捷键,并且 control 和 command 在使用上,没有一定的规律可循,导_mac指标高级运用?

推荐文章

热门文章

相关标签