模拟QQ登录-课后程序(JAVA基础案例教程-黑马程序员编著-第十一章-课后作业)
【案例11-3】 模拟QQ登录
【案例介绍】
1.案例描述
QQ是现实生活中常用的聊天工具,QQ登录界面看似小巧、简单,但其中涉及的内容却很多,对于初学者练习Java Swing工具的使用非常合适。本案例要求使用所学的Java Swing知识,模拟实现一个QQ登录界面。
2.运行结果

运行结果
【案例分析】
(1)首先,需要定义一些成员变量,如最小化、关闭、账号、密码、头像等,方便响应的逻辑实现。
(2)由于需要对账号、密码、头像等进行布局,故需要先对这些对象进行实例化。
(3)在对需要用到的文本框、图片等对象进行实例化过后,可以使用对象.setBounds()设置文本框、图片等组件的位置。
(4)接下来,对最小化、关闭、账号、密码、头像等添加监听事件。同时,对窗体也添加窗体拖动监听事件。
(5)最后,为最小化、关闭等编写点击时的执行逻辑。为账号、密码等设置点击、悬停等执行逻辑。
【案例实现】
Login.java
- package chapter1103;
- import java.awt.Color;
- import java.awt.Cursor;
- import java.awt.Font;
- import java.awt.Point;
- import java.awt.Toolkit;
- import java.awt.event.FocusEvent;
- import java.awt.event.FocusListener;
- import java.awt.event.MouseEvent;
- import java.awt.event.MouseListener;
- import java.awt.event.MouseMotionListener;
- import javax.swing.ImageIcon;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- import javax.swing.JOptionPane;
- import javax.swing.JPanel;
- import javax.swing.JPasswordField;
- import javax.swing.JTextField;
- public class Login extends JFrame implements MouseListener {
- JLabel bacgrangd, jan,bi,QQ,qq,tu;//gif,最小化,关闭,logo,QQ,头像
- JLabel an1, an2, lie1, lie2;// 暗色块|线
- JTextField user;// 账号
- JPasswordField pass;// 密码
- JPanel bgcolor;// 白
- JLabel su1, mi1, ku1, ku2, gou1, gou2;// 缩略图
- JLabel text1, text2, text3, text4, text5;//自动登录,记住密码,找回
- //密码,注册账号,登录
- static Point origin = new Point();// 变量,用于可拖动窗体
- int a = 0, b = 0, c = 0, d = 0;// 控制线
- int f = 0, g = 0, h = 0, j = 0;// 控制√
- JLabel submit, ma;// 背景
- public Login() {
- //实例化
- bacgrangd = new JLabel(new ImageIcon("images/1.gif"));
- jan = new JLabel(new ImageIcon("images/最小化.png"));
- bi = new JLabel(new ImageIcon("images/关闭.png"));
- QQ = new JLabel(new ImageIcon("imagesqq.png"));
- qq = new JLabel("QQ");
- an1 = new JLabel();
- an2 = new JLabel();// 暗调
- tu = new JLabel(new ImageIcon("images/头像.png"));
- user = new JTextField();
- pass = new JPasswordField();
- su1 = new JLabel(new ImageIcon("images/qq (1).png"));
- mi1 = new JLabel(new ImageIcon("images/密码.png"));
- lie1 = new JLabel(new ImageIcon("images/直线2.png"));
- lie2 = new JLabel(new ImageIcon("images/直线2.png"));
- bgcolor = new JPanel();
- ku1 = new JLabel(new ImageIcon("images/框框.png"));
- ku2 = new JLabel(new ImageIcon("images/框框.png"));
- gou1 = new JLabel(new ImageIcon("images/对勾.png"));
- gou2 = new JLabel(new ImageIcon("images/对勾.png"));
- text1 = new JLabel("自动登录");
- text2 = new JLabel("记住密码");
- text3 = new JLabel("找回密码");
- text4 = new JLabel("注册账号");
- text5 = new JLabel("登录");
- submit = new JLabel();
- ma = new JLabel(new ImageIcon("images/二维码.png"));
- //位置
- bacgrangd.setBounds(-35, -123, 500, 250);
- jan.setBounds(364, 2, 32, 32);
- bi.setBounds(396, 3, 32, 32);
- QQ.setBounds(10, 10, 32, 32);
- qq.setBounds(50, 5, 45, 45);
- an1.setBounds(361, 0, 35, 35);
- an2.setBounds(395, 0, 35, 35);
- tu.setBounds(170, 80, 90, 85);
- user.setBounds(130, 160, 180, 40);
- pass.setBounds(130, 200, 180, 40);
- su1.setBounds(100, 170, 20, 20);
- mi1.setBounds(100, 210, 20, 20);
- lie1.setBounds(100, 190, 240, 10);
- lie2.setBounds(100, 230, 240, 10);
- bgcolor.setBounds(0, 125, 500, 300);
- ku1.setBounds(100, 250, 20, 20);
- ku2.setBounds(190, 250, 20, 20);
- gou1.setBounds(106, 255, 10, 10);
- gou2.setBounds(196, 255, 10, 10);
- text1.setBounds(125, 250, 80, 20);
- text2.setBounds(215, 250, 80, 20);
- text3.setBounds(288, 250, 80, 20);
- text4.setBounds(15, 300, 80, 20);
- text5.setBounds(206, 285, 80, 20);
- submit.setBounds(100, 280, 242, 35);
- ma.setBounds(385, 290, 30, 30);
- //属性
- qq.setFont(new Font("微软雅黑", 1, 25));
- qq.setForeground(Color.white);
- an1.setBackground(new Color(0, 0, 0, 0.3f));
- an2.setBackground(new Color(0, 0, 0, 0.3f));
- bgcolor.setBackground(new Color(255, 255, 255));
- user.setForeground(Color.gray);
- user.setText("QQ号码/手机/邮箱");
- user.setOpaque(false);// 透明背景
- user.setBorder(null);// 去掉边框
- // 框内文字样式
- user.setFont(new Font("微软雅黑", Font.PLAIN, 16));
- // 框内文字样式
- pass.setFont(new Font("微软雅黑", Font.PLAIN, 16));
- pass.setBorder(null);// 去掉边框
- pass.setOpaque(false);// 透明背景
- pass.setForeground(Color.gray);
- pass.setText("密码");
- pass.setEchoChar((char) 0);// 让密码显示出来
- text1.setFont(new Font("微软雅黑", 0, 12));
- text2.setFont(new Font("微软雅黑", 0, 12));
- text3.setFont(new Font("微软雅黑", 0, 12));
- text4.setFont(new Font("微软雅黑", 0, 12));
- text5.setFont(new Font("微软雅黑", 0, 15));
- text1.setForeground(new Color(170, 170, 170));
- text2.setForeground(new Color(170, 170, 170));
- text3.setForeground(new Color(170, 170, 170));
- text4.setForeground(new Color(170, 170, 170));
- text5.setForeground(Color.white);
- gou1.setVisible(false);
- gou2.setVisible(false);
- submit.setBackground(new Color(5, 186, 251));
- submit.setOpaque(true);
- text3.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
- text4.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
- //事件区域
- jan.addMouseListener(this);
- bi.addMouseListener(this);
- user.addMouseListener(this);
- pass.addMouseListener(this);
- text1.addMouseListener(this);
- text2.addMouseListener(this);
- text3.addMouseListener(this);
- text4.addMouseListener(this);
- ku1.addMouseListener(this);
- ku2.addMouseListener(this);
- submit.addMouseListener(this);
- ma.addMouseListener(this);
- this.addMouseListener(this);
- // 窗体拖动事件
- this.addMouseMotionListener(new MouseMotionListener() {
- public void mouseMoved(MouseEvent e) {
- }
- public void mouseDragged(MouseEvent e) {
- Point p = getLocation();
- setLocation(p.x + e.getX()-origin.x, p.y + e.getY()-origin.y);
- }
- });
- user.addFocusListener(new FocusListener() {
- public void focusLost(FocusEvent e) {// 失去焦点
- su1.setIcon(new javax.swing.ImageIcon("images/qq (1).png"));
- lie1.setIcon(new javax.swing.ImageIcon("images/直线2.png"));
- c = 0;
- // 判断是否为空(为了设置默认提示语)
- if (user.getText().isEmpty()) {
- user.setForeground(Color.gray);
- user.setText("QQ号码/手机/邮箱");
- }
- }
- // 得到焦点
- public void focusGained(FocusEvent e) {
- user.setForeground(Color.black);
- lie1.setIcon(new javax.swing.ImageIcon("images/直线3.png"));
- a = 1;
- c = 1;
- b = 0;
- su1.setIcon(new javax.swing.ImageIcon("images/qq(2).png"));
- if (user.getText().equals("QQ号码/手机/邮箱")) {
- user.setText("");
- } else {
- user.setText(user.getText());
- user.selectAll();
- }
- }
- });
- pass.addFocusListener(new FocusListener() {
- // 失去焦点
- public void focusLost(FocusEvent e) {
- // 失去焦点换图片
- lie2.setIcon(new javax.swing.ImageIcon("images/直2.png"));
- mi1.setIcon(new javax.swing.ImageIcon("images/密码.png"));
- d = 0;
- if (pass.getText().isEmpty()) {
- pass.setForeground(Color.gray);
- pass.setText("密码");
- pass.setEchoChar((char) 0);// 让密码显示出来
- }
- }
- public void focusGained(FocusEvent e) {// 得到焦点
- mi1.setIcon(new javax.swing.ImageIcon("images/密码"+
- " (1).png"));
- lie2.setIcon(new javax.swing.ImageIcon("images/直线"+
- "3.png"));
- b = 1;
- a = 0;
- d = 1;
- pass.setForeground(Color.black);
- pass.setEchoChar('*');// 让用户输入看不见
- if (pass.getText().equals("密码")) {
- pass.setText("");
- } else {
- pass.setText(pass.getText());
- }
- }
- });
- this.setLayout(null);// 布局
- this.add(jan);
- this.add(bi);
- this.add(qq);
- this.add(QQ);
- this.add(an1);
- this.add(an2);
- this.add(tu);
- this.add(lie1);
- this.add(lie2);
- this.add(user);
- this.add(pass);
- this.add(su1);
- this.add(mi1);
- this.add(gou1);
- this.add(gou2);
- this.add(ku1);
- this.add(ku2);
- this.add(text1);
- this.add(text2);
- this.add(text3);
- this.add(text4);
- this.add(text5);
- this.add(submit);
- this.add(ma);
- this.add(bgcolor);
- this.add(bacgrangd);
- this.setSize(430, 330);
- this.setIconImage(Toolkit.getDefaultToolkit().createImage("images"+
- "/透明照片.png"));// 窗体图标
- this.setLocationRelativeTo(null);// 保持居中
- this.setUndecorated(true);// 去顶部
- this.setFocusable(true);// 面板首先获得焦点
- this.setBackground(new Color(255, 255, 255));// 背景颜色
- this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
- this.setAlwaysOnTop(true);// 最顶层
- this.setVisible(true);// 显示
- }
- public static void main(String[] args) {
- new Login();
- }
- // 点击不恢复
- public void mouseClicked(MouseEvent e) {
- }
- // 点击后
- public void mousePressed(MouseEvent e) {
- if (e.getSource() == jan) {
- setExtendedState(JFrame.ICONIFIED);
- } else if (e.getSource() == this) {
- origin.x = e.getX();
- origin.y = e.getY();
- } else if (e.getSource() == bi) {
- System.exit(0);
- } else if (e.getSource() == ku1 || e.getSource() == text1) {
- if (f == 0) {
- gou1.setVisible(true);
- g = 1;
- f = 1;
- } else if (g == 1) {
- gou1.setVisible(false);
- f = 0;
- g = 0;
- }
- } else if (e.getSource() == ku2 || e.getSource() == text2) {
- if (h == 0) {
- gou2.setVisible(true);
- j = 1;
- h = 1;
- } else if (j == 1) {
- gou2.setVisible(false);
- h = 0;
- j = 0;
- }
- } else if (e.getSource() == submit || e.getSource() == text5) {
- text5.setFont(new Font("微软雅黑", 0, 14));
- dispose();
- String users = user.getText();
- String password = pass.getText();
- if (users.equals("itcast") && password.equals("123")) {
- //new Table();//打开新的主界面如果要关闭登录界面可以写dispose();
- } else {
- JOptionPane.showMessageDialog(null, "用户名:itcast,密"+
- "码:123,您并未设置打开界面!");
- new Login();
- }
- }
- }
- // 点击时
- public void mouseReleased(MouseEvent e) {
- if (e.getSource() == submit || e.getSource() == text5) {
- text5.setFont(new Font("微软雅黑", 0, 15));
- }
- }
- // 悬停
- public void mouseEntered(MouseEvent e) {
- if (e.getSource() == jan) {
- an1.setOpaque(true);
- } else if (e.getSource() == bi) {
- an2.setOpaque(true);
- } else if (e.getSource() == user) {
- if (a == 0 && c == 0) {
- lie1.setIcon(new javax.swing.ImageIcon("images/直线4.png"));
- }
- } else if (e.getSource() == pass) {
- if (b == 0 && d == 0) {
- lie2.setIcon(new javax.swing.ImageIcon("images/直线4.png"));
- }
- } else if (e.getSource() == text3) {
- text3.setForeground(Color.GRAY);
- } else if (e.getSource() == text4) {
- text4.setForeground(Color.GRAY);
- } else if (e.getSource() == ma) {
- ma.setIcon(new javax.swing.ImageIcon("images/二维码2.png"));
- }
- }
- public void mouseExited(MouseEvent e) {// 悬停后
- if (e.getSource() == jan) {
- an1.setOpaque(false);
- } else if (e.getSource() == bi) {
- an2.setOpaque(false);
- } else if (e.getSource() == user) {
- if (a == 0) {
- lie1.setIcon(new javax.swing.ImageIcon("images/直线2.png"));
- }
- } else if (e.getSource() == pass) {
- if (b == 0) {
- lie2.setIcon(new javax.swing.ImageIcon("images/直线2.png"));
- }
- } else if (e.getSource() == text3) {
- text3.setForeground(new Color(170, 170, 170));
- } else if (e.getSource() == text4) {
- text4.setForeground(new Color(170, 170, 170));
- } else if (e.getSource() == ma) {
- ma.setIcon(new javax.swing.ImageIcon("images/二码.png"));
- }
- }
- }
上述代码中,第19-30行代码,定义了一些成员变量,方便响应的逻辑实现。第33-58行代码,对一些图片对象进行实例化。第60-85行,设置图片、文本框等的位置。第87-120行,设置各个文本框,文字等的样式。第122-134行,为各个文本框、按钮等设置监听事件。第136-143行,为窗体拖动事件设置窗体监听。第144-170,为账号文本框设置鼠标聚焦事件。第171-200,为密码文本框设置鼠标聚焦事件。第201-227行,将各个按钮,图片文本框对象放入容器内。第228-238,对界面进行布局。mouseClicked()方法中编写了按钮,文本框,文字等点击不回复的逻辑。mousePressed()方法中编写了按钮,文本框,文字等点击后的逻辑。mouseReleased()方法中编写了按钮,文本框,文字等点击时的逻辑。mouseEntered()方法中编写了按钮,文本框,文字等悬停时的逻辑。mouseExited()方法中编写了按钮,文本框,文字等悬停后的逻辑。
相关文章:
模拟QQ登录-课后程序(JAVA基础案例教程-黑马程序员编著-第十一章-课后作业)
【案例11-3】 模拟QQ登录 【案例介绍】 1.案例描述 QQ是现实生活中常用的聊天工具,QQ登录界面看似小巧、简单,但其中涉及的内容却很多,对于初学者练习Java Swing工具的使用非常合适。本案例要求使用所学的Java Swing知识,模拟实…...
【壹】嵌入式系统硬件基础
随手拍拍💁♂️📷 日期: 2023.2.28 地点: 杭州 介绍: 日子像旋转毒马🐎,在脑海里转不停🤯 🌲🌲🌲🌲🌲 往期回顾 🌲🌲🌲…...
当参数调优无法解决kafka消息积压时可以这么做
今天的议题是:如何快速处理kafka的消息积压 通常的做法有以下几种: 增加消费者数增加 topic 的分区数,从而进一步增加消费者数调整消费者参数,如max.poll.records增加硬件资源 常规手段不是本文的讨论重点或者当上面的手段已经使…...
Java线程池源码分析
Java 线程池的使用,是面试必问的。下面我们来从使用到源码整理一下。 1、构造线程池 通过Executors来构造线程池 1、构造一个固定线程数目的线程池,配置的corePoolSize与maximumPoolSize大小相同, 同时使用了一个无界LinkedBlockingQueue存…...
手撕八大排序(下)
目录 交换排序 冒泡排序: 快速排序 Hoare法 挖坑法 前后指针法【了解即可】 优化 再次优化(插入排序) 迭代法 其他排序 归并排序 计数排序 排序总结 结束了上半章四个较为简单的排序,接下来的难度将会大幅度上升&…...
SAP 详细解析SCC4
事务代码:SCC4,选择一个客户端,点击进入,如图: 一、客户端角色 客户控制:客户的角色(生产性,测试,...) 此属性表示 R/3 系统中的客户端角色。其中可能包括…...
java异常分类和finally代码块中return语句的影响
首先看一下java中异常相关类的继承关系: 引用 1、分类 异常可以分为受查异常和非受查异常,Error和RuntimeException及其所有的子类都是非受查异常,其他的是受查异常。 两者的区别主要在: 受检的异常是由编译器(编译…...
【链表OJ题(二)】链表的中间节点
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:数据结构 🎯长路漫漫浩浩,万事皆有期待 文章目录链表OJ题(二)1. 链表…...
【强烈建议收藏:MySQL面试必问系列之并发事务锁专题】
一.知识回顾 上节课我们一起学习了MySQL面试必问系列之事务,没有学习的同学可以看一下上一篇文章,肯定对你会有帮助,学习过的同学肯定知道,上节课我们留了一个小尾巴,这个小尾巴是什么呢?就是没有详细展开…...
Linux下使用Makefile实现条件编译
在Linux系统下Makefile和C/C语言都有提供条件选择编译的语法,就是在编译源码的时候,可以选择性地编译指定的代码。这种条件选择编译的使用场合有好多,例如我们开发一个兼容标准版本与定制版本兼容的项目,那么,一些与需…...
java 应用cpu飙升(超过100%)故障排查
前言害。。。昨天刚写完一份关于jvm问题排查相关的博客,今天线上项目就遇到了一个突发问题。现象是用户反映系统非常卡,无法操作。然后登录服务器查看发现cpu 一直100%以上。具体排查步骤:1,首先top命令查看服务器cpu等情况&#…...
光学设计软件Ansys的Lumerical 2023版本下载与安装使用
文章目录前言一、许可管理工具安装二、许可管理器配置三、Lumerical安装四、工具使用配置总结前言 Lumerical是一款功能强大的软件,用于设计和分析从组件到系统阶段的光子学和电磁学。这个版本的Lumerical改进了电子和光子学设计工具,用于复杂光子学&am…...
Java 异常
文章目录1. 异常概述2. JVM 的默认处理方案3. 异常处理之 try...catch4. Throwable 的成员方法5. 编译异常和运行异常的区别6. 异常处理之 throws7. 自定义异常8. throws 和 throw 的区别1. 异常概述 异常就是程序出现了不正常的情况。 ① Error:严重问题ÿ…...
JavaSE学习笔记day17
零、 复习昨日 File: 通过路径代表一个文件或目录 方法: 创建型,查找类,判断类,其他 IO 输入& 输出字节&字符 try-catch代码 一、作业 给定路径删除该文件夹 public static void main(String[] args) {deleteDir(new File("E:\\A"));}// 删除文件夹public s…...
【项目】Vue3+TS 动态路由 面包屑 查询重置 列表
💭💭 ✨:【项目】Vue3TS 动态路由 面包屑 查询重置 列表 💟:东非不开森的主页 💜: 热烈的不是青春,而是我们💜💜 🌸: 如有错误或不足之处࿰…...
前脚背完这些接口自动化测试面试题,后脚就进了字节测试岗
1、请结合你熟悉的项目,介绍一下你是怎么做测试的? -首先要自己熟悉项目,熟悉项目的需求、项目组织架构、项目研发接口等 -功能 接口 自动化 性能 是怎么处理的? -第一步: 进行需求分析,需求评审&#…...
termux 安装centos
相关链接 centos官网rootfs制作其他人提供的安装脚本centos镜像列表其他人提供的安装脚本的说明 如果想使用老版本的centos7跟着上面链接5走就行 如果想用新系统比如centos9 stream,就跟我来 Q:为什么要装新系统? A:旧系统太多软件已过时,升级费时费…...
从菜鸟程序员到高级架构师,竟然是因为这个字final
final实现原理 简介 final关键字,实际的含义就一句话,不可改变。什么是不可改变?就是初始化完成之后就不能再做任何的修改,修饰成员变量的时候,成员变量变成一个常数;修饰方法的时候,方法不允…...
【vulhub漏洞复现】CVE-2018-2894 Weblogic任意文件上传漏洞
一、漏洞详情影响版本weblogic 10.3.6.0、weblogic 12.1.3.0、weblogic 12.2.1.2、weblogic 12.2.1.3WebLogic是美国Oracle公司出品的一个application server,确切的说是一个基于JAVAEE架构的中间件,WebLogic是用于开发、集成、部署和管理大型分布式Web应…...
函数栈帧详解
写在前面 这个模块临近C语言的边界,学起来需要一定的时间,不过当我们知道这些知识后,在C语言函数这块我们看到的不仅仅是表象了,可以真正了解函数是怎么调用的。不过我的能力有限,下面的的知识若是不当,还…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
