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

news2024/9/23 17:24:11

文章目录

  • 前言
  • 一、项目设计
    • 1. 模块设计
      • 服务器模块设计
      • 客户端模块设计
    • 2. 实现效果
  • 二、部分源码
  • 项目源码


前言

今天学长向大家分享一个 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");
	}

}

项目源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/98536.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

R语言绘制森林图

在绘制森林图之前当然需要先下载RStudio软件啦&#xff0c;在下载后需要安装对应的rtool,最后将两者关联起来才能使用其中对应的包&#xff0c;否则只安装了软件很多功能不能使用而且还会报错&#xff0c;这篇文章主要是总结怎么使用forestploter包绘制森林图&#xff0c;本来是…

【Linux修炼手册:基本指令(完结)】

Life is about waiting for the right moment to act. 目录 1 zip/unzip指令 2 tar指令&#xff08;重要&#xff09;&#xff1a;打包/解包&#xff0c;不打开它&#xff0c;直接看内容 3 bc指令 4 uname –r指令 5 重要的几个热键[Tab],[ctrl]-c, [ctrl]-d 6 shutdown 7…

智能语音之远场关键词识别实践(二)

上篇&#xff08;智能语音之远场关键词识别实践&#xff08;一&#xff09;&#xff09;讲了“远场关键词识别”项目中后端上的实践。本篇将讲在前端上的一些实践以及将前端和后端连起来形成一个完整的方案。下图是其框图&#xff1a;&#xff08;麦克风阵列为圆阵且有四个麦克…

SpringMVC【学习笔记】

SpringMVC是什么? Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web 框架&#xff0c;即使用了MVC架构模式的思想&#xff0c;将web 层进行职责解耦&#xff0c;基于请求驱动指的就是使用请求-响应模型&#xff0c;框架的目的就是帮助我们简化…

看2022年卡塔尔世界杯有感

一、我印象中第一次看世界杯是2010年南非世界杯 自己第一次踢球是什么时候已经记不清了&#xff0c;大概是小学时候。因为我印象中第一次看世界杯是2010年南非世界杯&#xff0c;因为世界杯主题曲也比较好听&#xff0c;当然&#xff0c;我认为1998年法国世界杯的主题曲最为经…

Python中的魔法方法

python中的魔法方法是一些可以让你对类添加“魔法”的特殊方法,它们经常是两个下划线包围来命名的 Python的魔法方法&#xff0c;也称为dunder(双下划线)方法。大多数的时候&#xff0c;我们将它们用于简单的事情&#xff0c;例如构造函数(init)、字符串表示(str&#xff0c; r…

计算机毕设Python+Vue兴发农家乐服务管理系统(程序+LW+部署)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Linux | 套接字(socket)编程 | UDP协议讲解

文章目录TCP与UDP的区别网络字节序套接字接口介绍sockaddr结构服务端UDP套接字设置客户端UDP套接字设置TCP与UDP的区别 TCPUDP传输层协议传输层协议有连接无连接可靠连接不可靠连接面向字节流面向数据报 首先&#xff0c;网络通信模型是分层的&#xff0c;模型的每一层都有属于…

深入jvm字节码

深入jvm字节码1.深入剖析class文件结构1.1初探class文件1.2 class文件结构解析1.2.1 魔数1.2.2 版本号1.2.3 常量池1.2.4 Access flags1.2.5 this_class,super_name,interfaces1.2.6 字段表1.2.7 方法表1.2.8 属性表1.3使用javap查看类文件2.字节码基础2.1字节码概述2.2java虚拟…

一文看懂---B树及其简单实现

目录 1.B树的引入 2.B树的概念 3.B树是如何插入的&#xff1f; 4.具体的代码实现 1.B树的引入 在以往我们在内存中搜索数据时&#xff0c;可以使用红黑树&#xff0c;平衡树&#xff0c;哈希表等数据结构&#xff0c;但是当数据量比较大&#xff0c;不能一次放进内存&…

[附源码]计算机毕业设计Python仓储综合管理系统(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

C++PrimerPlus 第七章 函数-C++的编程模块-7.9 递归

目录 7.9 递归 7.9.1 包含一个递归调用的递归 7.9.2 包含多个递归调用的递归 7.9 递归 下面介绍一些完全不同的内容。C函数有一种有趣的特点——可以调用自己&#xff08;然而&#xff0c;与C语言不同的是&#xff0c;C不允许main()调用自己&#xff09;&#xff0c;这种功能…

SpringCloud Gateway简单使用

前言 SpringCloud Gateway是一个网关框架&#xff0c;也是现在流行的的一个网关框架&#xff0c;它包括了过滤器、限流、权限、基本路由、整合Eureka 断言predicates 等功能&#xff0c;也会介绍和zuul这个框架的一个对比&#xff0c; Spring Cloud 生态系统中的网关&#xff…

243. 一个简单的整数问题2——差分+树状数组

给定一个长度为 N 的数列 A&#xff0c;以及 M 条指令&#xff0c;每条指令可能是以下两种之一&#xff1a; C l r d&#xff0c;表示把 A[l],A[l1],…,A[r] 都加上 d。 Q l r&#xff0c;表示询问数列中第 l∼r 个数的和。 对于每个询问&#xff0c;输出一个整数表示答案。 …

《爱与自由》豆瓣9.3优秀父母的必读书

《爰和自由》 关于作者 孙瑞雪&#xff0c;中国著名的幼儿教育家与心理学专家&#xff0c;"爱和自由、规则和平等”教育精神的 发起者和倡导者&#xff0c;中国系统引进实施国际蒙特梭利教育第一人&#xff0c;成功实践了科学教育法的本土化。她发展和延伸了蒙特梭利敏感…

Oh My Posh美化CMD、Anaconda Prompt解决方案

网上搜到的Oh My Posh安装配置都是针对power shell的&#xff08;我参考这篇成功配置了针对power shell的字体和主题&#xff09;。期间遇到了无法加载文件WindowsPowerShell\profile.ps1的问题&#xff0c;参考这篇解决。由于平时我用Anaconda比较多&#xff0c;而anaconda是基…

基于ARMR和白噪声特性模型及风速威布尔分布研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

PRISEMI芯导产品推荐 | 支持路径管理功能的3A单节锂离子电池充电IC——PSC2965

PRISEMI芯导产品推荐 | 支持路径管理功能的3A单节锂离子电池充电IC——PSC2965 随着便携式电子设备功能越来越多样化和整机性能的不断提升&#xff0c;整机功耗也在面临越来越大的挑战。最直接有效的方式就是提高电池的容量来提高整机的使用时长。为了不降低用户体验&#xff0…

C# 绘图基础

一 GDI技术简介 ① GDI&#xff1a;Graphics Device Interface. ② GDI&#xff1a;GDI的改进&#xff1b; ③ 是.NET框架结构的重要组成部分&#xff1b; ④ 和GDI一样它提供对二维图形图像的支持&#xff1b; 二 .NET 对GDI的封装 三 坐标系统 GDI的坐标系统&#xff1b; …

计算机毕业设计——简单的网页设计

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 文章目录一、网页介绍一…