YangeIT大约 9 分钟JDKIdeaSwingGui

1. 报表模块

1.1 报表模块数据库设计和可视化组件介绍

前言

JFreeChart 简介

JFreeChart 是一款开源的 Java 图表库,用于在 Java 应用程序中生成各种高质量的 2D 图表,支持 Swing、JavaFX、Web 等多种环境,是 Java 领域最流行的图表工具之一。

核心特点:
  1. 丰富的图表类型:支持折线图、柱状图、饼图、散点图、甘特图、雷达图等 30+ 常用图表,满足数据统计与可视化需求。
  2. 跨平台兼容:纯 Java 编写,可在 Windows、Mac、Linux 等系统运行,无缝集成 Swing/JavaFX 桌面应用。
  3. 高度可定制:支持自定义颜色、字体、标签、图例、动画效果,可调整图表细节以匹配 UI 风格(如苹果简洁风)。
  4. 轻量易用: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中,点击“一键生成”按钮,即可生成对应的代码。

image
image

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

image
image

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

1.3 对接数据库中的真数据

前言

image
image

在ReportUI.java中,将loadStatCards()、loadCategoryMedicineData()、loadMedicineInventoryData()这三个方法中的假数据替换为真实数据即可。

接下来,一个一个完成真实数据对接。

1. loadStatCards()方法

image
image

2. loadCategoryMedicineData()方法

ReportUI
ReportUI
XXDao
XXDao
XXMapper
XXMapper

3. loadMedicineInventoryData()方法

image
image

其他的和上面loadCategoryMedicineData类似,sql语句如下

  select medicine_name,
          sum(quantity) as quantity
  from t_inventory
  group by medicine_name order by quantity desc limit 10
sql执行结果
sql执行结果

最终的效果图:👇

image
image