大约 9 分钟
1. 报表模块
1.1 报表模块数据库设计和可视化组件介绍
前言
JFreeChart 简介
JFreeChart 是一款开源的 Java 图表库,用于在 Java 应用程序中生成各种高质量的 2D 图表,支持 Swing、JavaFX、Web 等多种环境,是 Java 领域最流行的图表工具之一。
核心特点:
- 丰富的图表类型:支持折线图、柱状图、饼图、散点图、甘特图、雷达图等 30+ 常用图表,满足数据统计与可视化需求。
- 跨平台兼容:纯 Java 编写,可在 Windows、Mac、Linux 等系统运行,无缝集成 Swing/JavaFX 桌面应用。
- 高度可定制:支持自定义颜色、字体、标签、图例、动画效果,可调整图表细节以匹配 UI 风格(如苹果简洁风)。
- 轻量易用:API 设计简洁,通过少量代码即可生成图表,支持数据动态更新(如实时数据刷新)。
典型应用场景:
- 桌面应用数据报表(如本文的 Swing 报表模块);
- Web 应用图表生成(通过 servlet 输出图片);
- 数据分析工具的结果可视化。
优势与局限:
- 优势:开源免费、文档丰富、社区活跃,适合快速开发桌面/Web 图表功能。
- 局限:3D 图表效果较基础,复杂交互(如拖拽、缩放)需额外开发,性能在超大数据量下略逊于专业可视化库(如 ECharts)。
总之,JFreeChart 是 Java 开发中快速实现数据可视化的实用工具,尤其适合中小型项目的报表模块开发。
如何导入到项目中?
在项目的pom.xml文件中添加依赖后,点击右上角的刷新按钮,等待依赖下载完成即可(由红变黑)。
<!-- JFreeChart图表库 -->
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.5.3</version>
</dependency>

报表页面的数据,来自用户表,分类表,药品表,库存表,和库存流水表。因此不需要创建新的表,只需要通过多表查询,获取到需要的数据即可。
1.2 报表模块UI页面设计
前言
页面提示词如下:
报表模块ReportUI.java开发提示词(最终版)
一、项目环境
• 所属模块:HomeUI.java 内容区嵌入的子界面(通过侧边栏“报表中心”菜单切换显示);
• 技术:Java Swing,风格与现有界面(UserUI、WelcomeUI、HomeUI)一致;
• 数据依赖:需加载统计数据(模拟从数据库查询,返回Map格式数据,对应 t_user、t_category、t_medicine、t_inventory 表);
• 图表依赖:使用 JFreeChart 组件实现饼图、柱状图可视化;
• 刷新机制:仅在页面初始化时加载一次数据,无定时刷新,无手动刷新按钮(后续可扩展)。
二、界面设计(苹果风格:简洁、留白、色调统一、控件圆润)
1. 整体布局
采用 BorderLayout + GridBagLayout + 边距控制,分区明确:
• 顶部:标题区(居中显示报表标题);
• 第一行:统计卡片区(3个文字卡片,展示核心指标);
• 第二行:分类药品数量饼图区(占满该行空间);
• 第三行:药品库存量柱状图区(占满该行空间);
• 整体背景白色,四周留白舒适(如 EmptyBorder(15, 15, 15, 15)),图表区内部留白 EmptyBorder(10, 10, 10, 10)。
• 三行用滑动组件(JScrollPane)包裹,保证高度不超出屏幕。且每行的大小设置合理,刚好能显示到一个页面。且JFreeChart默认使用支持中文的字体
2. 标题区(顶部)
• 标题文本:文字“数据报表中心”,居中显示;
• 样式:字体“微软雅黑”,字号 20px,加粗,颜色 #333333;
• 布局:FlowLayout.CENTER,高度约 60px(含内边距),背景白色,无边框。
3. 统计卡片区(第一行)
• 布局:GridLayout(1, 3, 15, 0)(1行3列,卡片间距15px),占满该行宽度;
• 卡片样式(单个卡片):
• 尺寸:宽度自适应,高度 120px;
• 边框:CompoundBorder(LineBorder(#E0E0E0, 1), EmptyBorder(15, 15, 15, 15))(浅灰细边框+内边距);
• 背景:白色,圆角矩形(通过 setBorder 模拟);
• 内容排版(BorderLayout):
◦ 北:标题(如“用户总数”),字体“微软雅黑”,字号 14px,颜色 #666666,加粗;
◦ 中:数值(如“128”),字体“微软雅黑”,字号 28px,颜色 #007AFF(主题蓝),加粗,居中;
◦ 南:描述(如“系统注册用户总数”),字体“微软雅黑”,字号 12px,颜色 #999999,居中。
4. 饼图区(第二行)
• 布局:占满该行空间(BorderLayout.CENTER),高度约 350px;
• 标题:顶部居中显示“各分类药品数量分布”,字体“微软雅黑”,字号 16px,颜色 #333333,加粗,与图表间距 10px;
• 图表容器:ChartPanel(JFreeChart 图表面板),背景白色,无边框,图表边距 TOP/BOTTOM 20px, LEFT/RIGHT 20px;
• 饼图样式:
• 扇区颜色:分类1(西药)→ #4ECDC4(青绿色)、分类2(中药)→ #45B7D1(蓝色)、分类3(生物制品)→ #96CEB4(浅绿)、分类4(医疗器械)→ #FFEEAD(浅黄)、分类5(其他)→ #FF6B6B(红色);
• 标签:显示“分类名称: 数量(占比%)”,字体“微软雅黑”,字号 12px,颜色 #333333;
• 图例:右侧显示,字体“微软雅黑”,字号 12px,颜色 #666666。
5. 柱状图区(第三行)
• 布局:占满该行空间(BorderLayout.CENTER),高度约 400px;
• 标题:顶部居中显示“药品库存量 TOP10”,字体“微软雅黑”,字号 16px,颜色 #333333,加粗,与图表间距 10px;
• 图表容器:ChartPanel,背景白色,无边框,图表边距 TOP/BOTTOM 20px, LEFT/RIGHT 20px;
• 柱状图样式:
• X轴:药品名称(显示前6个字符,超出省略),字体“微软雅黑”,字号 11px,颜色 #666666;
• Y轴:库存数量,字体“微软雅黑”,字号 12px,颜色 #666666;
• 柱形颜色:#5CB85C(绿色),悬停时加深为 #449D44;
• 网格线:浅灰色虚线(Color.LIGHT_GRAY,Stroke.DASHED),仅显示横向网格线。
三、交互与逻辑
1. 数据加载(仅初始化时加载一次)
• 定义独立方法(返回 Map 数据,构造函数中调用一次):
• loadStatCards():返回 Map<String, String>,包含3个键值对:{"userCount":"128", "categoryCount":"5", "medicineCount":"30"}(键为指标标识,值为显示文本);
• loadCategoryMedicineData():返回 Map<String, Integer>,键为分类名称(如“西药”“中药”),值为药品数量(如 {"西药":12, "中药":8, "生物制品":3, "医疗器械":4, "其他":3});
• loadMedicineInventoryData():返回 Map<String, Integer>,键为药品名称(如“阿莫西林胶囊”),值为库存量(如 {"阿莫西林胶囊":120, "板蓝根颗粒":130, "头孢拉定胶囊":150, ...},取前10条);
• 页面初始化:构造函数中依次调用上述3个方法,获取Map数据后解析并刷新对应组件(卡片、饼图、柱状图),之后不再自动刷新。
2. 组件初始化
• 统计卡片初始化:initStatCardsPanel(Map<String, String> cards)
• 创建 StatCardsPanel(自定义面板,内部用 GridLayout 排列3个卡片);
• 从Map提取 userCount、categoryCount、medicineCount 的值,设置到3个卡片的数值标签;
• 饼图初始化:initPieChart(Map<String, Integer> data)
• 创建 DefaultPieDataset,遍历Map将键值对添加到数据集(dataset.setValue(分类名称, 数量));
• 调用 ChartFactory.createPieChart() 生成图表,设置标题、图例、标签格式;
• 创建 ChartPanel 并设置样式,添加到饼图区;
• 柱状图初始化:initBarChart(Map<String, Integer> data)
• 创建 DefaultCategoryDataset,遍历Map将键值对添加到数据集(dataset.addValue(库存量, "库存量", 药品名称));
• 调用 ChartFactory.createBarChart() 生成图表,设置标题、坐标轴、柱形样式;
• 创建 ChartPanel 并设置样式,添加到柱状图区。
3. 独立方法定义
• initStatCardsPanel(Map<String, String> cards):初始化统计卡片面板;
• initPieChart(Map<String, Integer> data):初始化饼图;
• initBarChart(Map<String, Integer> data):初始化柱状图;
• loadStatCards():返回 Map<String, String>(用户数、分类数、药品数);
• loadCategoryMedicineData():返回 Map<String, Integer>(分类名称→药品数量);
• loadMedicineInventoryData():返回 Map<String, Integer>(药品名称→库存量)。
四、风格一致性
• 色调:主色 #007AFF(卡片数值)、辅助色 #4ECDC4/#45B7D1(图表扇区/柱形)、背景色 #FFFFFF(整体)、文字色 #333333(标题)/ #666666(表头/描述)/ #999999(辅助文字)、边框色 #E0E0E0(浅灰细边框);
• 字体:全局使用“微软雅黑”(Windows)/“苹方”(Mac),标题字号 20px(加粗),卡片标题 14px(加粗),卡片数值 28px(加粗),卡片描述/图表标签 12px(常规);
• 与现有界面统一:按钮样式、对话框风格、背景色与 HomeUI 侧边栏、UserUI 输入框保持一致,图表边框与表格边框风格统一(浅灰细边框)。
五、输出要求
1. 提供 ReportUI.java 完整可运行代码(含 import、成员变量、构造方法、界面初始化、数据加载逻辑);
2. 代码注释清晰:说明各区域作用(如“统计卡片区”“饼图区”)、主要方法逻辑(如 loadStatCards() 数据模拟流程、initPieChart() 图表构建步骤);
3. 独立方法定义:严格按照“核心方法逻辑”中实现(含示例代码);
4. 暂不实现真实数据库查询(用硬编码Map模拟数据),但保留 DAO 层接口注释,便于后续对接 MyBatis;
5. 图表支持鼠标交互(如饼图扇区悬停显示详情、柱状图柱形悬停高亮),并在控制台输出交互日志(如“鼠标悬停饼图扇区:西药,数量12”);
6. 核心操作输出 System.out.println() 日志(如数据加载、交互事件),异常时输出 ex.printStackTrace();
7. 代码符合 JavaSE Swing 开发规范,界面适配主流分辨率(1366×768及以上),图表自动缩放适应面板大小;
8. 无定时刷新逻辑(删除所有 Timer 相关代码)。
目标:符合 JavaSE Swing 开发规范,界面美观(苹果风格)、数据可视化清晰,交互流畅,数据与界面分离,便于后续扩展真实数据对接(MyBatis)和业务逻辑。
将提示词和文件拖拽到tongyi中,点击“一键生成”按钮,即可生成对应的代码。

重启项目,观察是否显示假数据,👇

如果假数据能够正常显示,则说明代码生成成功,接下来只需要对接数据库中的真数据即可。
1.3 对接数据库中的真数据
前言

在ReportUI.java中,将loadStatCards()、loadCategoryMedicineData()、loadMedicineInventoryData()这三个方法中的假数据替换为真实数据即可。
接下来,一个一个完成真实数据对接。
1. loadStatCards()方法

2. loadCategoryMedicineData()方法



3. loadMedicineInventoryData()方法

其他的和上面loadCategoryMedicineData类似,sql语句如下
select medicine_name,
sum(quantity) as quantity
from t_inventory
group by medicine_name order by quantity desc limit 10

最终的效果图:👇
