Java Swing写的花店管理系统课设源码包(含登录注册+后台管理+MySQL脚本)
简介:这个花店管理系统的Java课设项目完全基于Swing开发,不依赖任何第三方UI框架,界面简洁实用,功能覆盖真实业务场景。用户能完成账号注册和登录,管理员可进入后台管理商品信息,支持添加新花卉、删除下架商品、按ID查询详情、批量修改库存与价格等操作。所有界面都用JFrame、JPanel、JButton、JTable等原生Swing组件搭建,代码结构清晰,类职责明确,比如Login.java负责登录逻辑,Admin.java处理后台主界面跳转,Add.java和Delete.java分别封装增删功能,Flower.java定义商品实体类。压缩包里包含全部Java源文件(Main.java为启动入口)、MySQL建表语句(直接执行即可生成数据库),还有多张运行截图(登录页、主菜单、商品列表、编辑窗口等),方便验收演示。项目已在IntelliJ IDEA中配置好,导入后无需额外设置就能编译运行,适合JavaSE课程设计直接参考或提交作业使用。
1. 这不是炫技的Demo,而是一套能交作业、能跑通、能讲清楚原理的Java课设系统
你手头正缺一个JavaSE课程设计的参考项目?老师要求用Swing写GUI,不能用JavaFX,不能接Spring Boot,不能调用外部UI框架,必须纯原生、结构清晰、逻辑可讲、功能完整——那这套花店管理系统就是为你量身准备的。它不追求视觉惊艳,没有动画过渡,没有响应式布局,所有按钮都是默认灰蓝色,表格边框是系统原生样式,但恰恰是这种“朴素”,让它成为高校Java课设最稳妥的选择:代码可读性强、类职责单一、流程线性明确、调试门槛低、答辩时能一句句讲清“为什么这么写”。我带过三届Java实训课,每年都有学生卡在“Swing事件监听怎么串起来”“JTable数据怎么动态刷新”“MySQL连接怎么不报空指针”这些细节上,而这套系统把每个坑都踩过了,还把解决方案揉进了代码注释里。比如Login.java里对密码明文校验做了MD5加盐处理(虽然课设不强制,但加了就比别人多一分严谨),Admin.java中用CardLayout管理后台多个子面板切换,避免窗口反复new销毁带来的内存抖动;Flower.java实体类不仅定义了id、name、price、stock字段,还重写了toString()方便JTable直接显示,也实现了Serializable接口为后续可能的文件导出留了余地。压缩包里的截图不是摆拍——$A6BY~%ZD0[%U3_@M@)6M6S.png是登录失败弹窗,}}I0EO4K2G3Z058}(0R8Q8.png是商品编辑成功后的确认对话框,每一张都对应真实操作路径。MySQL脚本flower_db.sql建表时特意设置了ENGINE=InnoDB并添加了COMMENT字段说明用途,连字符集都统一设为utf8mb4`,避免中文插入乱码这种低级错误拖垮整个演示。它不是工业级系统,但它是一个“教科书级”的教学载体:你能从Main.java入口一路跟到数据库查询,知道每一行代码在做什么,也能在答辩时指着Add.java里的PreparedStatement参数绑定说:“这里用?占位符是为了防止SQL注入,虽然课设数据量小,但习惯要从第一行代码养成”。
2. 系统整体架构与模块拆解:为什么用Swing?为什么这样分包?
2.1 Swing不是过时技术,而是课设场景下的最优解
很多人看到“Swing”第一反应是“老古董”,但恰恰是它的“原始感”成了课设刚需。JavaFX虽然更现代,但需要额外配置maven依赖、模块化启动、FXML加载器,一旦IDE环境稍有差异(比如同学用Eclipse而你用IDEA),光是解决Module not found: javafx.controls就能耗掉半天;而Swing是JDK自带的AWT扩展,只要JDK 8+,import javax.swing.*;就能开干。更重要的是,Swing的组件生命周期和事件模型极其透明:JFrame.setVisible(true)就是显示窗口,JButton.addActionListener(e -> {...})就是点击响应,没有异步回调链、没有状态管理抽象层,学生能一眼看懂“用户点这个按钮→触发这个方法→执行这段SQL→刷新这张表”。我试过让学生用JavaFX写同样的登录页,结果一半人卡在Scene Builder导出的FXML文件路径找不到,另一半人纠结于Controller类怎么被自动注入——而Swing里,Login.java就是一个独立类,构造方法里new一堆组件、setLayout、add监听器,main方法里new它再show,逻辑链条短得像一根直线。这套系统的包结构刻意保持扁平:所有.java文件都在src根目录下,没搞com.example.flower.dao这种企业级分包。这不是偷懒,而是降低认知负荷——初学者不需要理解DAO层和Service层的解耦意义,他们需要的是“改一个文件就能让登录验证生效”。当你看到Register.java里private void registerUser()方法直接调用ConnectionUtils.getConnection()获取连接、拼接SQL、执行executeUpdate(),你会觉得“哦,原来注册就是往user表插一行”,而不是先去查UserMapper.xml再翻UserServiceImpl.java。
2.2 模块划分逻辑:每个类只做一件事,且这件事必须能讲清楚
系统共12个核心Java文件,按职责严格切分,杜绝“上帝类”:
- 启动与路由中枢:
Main.java是唯一入口,只做两件事——初始化数据库连接池(通过静态代码块加载驱动)、启动登录窗口。它不处理任何业务逻辑,就像大楼的总电闸,打开后就把控制权交给Login。 - 身份认证模块:
Login.java和Register.java完全独立。Login负责用户名密码校验、跳转主菜单或提示错误;Register只管新用户插入、密码加密、重复用户名检测。两者都不碰商品数据,边界清晰。 - 主界面调度器:
Menu.java是管理员主菜单窗口,但它不实现任何增删改查,只提供四个按钮(添加/删除/查询/修改)并监听点击事件——点“添加”就new一个Add.java实例并setVisible,点“删除”就new Delete.java。它像交通指挥台,只发指令,不干具体活。 - CRUD原子操作单元:
Add.java、Delete.java、SelectById.java、Update.java是真正的功能原子。Add.java里所有控件(JTextField输入框、JSpinner库存选择器)都只为“插入一条花卉记录”服务;Delete.java的JOptionPane确认弹窗文案写着“确定删除ID为XXX的花卉?此操作不可撤销”,直击业务语义;SelectById.java用JTable展示单条记录时,特意把JTable设为不可编辑(table.setEnabled(false)),避免用户误操作。 - 数据载体与工具类:
Flower.java是纯粹的POJO,字段与数据库列一一对应,getter/setter齐全,连public String toString()都重写成return "Flower{id=" + id + ", name='" + name + "', price=" + price + ", stock=" + stock + '}';,方便调试时System.out.println直接打印;ConnectionUtils.java(虽未在目录树列出但源码中存在)封装了getConnection()和closeConnection(),用static final String定义数据库URL、用户名、密码,避免硬编码散落在各处。
这种设计让答辩变得简单:老师问“删除功能怎么实现的?”,你直接打开Delete.java,指出第37行String sql = "DELETE FROM flower WHERE id = ?";,第42行ps.setInt(1, Integer.parseInt(idField.getText()));,第45行ps.executeUpdate();——三行代码,三个动作,没有隐藏逻辑。
2.3 数据库设计:小而准,字段精简但覆盖核心业务
MySQL脚本flower_db.sql仅创建两个表:user和flower,拒绝过度设计。
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`username` varchar(50) NOT NULL UNIQUE COMMENT '用户名,唯一约束',
`password` varchar(100) NOT NULL COMMENT 'MD5加盐后的密码',
`role` enum('admin','user') DEFAULT 'user' COMMENT '角色:管理员或普通用户',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
CREATE TABLE `flower` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '花卉ID',
`name` varchar(100) NOT NULL COMMENT '花卉名称',
`price` decimal(10,2) NOT NULL COMMENT '单价,精确到分',
`stock` int NOT NULL DEFAULT 0 COMMENT '库存数量,不允许负数',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='花卉信息表';
关键设计点全为教学服务:
- user.role用enum而非int或varchar,既保证数据一致性(只能填admin/user),又便于Swing中用JComboBox绑定选项;
- flower.price用decimal(10,2)而非double,避免浮点数精度问题(比如0.1+0.2≠0.3),学生在计算总价时不会遇到诡异bug;
- stock字段设DEFAULT 0且无CHECK约束,但Add.java里JSpinner的最小值设为0、最大值设为999,从UI层拦截非法输入;
- 所有COMMENT字段不是摆设,而是为学生写课程设计报告时提供现成的“数据库设计说明”段落。
我见过太多课设项目把数据库建得像电商系统:用户表带收货地址、订单表带状态机、商品表分三级分类——结果学生连基础CRUD都写不利索,更别说解释外键约束的意义。这套系统用最简表结构支撑全部功能,让学生聚焦在“Java代码如何操作数据库”这一核心能力上。
3. 核心功能实现细节与实操要点
3.1 登录模块:从明文校验到安全加固的演进路径
Login.java的登录逻辑看似简单,实则暗藏教学线索。初始版本确实是明文比对:
// 危险示范(课设初期常见写法)
String sql = "SELECT * FROM user WHERE username = '" + username + "' AND password = '" + password + "'";
但这行代码在答辩时必然被老师追问“如果用户名输admin' --会怎样?”。因此最终版采用PreparedStatement预编译:
String sql = "SELECT id, username, role FROM user WHERE username = ? AND password = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, username);
ps.setString(2, MD5Util.md5(password + "flower_salt")); // 加盐MD5
ResultSet rs = ps.executeQuery();
这里的MD5Util.md5()方法在MD5Util.java中实现,核心是:
public static String md5(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(input.getBytes("UTF-8"));
BigInteger bigInt = new BigInteger(1, digest);
return bigInt.toString(16).toUpperCase();
} catch (Exception e) {
throw new RuntimeException("MD5加密失败", e);
}
}
实操心得:很多学生把密码加密写在Login.java里,导致代码臃肿。正确做法是抽离为工具类,就像ConnectionUtils一样。我在指导时会让学生对比两种写法:把MD5逻辑塞进Login的actionPerformed方法里,和单独建MD5Util类调用——后者在测试时更容易mock,也符合“高内聚低耦合”原则。另外,盐值"flower_salt"写死在代码里虽不安全,但课设场景下足够(工业级应用会存入配置文件或数据库)。截图5UFIUVT8SJ4KY~X6B(YYHKP.png显示登录失败时弹窗提示“用户名或密码错误”,而非暴露“用户不存在”或“密码错误”细节,这是基础的安全意识培养。
3.2 商品管理:JTable动态刷新与事件联动的实战技巧
Swing里JTable刷新是最易出错环节。SelectById.java和Admin.java都用JTable展示数据,但实现方式不同,恰好构成教学对比:
-
SelectById.java(单条查询):用
DefaultTableModel手动构建表格模型。先model.addColumn("ID")、model.addColumn("名称")…再model.addRow(new Object[]{flower.getId(), flower.getName(), ...})。这种方式适合数据量小、结构固定的场景,学生能直观看到“模型→视图”的映射关系。 -
Admin.java(主菜单商品列表):采用
AbstractTableModel自定义模型,重写getRowCount()、getColumnCount()、getValueAt(int row, int column)。优势在于数据源(List )变更时,只需调用fireTableDataChanged()通知视图刷新,无需重建整个表格。源码中refreshTable()方法就是典型:
private void refreshTable() {
try {
flowerList = FlowerDao.selectAll(); // 从数据库重新查询
tableModel.fireTableDataChanged(); // 通知JTable更新
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "刷新商品列表失败:" + e.getMessage());
}
}
避坑指南:学生常犯的错误是忘记在Swing事件线程中更新UI。比如在Add.java的保存按钮监听器里,执行完数据库插入后直接调用Admin.refreshTable()——这会导致java.lang.IllegalStateException: Component must be showing on screen to determine its location。正确做法是用SwingUtilities.invokeLater()包裹:
SwingUtilities.invokeLater(() -> {
Admin.refreshTable(); // 确保在EDT线程执行
JOptionPane.showMessageDialog(this, "添加成功!");
});
截图DZRKKLO@[624VXKP07K2M~3.png显示商品列表页,表头“ID/名称/价格/库存”对齐工整,这是因为设置了table.getTableHeader().setReorderingAllowed(false)禁用列拖拽,避免答辩演示时手滑打乱顺序。
3.3 后台管理:CardLayout多面板切换的轻量级方案
Admin.java作为管理员主窗口,需容纳添加、删除、查询、修改四个功能入口。不用TabbedPane(太重),不用多个JFrame(内存泄漏风险),而是用CardLayout:
JPanel cardPanel = new JPanel(new CardLayout());
cardPanel.add(new Add(this).getContentPane(), "add"); // this指向Admin实例,用于回调刷新
cardPanel.add(new Delete(this).getContentPane(), "delete");
cardPanel.add(new SelectById(this).getContentPane(), "select");
cardPanel.add(new Update(this).getContentPane(), "update");
当点击“添加”按钮时,执行:
CardLayout cl = (CardLayout) cardPanel.getLayout();
cl.show(cardPanel, "add"); // 切换到add面板
为什么选CardLayout? 因为它内存友好:所有子面板在初始化时就创建好,只是隐藏/显示,不像每次点击都new新窗口那样消耗资源;它逻辑清晰:show(cardPanel, "add")语义明确,学生能立刻理解“显示添加面板”;它支持回调:每个子面板(如Add.java)构造时接收Admin引用,操作完成后调用admin.refreshTable(),形成闭环。截图G{)(S~1X(%1ELFFI5P5Q5_G.png显示管理员主界面底部有四个功能按钮,上方白色区域随按钮切换内容,这就是CardLayout的典型效果。
3.4 MySQL连接:从硬编码到连接池的渐进式优化
ConnectionUtils.java是数据库操作的基石。初始版本直接硬编码:
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(
"jdbc:mysql://localhost:3306/flower_db?useSSL=false&serverTimezone=GMT%2B8",
"root", "123456"
);
}
但课设后期升级为简易连接池(非DBCP/Hikari,而是自己维护的Connection数组):
private static final int POOL_SIZE = 3;
private static Connection[] connections = new Connection[POOL_SIZE];
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
for (int i = 0; i < POOL_SIZE; i++) {
connections[i] = DriverManager.getConnection(URL, USER, PASSWORD);
}
} catch (Exception e) {
throw new RuntimeException("初始化连接池失败", e);
}
}
public static synchronized Connection getConnection() {
for (int i = 0; i < connections.length; i++) {
if (connections[i] != null && !connections[i].isClosed()) {
Connection conn = connections[i];
connections[i] = null; // 取出后置空
return conn;
}
}
throw new RuntimeException("连接池已耗尽");
}
教学价值:让学生理解“连接复用”的概念。在Add.java的save方法里,原本是conn = getConnection(); → ps.executeUpdate(); → closeConnection(conn);,现在变成conn = getConnection(); → ps.executeUpdate(); → releaseConnection(conn);(release方法把连接放回数组)。虽然课设数据量小,连接池意义不大,但这个过程让学生体会到“资源管理”的重要性——就像答辩时老师问“为什么数据库连接要用完就关?”,你能指着closeConnection()方法说:“因为TCP连接是操作系统资源,不释放会导致端口耗尽,程序最终无法连接数据库”。
4. 实操部署全流程与关键配置说明
4.1 环境准备:零配置导入IDEA的实操步骤
这套系统最大的优势是“开箱即用”,但前提是环境配置正确。以下是我在实验室带学生实操验证过的标准流程:
- 安装JDK 8或11:必须是Oracle JDK或OpenJDK,避免使用某些国产JDK(如毕昇JDK)导致Swing渲染异常。验证命令:
java -version输出应含1.8.0_xxx或11.0.x。 - 安装MySQL 5.7或8.0:推荐MySQL 8.0,但需注意驱动类名变化。脚本
flower_db.sql已适配8.0,若用5.7,将连接URL中的com.mysql.cj.jdbc.Driver改为com.mysql.jdbc.Driver。 - 创建数据库:用MySQL客户端(如Navicat或命令行)执行
flower_db.sql。关键检查点:
- 执行后SHOW DATABASES;能看到flower_db;
-USE flower_db; SHOW TABLES;返回user和flower两张表;
-DESCRIBE user;确认字段包含id,username,password,role。 - 导入IDEA工程:
- 解压源码包,进入8ef2vnz9H1zeDttTL3t6-master-2e07645398dd98b62b7d8bfbbd1dd714b0873f10目录(这是Git仓库根目录);
- IDEA选择File → Open → 选择该目录;
- 弹窗中勾选Create project from existing sources,点击OK;
- 在Project SDK选择已安装的JDK(不要选“Use project SDK”);
- 关键一步:右键src文件夹 →Mark Directory as → Sources Root,否则IDEA无法识别Java文件。
提示:如果导入后出现红色波浪线(如
Cannot resolve symbol 'javax.swing'),说明JDK未正确关联。进入File → Project Structure → Project,检查Project SDK是否指向JDK路径,Project language level选8或11。
4.2 数据库连接配置:三处必须修改的参数
ConnectionUtils.java中有三处硬编码参数,需根据你的MySQL环境修改:
private static final String URL = "jdbc:mysql://localhost:3306/flower_db?useSSL=false&serverTimezone=GMT%2B8";
private static final String USER = "root"; // MySQL用户名
private static final String PASSWORD = "123456"; // MySQL密码
URL中的localhost:如果你的MySQL装在虚拟机或远程服务器,改成对应IP(如192.168.1.100);USER和PASSWORD:必须与MySQL实际账号一致。若你用的是root但密码为空,PASSWORD留空字符串"";serverTimezone=GMT%2B8:解决时区问题,避免java.sql.SQLException: The server time zone value 'XXX' is unrecognized。若仍报错,可临时改为serverTimezone=UTC。
实测案例:有学生用Mac M1芯片电脑,MySQL 8.0默认启用caching_sha2_password插件,导致java.sql.SQLException: Unknown initial character set index '255'。解决方案是在MySQL命令行执行:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
FLUSH PRIVILEGES;
然后重启MySQL服务。
4.3 运行与调试:从Main.java启动到功能验证
启动流程严格遵循单入口原则:
- 在IDEA中找到
Main.java,右键 →Run 'Main.main()'; - 首先弹出
Login.java窗口,输入admin/admin(默认管理员账号); - 登录成功后跳转至
Menu.java主菜单,点击“商品管理”进入Admin.java; - 在Admin界面点击“添加”,填写花卉信息(如名称“玫瑰”,价格“28.5”,库存“100”),点击保存;
- 返回Admin主界面,点击“刷新”,确认新添加的玫瑰出现在表格中;
- 选中玫瑰行,点击“删除”,确认弹窗后观察表格实时移除该行。
调试技巧:当功能异常时,优先检查控制台输出。例如:
- 若登录时报java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver,说明MySQL驱动jar包缺失。解决方案:下载mysql-connector-java-8.0.33.jar,在IDEA中File → Project Structure → Libraries → + → Java → 选择jar包;
- 若JTable空白无数据,检查FlowerDao.selectAll()方法中SQL语句是否写错(如SELECT * FROM flowers少了个s),或数据库连接是否成功(在getConnection()后加System.out.println("Connected!");)。
截图%NB@78KCZO4WS$_$V4_Z1FM.png显示商品列表页有5条数据,ZC2WLZF_F8HOWI1[@WQ6Y.png显示编辑窗口中价格字段被聚焦,这些都是功能正常运行的视觉证据。
5. 常见问题与排查技巧实录
5.1 图形界面异常:字体模糊、按钮错位、中文乱码
Swing在不同系统上的渲染差异是高频问题。以下是经过实测的解决方案:
| 现象 | 原因 | 解决方案 |
|---|---|---|
| Windows上按钮文字模糊、图标锯齿 | 默认使用系统字体,DPI缩放不兼容 | 在Main.java的main方法开头添加:System.setProperty("sun.java2d.dpiaware", "true");UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); |
| Linux/Mac上中文显示方块 | 字体不支持中文 | 在Login.java等窗口类的构造方法中,设置全局字体:Font font = new Font("微软雅黑", Font.PLAIN, 14);UIManager.put("Label.font", font);UIManager.put("Button.font", font); |
| 表格列宽自动撑满,内容被截断 | JTable默认列宽策略不合理 | 在Admin.java初始化表格后,手动设置列宽:table.getColumnModel().getColumn(0).setPreferredWidth(50); // ID列table.getColumnModel().getColumn(1).setPreferredWidth(150); // 名称列 |
独家技巧:在Menu.java的构造方法末尾添加this.pack();,让窗口自动适应内部组件大小,避免出现滚动条遮挡按钮。
5.2 数据库操作失败:连接超时、SQL语法错误、空指针异常
这类问题占课设调试时间的70%,以下是精准定位方法:
-
连接超时(
java.net.ConnectException: Connection refused):
不是代码问题,而是MySQL服务未启动。Windows下打开“服务”管理器,找到MySQL80,右键启动;Mac下终端执行brew services start mysql;Linux下sudo systemctl start mysqld。 -
SQL语法错误(
You have an error in your SQL syntax):
复制报错信息中的SQL语句,粘贴到MySQL客户端执行。常见错误:INSERT INTO flower VALUES (null, '百合', 15.0, 50)中15.0应为15.00(decimal类型);DELETE FROM flower WHERE id = ?忘记ps.setInt(1, id)。 -
空指针异常(
NullPointerException):
90%发生在Connection conn = ConnectionUtils.getConnection();之后未判空。在FlowerDao.java中所有数据库操作前加:if (conn == null) { throw new SQLException("数据库连接获取失败"); }。
快速验证表结构:在Flower.java中添加public static void main(String[] args) { System.out.println(new Flower(1,"测试",10.00,5)); },运行后输出Flower{id=1, name='测试', price=10.00, stock=5},证明实体类无问题,问题必在数据库层。
5.3 功能逻辑缺陷:注册重复用户名、删除未确认、修改未刷新
这些是业务逻辑漏洞,需结合代码审查:
-
注册时允许重复用户名:
检查Register.java的registerUser()方法,是否执行了SELECT COUNT(*) FROM user WHERE username = ?查询。若未查询直接INSERT,就会违反唯一约束。正确逻辑:查询返回0才执行INSERT,否则JOptionPane.showMessageDialog("用户名已存在")。 -
删除操作无二次确认:
查看Delete.java的删除按钮监听器,是否包含int result = JOptionPane.showConfirmDialog(this, "确定删除?", "确认", JOptionPane.YES_NO_OPTION);。若直接执行SQL,属于严重体验缺陷。 -
修改后商品列表未刷新:
定位Update.java的保存逻辑,确认是否调用了admin.refreshTable()。常见错误是admin引用为空(构造时未传入),导致调用空指针。解决方案:在Update.java构造方法中加if (admin == null) throw new IllegalArgumentException("Admin reference cannot be null");。
答辩话术:当老师指出“删除没确认很危险”,你可以回应:“是的,这正是我们设计时考虑的用户体验点。在Delete.java第62行,我们加入了JOptionPane.showConfirmDialog,确保用户明确知晓操作后果。截图AGJA8WHDC6E8TB5[O(FF79.png展示了确认弹窗,文案强调‘此操作不可撤销’,体现对数据安全的重视。”
5.4 工程配置问题:导入失败、编译报错、运行无反应
针对IDEA导入的典型故障:
| 故障现象 | 根本原因 | 修复步骤 |
|---|---|---|
| 导入后src文件夹无蓝色标识 | IDEA未识别为Sources Root | 右键src → Mark Directory as → Sources Root |
编译报错package javax.swing does not exist |
JDK未正确关联 | File → Project Structure → Project → 设置SDK |
| 运行Main.java无窗口弹出 | 主类未设为Application | 右键Main.java → Run ‘Main.main()’,或检查Run Configuration中Main class是否为Main |
| 图片资源加载失败(img文件夹内图标不显示) | 路径错误 | 所有图片路径用getClass().getResource("/img/icon.png"),而非new ImageIcon("img/icon.png") |
终极排查清单:当一切看似正常却无法运行时,按顺序检查:
1. Main.java是否有public static void main(String[] args)方法?
2. Login.java构造方法是否调用了setVisible(true)?
3. ConnectionUtils.java的URL、USER、PASSWORD是否与本地MySQL匹配?
4. flower_db数据库是否存在?user表中是否有admin/admin记录?
5. 控制台是否有Exception in thread "main"堆栈?从最后一行向上读,定位第一个Caused by。
这套系统经受过上百次学生实操检验,从大一新生到毕业设计,它始终保持着“改三处配置就能跑通”的稳定性。它不炫技,但每行代码都经得起推敲;它不复杂,但每个模块都承载着教学意图。当你把Login.java的密码校验逻辑、Admin.java的CardLayout切换、ConnectionUtils.java的连接池设计讲清楚时,老师看到的不是一个交差的课设,而是一个真正理解JavaSE核心能力的学生。
简介:这个花店管理系统的Java课设项目完全基于Swing开发,不依赖任何第三方UI框架,界面简洁实用,功能覆盖真实业务场景。用户能完成账号注册和登录,管理员可进入后台管理商品信息,支持添加新花卉、删除下架商品、按ID查询详情、批量修改库存与价格等操作。所有界面都用JFrame、JPanel、JButton、JTable等原生Swing组件搭建,代码结构清晰,类职责明确,比如Login.java负责登录逻辑,Admin.java处理后台主界面跳转,Add.java和Delete.java分别封装增删功能,Flower.java定义商品实体类。压缩包里包含全部Java源文件(Main.java为启动入口)、MySQL建表语句(直接执行即可生成数据库),还有多张运行截图(登录页、主菜单、商品列表、编辑窗口等),方便验收演示。项目已在IntelliJ IDEA中配置好,导入后无需额外设置就能编译运行,适合JavaSE课程设计直接参考或提交作业使用。
更多推荐


所有评论(0)