java项目开发-- 进销存管理系统1 - 图文
更新时间:2024-01-20 21:27:01 阅读量: 教育文库 文档下载
- java项目开发实例推荐度:
- 相关推荐
第1章 进销存管理系统
? 1.1 开发背景 ? 1.2.2 可行性分析 ? 1.3.1 系统目标
? 1.3.3 业务逻辑编码规则 ? 1.3.5 构建开发环境 ? 1.3.7 文件夹组织结构
? 1.4.2 进销存管理系统的E-R图 ? 1.4.4 创建数据库 ? 1.5.1 创建主窗体 ? 1.5.2 创建导航面板(2) ? 1.6.1 编写Dao公共类(2) ? 1.7.1 基础信息模块概述 ? 1.7.3 供应商添加实现过程
? 1.7.4 供应商修改与删除实现过程(2) ? 1.7.5 单元测试(2) ? 1.8.2 进货管理模块技术分析 ? 1.8.3 进货单实现过程(2) ? 1.9.2 查询统计模块技术分析 ? 1.10.1 库存管理模块概述 ? 1.10.3 价格调整实现过程 ? 1.11 系统打包发布
? 1.13 使用PowerDesigner逆向生成数据
? 1.2.1 需求分析 ? 1.2.3 编写项目计划书 ? 1.3.2 系统功能结构 ? 1.3.4 系统流程图 ? 1.3.6 系统预览 ? 1.4.1 数据库分析
? 1.4.3 使用PowerDesigner建模 ? 1.5 主窗体设计
? 1.5.2 创建导航面板(1) ? 1.6.1 编写Dao公共类(1) ? 1.6.2 编写Item类
? 1.7.2 基础信息模块技术分析
? 1.7.4 供应商修改与删除实现过程(1) ? 1.7.5 单元测试(1) ? 1.8.1 进货管理模块概述 ? 1.8.3 进货单实现过程(1) ? 1.9.1 查询统计模块概述 ? 1.9.3 销售查询实现过程 ? 1.10.2 库存管理模块技术分析 ? 1.10.4 单元测试
? 1.12 开发技巧与难点分析 ? 1.14 本章小结
1.1 开发背景
2011-01-01 12:29 明日科技/李钟尉 等 清华大学出版社 我要评论(0) 字号:
《Java项目开发案例全程实录(第2版)》第1章进销存管理系统,通过本章的学习,您可以了解Java应用程序的开发流程及Java Swing的窗体设计、事件监听等技术。另外,还介绍了PowerDesigner工具的数据库建模和逆向生成数据库E-R图以及Java应用程序的系统打包等技术,希望对读者日后的程序开发有所帮助。本节为大家介绍开发背景。
第1章 进销存管理系统
(Swing+SQL Server 2000实现) ( 视频讲解:1小时42分钟)
实现企业信息化管理是现代社会中小企业稳步发展的必要条件,它可以提高企业的管理水平和工作效率,最大限度地减少手工操作带来的失误。进销存管理系统正是一个信息化管理软件,可以实现企业的进货、销售、库存管理等各项业务的信息化管理。本章将介绍如何使用Java Swing技术和SQL Server 2000数据库开发跨平台的应用程序。 通过阅读本章,可以学习到: 如何进行项目的可行性分析 如何进行系统设计
如何进行数据库分析和数据库建模 企业进销存主要功能模块的开发过程 如何设计公共类 如何将程序打包
1.1 开发背景
加入WTO之后,随着国内经济的高速发展,中小型的商品流通企业越来越多,其所经营的商品种类繁多,难以管理,而进销存管理系统逐渐成为企业经营和管理中的核心环节,也是企业取得效益的关键。×××有限公司是一家以商业经营为主的私有企业,为了完善管理制度,增强企业的竞争力,公司决定开发进销存管理系统,以实现商品管理的信息化。现需要委托其他单位开发一个企业进销存管理系统。
1.2 系统分析
1.2.1 需求分析
通过与×××有限公司的沟通和需求分析,要求系统具有以下功能。 系统操作简单,界面友好。 规范、完善的基础信息设置。
支持多人操作,要求有权限分配功能。 为了方便用户,要求系统支持多条件查询。
对销售信息提供销售排行。 支持销售退货和入库退货功能。 批量填写进货单及销售单。 支持库存价格调整功能。
当外界环境(停电、网络病毒)干扰本系统时,系统可以自动保护原始数据的安全。 1.2.2 可行性分析
根据《GB 8567-1988计算机软件产品开发文件编制指南》中可行性分析的要求,制定可行性研究报告如下。 1.引言 编写目的
以文件的形式给企业的决策层提供项目实施的参考依据,其中包括项目存在的风险、项目需要的投资和能够收获的最大效益。 背景
×××有限公司是一家以商业经营为主的私有企业。为了完善管理制度、增强企业的竞争力、实现信息化管理,公司决定开发进销存管理系统。 2.可行性研究的前提 要求
企业进销存管理系统必须提供商品信息、供应商信息和客户信息的基础设置;提供强大的多条件搜索功能和商品的进货、销售和库存管理功能;可以分不同权限、不同用户对该系统进行操作。另外,该系统还必须保证数据的安全性、完整性和准确性。 目标
企业进销存管理系统的目标是实现企业的信息化管理,减少盲目采购、降低采购成本、合理控制库存、减少资金占用并提升企业市场竞争力。 条件、假定和限制
为实现企业的信息化管理,必须对操作人员进行培训,而且将原有的库存、销售、入库等信息转换为信息化数据,需要操作员花费大量时间和精力来完成。为了不影响企业的正常运行,进销存管理系统必须在两个月的时间内交付用户使用。
系统分析人员需要2天内到位,用户需要5天时间确认需求分析文档。去除其中可能出现的问题,例如用户可能临时有事,占用6天时间确认需求分析。那么程序开发人员需要在1个月零15天的时间内进行系统设计、程序编码、系统测试、程序调试和网站部署工作,其间还包括了员工每周的休息时间。 评价尺度
根据用户的要求,项目主要以企业进货、销售和查询统计功能为主,对于库存、销售和进货的记录信息应该及时、准确地保存,并提供相应的查询和统计。由于库存商品数量太多,不易盘点,传统的盘点方式容易出错,系统中的库存盘点功能要准确地计算出每种商品的损益数量,减少企业不必要的损失。 3.投资及效益分析 支出
根据系统的规模及项目的开发周期(两个月),公司决定投入7个人。为此,公司将直接支付9万元的工资及各种福利待遇。在项目安装及调试阶段,用户培训、员工出差等费用支出需要2万元。在项目维护阶段预计需要投入4万元的资金。累计项目投入需要15万元资金。 收益
用户提供项目资金32万元。对于项目运行后进行的改动,采取协商的原则根据改动规模额外提供资金。因此从投资与收益的效益比上,公司可以获得17万元的利润。
项目完成后,会给公司提供资源储备,包括技术、经验的积累,其后再开发类似的项目时,可以极大地缩短项目开发周期。 4.结论
根据上面的分析,在技术上不会存在问题,因此项目延期的可能性很小。在效益上公司投入7个人、2个月的时间获利17万元,效益比较可观。在公司今后发展上,可以储备网站开发的经验和资源。因此,认为该项目可以开发。 1.2.3 编写项目计划书
根据《GB 8567-1988计算机软件产品开发文件编制指南》中的项目开发计划要求,结合单位实际情况,设计项目计划书如下。 1.引言 编写目的
为了保证项目开发人员按时保质地完成预定目标,更好地了解项目实际情况,按照合理的顺序开展工作,现以书面的形式将项目开发生命周期中的项目任务范围、项目团队组织结构、团队成员的工作责任、团队内外沟通协作方式、开发进度、检查项目工作等内容描述出来,作为项目相关人员之间的共识和约定以及项目生命周期内的所有项目活动的行动基础。
背景
企业进销存管理系统是由×××有限公司委托我公司开发的大型管理系统,主要功能是实现企业进销存的信息化管理,包括统计查询、进货、销售、库存盘点及系统管理等功能。项目周期两个月。项目背景规划如表1.1所示。 表1.1 项目背景规划
项 目 名 称 项目委托单位 任务提出者 项目承担部门 策划部门 研发部门 测试部门 企业进销存管理系统 ×××有限公司 陈经理 2.概述 项目目标
项目目标应当符合SMART原则,把项目要完成的工作用清晰的语言描述出来。企业进销存管理系统的项目目标如下:
企业进销存管理系统的主要目的是实现企业进销存的信息化管理,主要的业务就是商品的采购、销售和入库,另外还需要提供统计查询功能,其中包括商品查询、供应商查询、客户查询、销售查询、入库查询和销售排行等。项目实施后,能够降低采购成本、合理控制库存、减少资金占用并提升企业市场竞争力。整个项目需要在两个月的时间内交付用户使用。 产品目标
时间就是金钱,效率就是生命。项目实施后,企业进销存管理系统能够为企业节省大量人力资源,减少管理费用,从而间接为企业节约成本,提高企业效益。 应交付成果
在项目开发完后,交付内容有企业进销存管理系统的源程序、系统的数据库文件、系统使用说明书。 将开发的进销存管理系统打包并安装到企业的网络计算机中。
企业进销存管理系统交付用户之后,进行系统无偿维护和服务 6 个月,超过 6 个月进行系统有偿维护与服务。 项目开发环境
操作系统为Windows XP或Windows 2003均可,使用集成开发工具Eclipse,数据库采用SQL Server 2000,项目运行环境为JDK 6.0。 项目验收方式与依据
项目验收分为内部验收和外部验收两种方式。在项目开发完成后,首先进行内部验收,由测试人员根据用户需求和项目目标进行验收。项目在通过内部验收后,交给客户进行验收,验收的主要依据为需求规格说明书。
3.项目团队组织 组织结构
为了完成进销存管理系统的项目开发,公司组建了一个临时的项目团队,由公司副经理、项目经理、系统分析员、软件工程师、美工人员和测试人员构成,如图1.1所示。
图1.1 项目团队组织结构图 人员分工
为了明确项目团队中每个人的任务分工,现制定人员分工表,如表1.2所示。 表1.2 人员分工表
姓 名 技 术 水 平 陈×× 侯×× 钟×× 李×× 粱×× MBA MBA 高级系统分析员 高级美术工程师 高级软件工程师 所 属 部 门 角 色 经理部 项目开发部 项目开发部 美工设计部 项目开发部 副经理 项目经理 系统分析员 美工人员 软件工程师 工 作 描 述 负责项目的审批、决策的实施 负责项目的前期分析、策划、 项目开发进度的跟踪、 项目质量的检查 负责系统功能分析、 系统框架设计 负责软件美术设计 负责软件设计与编码
马×× 王××
1.3 系统设计
高级软件工程师 中级软件工程师 项目开发部 软件评测部 软件工程师 测试人员 负责软件设计与编码 负责软件测试与评定 1.3.1 系统目标
根据需求分析的描述以及与用户的沟通,现制定系统实现目标如下。 界面设计简洁、友好、美观大方。 操作简单、快捷方便。 数据存储安全、可靠。 信息分类清晰、准确。
强大的查询功能,保证数据查询的灵活性。 提供销售排行榜,为管理员提供真实的数据信息。
提供灵活、方便的权限设置功能,使整个系统的管理分工明确。
对用户输入的数据,系统进行严格的数据检验,尽可能排除人为的错误。 1.3.2 系统功能结构
本系统包括基础信息管理、进货管理、销售管理、库存管理、查询统计、系统管理等6大部分,功能结构如图1.2所示。
(点击查看大图)图1.2 企业进销存管理系统功能结构
1.3.3 业务逻辑编码规则
遵守程序编码规则所开发的程序,代码清晰、整洁、方便阅读,并可以提高程序的可读性。要做到\见其名知其意\,才能编写出优雅的程序代码。本节从数据库设计和程序编码两个方面介绍程序开发中的编码规则。 1.数据库对象命名规则 数据库命名规则
数据库命名以字母\开头(小写),后面加数据库相关英文单词或缩写。下面将举例说明,如表1.3所示。
表1.3 数据库命名
数据库名称 描 述
db_JXC db_library 库 企业进销存管理系统数据库 图书馆管理系统数据注意:在设计数据库时,为使数据库更容易理解,数据库命名时要注意大小写。 数据表命名规则
数据表以字母\开头(小写),后面加数据库相关英文单词或缩写和数据表名,多个单词间用\分隔。下面将举例说明,如表1.4所示。 表1.4 数据表命名
数据表名称 tb_sell_main tb_sell_detail 字段命名规则
描 述 销售主表 销售明细表 字段一律采用英文单词或词组(可利用翻译软件)命名,如找不到专业的英文单词或词组可以用相同意义的英文单词或词组代替。下面将举例说明,如表1.5所示。 表1.5 字段命名
字 段 名 称 描 述 ID Name ProductInfo
注意:在命名数据表的字段时,应注意字母的大小写。 2.业务编码规则 供应商编号
供应商的ID编号是进销存管理系统中供应商的唯一标识,不同的供应商可以通过该编号来区分。该编号是供应商信息表的主键。在本系统中对该编号的编码规则:以字符串\为编号前缀,加上4位数字作编号的后缀,这4位数字从1000开始。例如(gys1001)。
流水号 名称 商品信息
客户编号
和供应商编号类似,客户的ID编号也是客户的唯一标识,不同的客户将以该编号进行区分。该编号作为客户信息表的主键,有数据的唯一性的约束条件,所以在客户信息表中不可能有两个相同的客户编号。企业进销存管理系统对客户编号的编码规则:以字符串\为编号的前缀,加上4位数字作编号的后缀,这4位数字从1000开始。例如(kh1002)。 商品编号
商品编号是商品的唯一标识,它是商品信息表的主键,用于区分不同的商品。即使商品名称、单价、规格等信息相同,其ID编号也是不可能相同的,因为主键约束不可以存在相同的ID值。商品编号的编码规则和客户编号、供应商编号的编码规则相同,但是前缀使用了\字符串。例如(sp2045)。 销售单编号
销售单编号用于区分不同的销售凭据。销售单编号的命名规则:以\字符串为前缀,加上销售单的销售日期,再以3位数字作后缀。例如(XS20071205001)。 入库编号
入库编号用于区分不同的商品入库信息。入库编号的命名规则:以\字符串为前缀,加上商品的入库日期,再以3位数字作后缀。例如(RK20071109003)。 入库退货编号
入库退货编号用于区分不同的入库退货信息。入库退货编号的命名规则:以\字符串为前缀,加上商品入库的退货日期,再以3位数字作后缀。例如(RT20071109001)。 1.3.4 系统流程图
企业进销存管理系统的流程如图1.3所示。
1.3.5 构建开发环境
在开发企业进销存管理系统时,使用了下面的软硬件环境。 操作系统:Windows 2003(SP1)。 Java开发包:JDK 1.6。 数据库:SQL Server 2000。
分辨率:最佳效果为1024×768像素。
注意:SP(Service Pack)为Windows操作系统补丁。
1.3.6 系统预览
企业进销存管理系统由多个程序界面组成,下面仅列出几个典型界面的预览效果,其他界面参见配书光盘中的源程序。
进销存管理系统的主界面如图1.4所示,该界面是所有功能模块的父窗体,其中包含调用所有功能模块的导航面板。商品进货单界面如图1.5所示,该界面将记录进货单据添加到数据库,其中进货单的编号由系统自动生成。
图1.4 主界面(光盘\\?\\com\\lzw\\JXCFrame.java) 图1.5 进货单界面(光盘\\?\\ internalFrame\\JinHuoDan.java)
操作员管理界面如图1.6所示,该界面由系统管理调用,主要用于操作员的添加、查看和删除。商品管理界面如图1.7所示,该界面包括商品的添加、修改和删除等功能。
图1.6 操作员管理界面(光盘\\?\\internalFrame\\CzyGL.java) 1.7 商品管理界面(光盘\\?\\internalFrame\\ShangPinGuanLi.java) 说明:由于路径太长,因此省略了部分路径,省略的路径是\。 1.3.7 文件夹组织结构
在进行系统开发之前,需要规划文件夹组织结构。也就是说,建立多个文件夹,对各个功能模块进行划分,实现统一管理。这样做的好处在于:易于开发、管理和维护。本系统的文件夹组织结构如图1.8所示。
图1.8 文件夹组织结构图 1.4 数据库设计 1.4.1 数据库分析
企业进销存管理系统是一个桌面应用程序,可以直接在本地计算机中运行,而不需要像Web应用那样部署到指定的服务器中。因此,本系统在本地计算机安装了SQL Server 2000数据库服务器。将数据库和应用程序放在同一个计算机中,可以节省开销、提升系统安全性。另外,本系统也可以在网络内的其他计算机中运行,但是这需要将数据库对外开放,会降低数据安全性。其数据库运行环境如下: 硬件平台: CPU:P4 3.2GHz。 内存:512MB以上。 硬盘空间:80GB。 软件平台:
操作系统:Windows 2003。 数据库:SQL Server 2000。 1.4.2 进销存管理系统的E-R图
企业进销存管理系统主要实现从进货、库存到销售的一体化信息管理,涉及商品信息、商品的供应商、购买商品的客户等多个实体。下面简单介绍几个关键的实体E-R图。 客户实体E-R图
企业进销存管理系统记录了所有的客户信息,在进行销售、退货等操作时,将直接引用该客户的实体属性。客户实体包括客户编号、客户名称、简称、地址、电话、E-mail、邮政编码、联系人、联系电话、传真、开户行和账号等属性,客户实体E-R图如图1.9所示。
(点击查看大图)图1.9 客户实体E-R图 供应商实体E-R图
不同的供应商可以为企业提供不同的商品,在商品信息中将引用商品供应商的实体属性。供应商实体包括编号、名称、简称、地址、电话、邮政编码、传真、联系人、联系电话、开户行和E-mail等属性,供应商实体E-R图如图1.10所示。
图1.10 供应商实体E-R图 商品实体E-R图
商品信息是进销存管理系统中的基本信息,系统将维护商品的进货、退货、销售、入库等操作。商品实体包括编号、商品名称、商品简称、产地、单位、规格、包装、批号、批准文号、商品简介和供应商等属性,商品实体E-R图如图1.11所示。
(点击查看大图)图1.11 商品实体E-R图 1.4.3 使用PowerDesigner建模
在数据库概念设计中已经分析了本系统中主要的数据库实体对象,通过这些实体可以得出数据表结构的基本模型,最终实施到数据库中,形成完整的数据结构。本系统将使用PowerDesigner工具完成数据库建模,使用的版本为12.5。使用该工具建模的步骤如下:
(1)运行PowerDesigner,并在PowerDesigner主窗口中选择File/New命令,在打开的New对话框左侧的Model type列表框中选择Physical Data Model(物理数据模型,简称PDB)选项,在右侧的Model name文本框中输入模型名称JXCManager,在DBMS下拉列表框中选择数据库管理系统。PowerDesigner支持的数据库管理系统非常多,例如常用的MySQL 5.0、Microsoft SQL Server 2005、Oracle Version 10gR2等。企业进销存管理系统选择Microsoft SQL Server 2000作为数据库服务器,单击\确定\按钮,如图1.12所示。
(点击查看大图)图1.12 New对话框 (2)打开新建的PDM窗口。在该窗口的中心空白区域是模型编辑器,下方为输出窗口。另外还有一个浮动的工具面板,其中包括常用的建表工具、建视图工具和主外键引用工具,如图1.13所示。
(3)在图1.13中单击\建表工具\按钮 ,这时鼠标指针将显示为 ,在模型编辑器的合适位置单击,
此时在图形窗口中将显示如图1.14所示的数据表模型。
图1.13 工具面板 图1.14 表符号 注意:细心的读者可以发现,此时的鼠标指针仍然显示为 。如果再次单击,还将出现类似图1.14所示的表符号。如果想取消该指针,可以单击工具面板中的 按钮或单击鼠标右键。
(4)在图1.14所示的表符号上双击鼠标左键,将打开Table Properties(表属性)对话框。默认情况下选中的是General选项卡,在该选项卡的Name文本框中,输入表的名称tb_manager,此时在Code文本框中也将自动显示tb_manager,其他选择默认即可。
(5)选择Columns选项卡,单击表格的第一行,第一行将自动转换为编辑状态;然后在Name列输入字段名称为ID,同时Code列也将自动显示为ID;再在Data Type列中选择int选项;最后选中P列的复选框,将该数据表字段设置为主键;此时M列的复选框也将自动被选中,它约束字段值不能为空。
(6)按照步骤(5)的方法再添加两个列name和PWD,但是不需要选中P列复选框设置主键,如图1.15所示。
(点击查看大图)图1.15 Columns(列)选项卡 (7) 在图1.15中单击\应用\按钮后,选择ID字段,单击左上角的 按钮,将打开Column Properties(列属性)对话框,默认选中General选项卡,在其中选中Identity复选框,此项操作用于设置ID字段使用自动编号。
(8)单击\应用\按钮后,再单击\确定\按钮,关闭Column Properties对话框。 (9)单击\确定\按钮,关闭Table Properties对话框,完成tb_manager表的创建。
(10)按照步骤(3)~(9)的方法创建本系统中的其他数据表,并通过主外键引用工具建立各表间的依赖关系。创建完成的模型如图1.16所示。
技巧:在默认情况下,创建后的表模型中的全部文字均为常规样式的宋体8号字,如果想修改文字的格式,可以选中全部表符号,按Ctrl+T键,在打开的Symbol Format对话框中选择Font选项卡,从中设置相关内容的字体及样式和字号等。
(11)在PowerDesigner菜单栏中选择Database/Generate Database命令,打开Database Generation对话框。在该对话框中设置导出的脚本文件的名称(如jxc.sql)及保存路径(如D:\\JXC),选中Script generation单选按钮,如图1.17所示。单击\确定\按钮,即可在指定的路径中生成数据库脚本文件。
(点击查看大图)图1.16 企业进销存管理系统的模型
(点击查看大图)图1.17 Database Generation对话框 (12)在图1.17所示的对话框中选择Direct generation单选按钮,可以使用ODBC数据源直接在数据库管理系统中生成数据表和视图。但是,必须先创建数据库的数据源,然后单击 按钮选择指定的数据源,并单击\确定\按钮。 1.4.4 创建数据库
在导出数据库脚本文件后,就可以在查询分析器中执行该脚本来创建数据库及数据表了。具体步骤如下: (1)选择\开始\所有程序\查询分析器\命令,在弹出的\连接到 SQL Server\对话框中输入访问数据库的用户名和密码,单击\确定\按钮,如图1.18所示。
图1.18 \连接到 SQL Server\对话框 (2)在打开的SQL查询分析器中选择\文件\打开\命令,在弹出的对话框中选择数据库脚本文件,然后单击\打开\按钮,返回查询分析器,选择执行脚本的数据库,然后单击 按钮执行脚本中的命令,创建数据
库的表结构,如图1.19所示。
(点击查看大图)图1.19 查询分析器运行效果 1.5 主窗体设计
主窗体界面也是该系统的欢迎界面。应用程序的主窗体必须设计层次清晰的系统菜单和工具栏,其中系统菜单包含系统中所有功能的菜单项,而工具栏主要提供常用功能的快捷访问按钮。企业进销存管理系统采用导航面板,综合了系统菜单和工具栏的优点,而且其界面更加美观,操作更快捷。主窗体的运行效果如图1.20所示。
(点击查看大图)图1.20 程序主窗体界面效果 1.5.1 创建主窗体 创建主窗体的步骤如下:
(1)创建JXCFrame类,在类中创建并初始化窗体对象,为窗体添加桌面面板,并设置背景图片。关键代码如下:
例程01 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\JXCFrame.java
1. 2. 3. 4. 5. 6.
private JDesktopPane desktopPane; private JFrame frame; private JLabel backLabel;
private Preferences preferences; //创建窗体的Map类型集合对象
private Map
public JXCFrame() {
frame = new JFrame(\企业进销存管理系统\//创建窗体对象
frame.addComponentListener(new FrameListener()); //添加窗体事件监听器
10. frame.getContentPane().setLayout(new BorderLayout());
//设置布局管理器
11. frame.setBounds(100, 100, 800, 600);
//设置窗体位置和大小
12. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置窗体默认的关闭方式
13. backLabel = new JLabel();
//背景标签
14. backLabel.setVerticalAlignment(SwingConstants.TOP);
//设置背景标签垂直对齐方式
15. backLabel.setHorizontalAlignment(SwingConstants.CENTER);
//设置背景标签水平对齐方式
16. updateBackImage();
//调用初始化背景标签的方法
17. desktopPane = new JDesktopPane();
//创建桌面面板
18. desktopPane.add(backLabel, new Integer(Integer.MIN_VALUE));
//将背景标签添加到桌面面板中
19. frame.getContentPane().add(desktopPane);
//添加桌面面板到窗体中
20. JTabbedPane navigationPanel = createNavigationPanel();
//创建导航面板
21. frame.getContentPane().add(navigationPanel, BorderLayout.NORTH);
//添加导航面板到窗体中
22. frame.setVisible(true);
//显示窗体 23. }
(2)编写updateBackImage()方法,在该方法中初始化背景标签,背景标签使用HTML超文本语言设置了主窗体的背景图片,该图片将随主窗体的大小自动缩放。关键代码如下: 例程02 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\JXCFrame.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
private void updateBackImage() { if (backLabel != null) {
int backw = JXCFrame.this.frame.getWidth(); int backh = frame.getHeight();
backLabel.setSize(backw, backh); //初始化背景标签的大小
backLabel.setText(\
+ JXCFrame.this.getClass().getResource(\)
+ \>\//设置背景标签的图像 10. } 11. }
(3)在类的静态代码段中设置进销存管理系统的外观样式。Swing支持跨平台特性,它可以在不同的操作系统中保持一致的外观风格,但是本系统使用UIManager类的setLookAndFeel()方法设置程序界面使用本地外观,这样可以使程序更像本地应用程序。关键代码如下:
例程03 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\JXCFrame.java
1. 2. 3. 4. 5. 6. 7.
static { try {
UIManager.setLookAndFeel(UIManager. getSystemLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); } }
(4)编写主窗体的main()入口方法,在该方法中创建登录窗体对象,登录窗体会验证登录信息,并显示主窗体界面。关键代码如下:
例程04 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\JXCFrame.java
1. 2. 3. 4. 5. 6. 7.
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() { public void run() { new Login(); } }); }
1.5.2 创建导航面板(1) 创建导航面板的步骤如下:
(1)在JXCFrame类中编写createNavigationPanel()方法,在该方法中创建JTabbedPane选项卡面板对象;为突出选项卡的立体效果,设置其使用BevelBorder边框效果;然后依次创建\基础信息管理\、\库存管理\、\销售管理\、\查询统计\、\进货管理\和\系统管理\选项卡。关键代码如下: 例程05 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\JXCFrame.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
private JTabbedPane createNavigationPanel() { //创建导航面板的方法 JTabbedPane tabbedPane = new JTabbedPane(); tabbedPane.setFocusable(false);
tabbedPane.setBackground(new Color(211, 230, 192));
tabbedPane.setBorder(new BevelBorder(BevelBorder.RAISED)); JPanel baseManagePanel = new JPanel(); //“基础信息管理”面板
baseManagePanel.setBackground(new Color(215, 223, 194)); baseManagePanel.setLayout(new BoxLayout (baseManagePanel, BoxLayout.X_AXIS));
baseManagePanel.add(createFrameButton(\客户信息管理\\
10. baseManagePanel.add(createFrameButton(\商品信息管理\
\
11. baseManagePanel.add(createFrameButton(\供应商信息管理\
\
12. JPanel depotManagePanel = new JPanel();
//“库存管理”面板
13. depotManagePanel.setBackground(new Color(215, 223, 194)); 14. depotManagePanel.setLayout(new BoxLayout
(depotManagePanel, BoxLayout.X_AXIS));
15. depotManagePanel.add(createFrameButton(\库存盘点\
\
16. depotManagePanel.add(createFrameButton(\价格调整\
\
17. JPanel sellManagePanel = new JPanel();
//“销售管理”面板
18. sellManagePanel.setBackground(new Color(215, 223, 194)); 19. sellManagePanel.setLayout(new BoxLayout
(sellManagePanel, BoxLayout.X_AXIS));
20. sellManagePanel.add(createFrameButton(\销售单\
\
21. sellManagePanel.add(createFrameButton(\销售退货\
\
22. JPanel searchStatisticPanel = new JPanel();
//“查询统计”面板
23. searchStatisticPanel.setBounds(0, 0, 600, 41);
24. searchStatisticPanel.setName(\
25. searchStatisticPanel.setBackground(new Color(215, 223, 194)); 26. searchStatisticPanel.setLayout(new BoxLayout
(searchStatisticPanel, BoxLayout.X_AXIS)); 27. searchStatisticPanel.add(createFrameButton
(\客户信息查询\
28. searchStatisticPanel.add(createFrameButton
(\商品信息查询\
29. searchStatisticPanel.add(createFrameButton
(\供应商信息查询\ 30. searchStatisticPanel.add(createFrameButton
(\销售信息查询\
31. searchStatisticPanel.add(createFrameButton
(\销售退货查询\
32. searchStatisticPanel.add(createFrameButton
(\入库查询\
33. searchStatisticPanel.add(createFrameButton
(\入库退货查询\
34. searchStatisticPanel.add(createFrameButton
(\销售排行\
35. JPanel stockManagePanel = new JPanel();
//“进货管理”面板
36. stockManagePanel.setBackground(new Color(215, 223, 194)); 37. stockManagePanel.setLayout(new BoxLayout
(stockManagePanel, BoxLayout.X_AXIS));
38. stockManagePanel.add(createFrameButton(\进货单\ 39. stockManagePanel.add(createFrameButton(\进货退货
\
40. JPanel sysManagePanel = new JPanel();
//“系统管理”面板
41. sysManagePanel.setBackground(new Color(215, 223, 194)); 42. sysManagePanel.setLayout(new BoxLayout
(sysManagePanel, BoxLayout.X_AXIS));
43. sysManagePanel.add(createFrameButton(\操作员管理\ 44. sysManagePanel.add(createFrameButton(\更改密码
\
45. sysManagePanel.add(createFrameButton(\权限管理
\
46. //将所有面板添加到导航面板中
47. tabbedPane.addTab(\基础信息管理 \
baseManagePanel, \基础信息管理\
48. tabbedPane.addTab(\进货管理 \
stockManagePanel, \进货管理\
49. tabbedPane.addTab(\销售管理 \
sellManagePanel, \销售管理\
50. tabbedPane.addTab(\查询统计 \
searchStatisticPanel, \查询统计\
51. tabbedPane.addTab(\库存管理 \
depotManagePanel, \库存管理\
52. tabbedPane.addTab(\系统管理 \
sysManagePanel, \系统管理\ 53. return tabbedPane; 54. }
(2)编写createFrameButton()方法,该方法负责创建Action对象,该对象用于创建并显示窗体对象。另外,它还包含图标、文本等属性。如果将Action对象添加到系统菜单栏或者工具栏中,会直接创建相应的菜单项和工具按钮,而且这些菜单项和工具按钮将显示Action对象中的文本和图标属性。本系统没有使用系统菜单,所以该方法将直接创建按钮对象。关键代码如下:
例程06 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\JXCFrame.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
private JButton createFrameButton(String fName, String cname) { //为内部窗体添加 Action 的方法
String imgUrl = \ + fName + \
String imgUrl_roll = \ + fName + \ String imgUrl_down = \ + fName + \ Icon icon = new ImageIcon(imgUrl); //创建按钮图标
Icon icon_roll = null; if (imgUrl_roll != null)
icon_roll = new ImageIcon(imgUrl_roll); //创建鼠标经过按钮时的图标 Icon icon_down = null;
10. if (imgUrl_down != null)
11. icon_down = new ImageIcon(imgUrl_down);
//创建按钮按下的图标
12. Action action = new openFrameAction(fName, cname,
icon); //用 openFrameAction 类创建 Action 对象 13. JButton button = new JButton(action); 14. button.setMargin(new Insets(0, 0, 0, 0)); ? 15. button.setHideActionText(true); ? 16. button.setFocusPainted(false); ? 17. button.setBorderPainted(false); ? 18. button.setContentAreaFilled(false); ? 19. if (icon_roll != null)
20. button.setRolloverIcon(icon_roll); ? 21. if (icon_down != null)
22. button.setPressedIcon(icon_down); ? 23. return button; 1.5.2 创建导航面板(2) 代码贴士
setMargin():该方法用于设置按钮的四周边界大小。
setHideActionText():该方法用于设置按钮隐藏Action对象中的文本信息,例如一个只显示图标的按钮可以取消文本使按钮更加美观。
setFocusPainted():该方法用于设置按钮获取焦点时,是否绘制焦点样式。导航面板取消了这个焦点样式,因为它破坏了按钮图标的美观性。
setBorderPainted():该方法用于设置是否绘制按钮的边框样式,导航面板取消了边框样式,因为按钮的图标需要覆盖整个按钮。
setContentAreaFilled():该方法用于设置是否绘制按钮图形,在不同的操作系统,甚至系统不同的皮肤样式中都有不同的图形。导航面板取消了按钮的图形效果,因为导航面板要使用图标绘制整个按钮。 setRolloverIcon():该方法用于设置鼠标经过按钮时,按钮所使用的图标。 setPressedIcon():该方法用于设置鼠标按下按钮时,按钮所使用的图标。
(3)编写内部类openFrameAction,它必须继承AbstractAction类实现Action接口。该类用于创建导航按钮的Action对象,并为每个导航按钮定义创建并显示不同窗体对象的动作监听器,这个监听器在按钮被按下时,调用getIFrame()方法获取相应的窗体对象,并显示在主窗体中。关键代码如下: 例程07 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\JXCFrame.java
1.
protected final class openFrameAction extends AbstractAction { //主窗体菜单项的单击事件监听器
2. 3. 4. 5. 6. 7. 8. 9.
private String frameName = null; private openFrameAction() { }
public openFrameAction(String cname, String frameName, Icon icon) {
this.frameName = frameName;
putValue(Action.NAME, cname); //设置 Action 的名称
putValue(Action.SHORT_DESCRIPTION, cname); //设置 Action 的提示文本框
putValue(Action.SMALL_ICON, icon); //设置 Action 的图标
10. }
11. public void actionPerformed(final ActionEvent e) { 12. JInternalFrame jf = getIFrame(frameName);
//调用 getIFrame() 方法
13. //在内部窗体关闭时,从内部窗体容器 ifs 对象中清除该窗体
14. jf.addInternalFrameListener(new InternalFrameAdapter() { 15. public void internalFrameClosed(InternalFrameEvent e) {
16. ifs.remove(frameName); 17. } 18. });
19. if (jf.getDesktopPane() == null) {
20. desktopPane.add(jf);
//将窗体添加到主窗体中
21. jf.setVisible(true);
//显示窗体 22. } 23. try {
24. jf.setSelected(true);
//使窗体处于被选择状态
25. } catch (PropertyVetoException e1) { 26. e1.printStackTrace(); 27. } 28. } 29. }
(4)编写getIFrame()方法,该方法负责创建指定名称的窗体对象。在方法中使用了Java的反射技术,调用不同窗体类的默认构造方法创建窗体对象。关键代码如下:
例程08 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\JXCFrame.java
1.
private JInternalFrame getIFrame(String frameName) { //获取内部窗体的唯一实例对象
2. 3. 4. 5. 6. 7. 8. 9.
JInternalFrame jf = null;
if (!ifs.containsKey(frameName)) { try {
Class fClass = Class.forName(\e);
Constructor constructor = fClass.getConstructor(null); jf = (JInternalFrame) constructor.newInstance(null); ifs.put(frameName, jf); } catch (Exception e) {
10. e.printStackTrace(); 11. } 12. } else
13. jf = ifs.get(frameName); 14. return jf; 15. } 1.6 公共模块设计
在本系统的项目空间中,有部分模块(或者是多个模块甚至整个系统的配置信息)是公用的,它们被多个模块重复调用完成指定的业务逻辑,本节将这些公共模块提出来加以单独介绍。 1.6.1 编写Dao公共类(1)
Dao类主要负责有关数据库的操作,该类在静态代码段中驱动并连接数据库,然后将所有的数据库访问方法定义为静态的。本节将介绍Dao类中有关数据库操作的关键方法。Dao类的定义代码如下: 例程09 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\dao\\Dao.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
public class Dao {
protected static String ?dbClassName = \microsoft.jdbc.sqlserver.SQLServerDriver\;
protected static String ?dbUrl = \sqlserver://localhost:1433;\
+ \DatabaseName=db_JXC;SelectMethod=Cursor\ protected static String ?dbUser = \; protected static String ?dbPwd = \; protected static String second = null; public static Connection ?conn = null; static {
10. try {
11. if (conn == null) {
12. Class.forName(dbClassName).newInstance();
//加载数据库驱动类
13. conn = DriverManager.getConnection(dbUrl,
dbUser, dbPwd); //获取数据库连接
14. }
15. } catch (Exception ee) { 16. ee.printStackTrace(); 17. } 18. } 19. } 代码贴士
dbClassName:该成员变量用于定义数据库驱动类的名称。 dbUrl:该成员变量用于定义访问数据库的URL路径。 dbUser:该成员变量用于定义访问数据库的用户名称。 dbPwd:该成员变量用于定义访问数据库的用户密码。 conn:该成员变量用于定义连接数据库的对象。 1.addGys()方法
该方法用于添加供应商的基础信息,它接收供应商的实体类TbGysinfo作方法的参数,然后把实体对象中的所有属性存入供应商数据表中。关键代码如下:
例程10 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\dao\\Dao.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
//添加供应商信息的方法
public static boolean addGys(TbGysinfo gysInfo) { if (gysInfo == null) //如果供应商实体对象为空
return false; //则返回false
return insert(\getId() + \执行供应商添加
+ gysInfo.getName() + \ + gysInfo.getAddress() + \','\
+ gysInfo.getTel() + \ + gysInfo.getLian() + \
10. + gysInfo.getMail() + \ 11. } 2.getGysInfo()方法
该方法将根据Item对象中封装的供应商ID编号和供应商名称获取指定供应商的数据,并将该供应商的数据封装到实体对象中,然后返回该实体对象。关键代码如下:
例程11 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\dao\\Dao.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
//读取指定供应商信息
public static TbGysinfo getGysInfo(Item item) {
String where = \ + item.getName() + \//默认的查询条件以供应商名称为主
if (item.getId() != null) //如果Item对象中存有ID编号
where = \ + item.getId() + \//则以ID编号为查询条件
TbGysinfo info = new TbGysinfo();
ResultSet set = findForResultSet(\tb_gysinfo where \ try {
if (set.next()) { //封装供应商数据到实体对象中
11. info.setAddress(set.getString(\ 12. info.setBianma(set.getString(\ 13. info.setFax(set.getString(\ 14. info.setJc(set.getString(\ 15. info.setLian(set.getString(\ 16. info.setLtel(set.getString(\ 17. info.setMail(set.getString(\ 18. info.setName(set.getString(\ 19. info.setTel(set.getString(\ 20. info.setYh(set.getString(\ 21. }
22. } catch (SQLException e) { 23. e.printStackTrace(); 24. }
25. return info;
//返回供应商实体对象 26. }
1.6.1 编写Dao公共类(2) 3.updateGys()方法
该方法用于更新供应商的基础信息,它接收供应商的实体类TbGysinfo作方法参数,在方法中直接解析供应商实体对象中的属性,并将这些属性更新到数据表中。关键代码如下:
10. info.setId(set.getString(\
例程12 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\dao\\Dao.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
//修改供应商信息的方法
public static int updateGys(TbGysinfo gysInfo) {
return update(\jc='\ + \address='\,bianma='\ + gysInfo.getBianma() + \tel='\ + \fax='\,lian='\tLian()
+ \ltel='\,mail='\ + gysInfo.getMail() + \yh='\ + \id='\\
10. }
4.insertRukuInfo()方法
该方法负责完成入库单信息的添加,涉及到库存表、入库主表和入库详细表等多个数据表的操作。为保证数据的完整性,该方法将入库信息的添加操作放在事务中完成,方法将接收入库主表的实体类TbRukuMain作参数,该实体类中包含了入库详细表的引用。关键代码如下:
例程13 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\dao\\Dao.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
public static boolean insertRukuInfo(TbRukuMain ruMain) { //在事务中添加入库信息 try {
boolean ?autoCommit = conn.getAutoCommit();
conn.setAutoCommit(false); ? //取消自动提交模式
insert(\//添加入库主表记录
+ \\
+ ruMain.getYsjl() + \','\
+ ruMain.getRkdate() + \'\
+ ruMain.getJsr() + \;
10. Set
r.hasNext();) {
12. TbRukuDetail details = iter.next();
13. insert(\
ruMain.getRkId() //添加入库详细表记录
14. + \
+ details.getDj() + \ 15. Item item = new Item();
16. item.setId(details.getTabSpinfo()); 17. TbSpinfo spInfo = getSpInfo(item);
18. if (spInfo.getId() != null && !spInfo.getId().isEmpty())
{
19. TbKucun kucun = getKucun(item);
20. if (kucun.getId() == null || kucun.getId().
isEmpty()) { //添加或修改库存表记录
21. insert(\
spInfo.getId()
22. + \
\
23. + \
\
24. + \
\ 25. } else {
26. int sl = kucun.getKcsl() + details.getSl(); 27. update(\kcsl=\
\,dj=\ where id='\\ 28. } 29. } 30. }
31. conn.commit(); ?
//提交事务
32. conn.setAutoCommit(autoCommit);
//恢复自动提交模式
33. } catch (SQLException e) { 34. try {
35. conn.rollback(); ?
//如果出错,回退事务
36. } catch (SQLException e1) { 37. e1.printStackTrace(); 38. }
39. e.printStackTrace(); 40. }
41. return true; 42. } 代码贴士
getAutoCommit():该方法用于获取事务自动提交模式。
setAutoCommit():该方法用于设置事务的自动提交模式。 commit():该方法用于执行事务提交。
rollback ():该方法在事务执行失败时,执行回退操作。 5.getKucun()方法
该方法用于获取指定ID编号或名称的商品库存信息,它接收一个Item对象作参数,该对象中封装了商品的ID编号和商品名称信息,如果库存表中存在该商品的库存记录,就获取该记录并将记录中的数据封装到库存表的实体对象中,然后将该实体对象作为方法的返回值。关键代码如下: 例程14 代码位置:光盘\\TM\\01\\JXCManager\\src\\com\\lzw\\dao\\Dao.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
//获取库存商品信息
public static TbKucun getKucun(Item item) {
String where = \ + item.getName() + \ if (item.getId() != null)
where = \ + item.getId() + \
ResultSet rs = findForResultSet(\+ where);
TbKucun kucun = new TbKucun(); try {
if (rs.next()) {
10. kucun.setId(rs.getString(\
11. kucun.setSpname(rs.getString(\ 12. kucun.setJc(rs.getString(\ 13. kucun.setBz(rs.getString(\ 14. kucun.setCd(rs.getString(\ 15. kucun.setDj(rs.getDouble(\ 16. kucun.setDw(rs.getString(\ 17. kucun.setGg(rs.getString(\ 18. kucun.setKcsl(rs.getInt(\ 19. }
20. } catch (SQLException e) { 21. e.printStackTrace(); 22. }
23. return kucun; 24. } 1.6.2 编写Item类
Item类是系统的公共类之一,主要用于封装和传递参数信息,这是典型命令模式的实现。在Dao类中经常使用该类作为方法参数;另外,在各个窗体界面中也经常使用该类作组件数据,其toString()方法将返回
name属性值,所以显示到各个组件上的内容就是Item类的对象所代表的商品、供应商或者客户等信息中的名称。定义该类的关键代码如下:
例程15 代码位置:光盘\\TM\\01\\JXCManager\\src\\internalFrame\\guanli\\Item.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
public String id; //定义id属性 public String name; //定义名称属性
public String getId() { //定义暴露ID属性的方法 return id; }
public void setId(String id) { this.id = id; }
public String getName() { //定义暴露名称属性的方法
10. return name; 11. }
12. public void setName(String name) { 13. this.name = name; 14. }
15. public String toString() { //定义该类的字符串表现形式 16. return getName(); 17. } 18.
1.7 基础信息模块设计
基础信息模块用于管理企业进销存管理系统中的客户、商品和供应商信息,其功能主要是对这些基础信息进行添加、修改和删除。 1.7.1 基础信息模块概述
企业进销存管理系统中的基础信息模块主要包括客户管理、商品管理和供应商管理3部分。由于它们的实现方法基本相似,本节将以供应商管理部分为主,介绍基础信息模块对本系统的意义和实现的业务逻辑。 1.供应商添加
供应商添加功能主要负责为系统添加新的供应商记录。在企业进销存管理系统中,商品是主要的管理对象,而系统中所有的商品都由不同的供应商提供,这就需要把不同的供应商信息添加到系统中,在商品信息中会关联系统中对应的供应商信息。供应商添加功能的程序界面如图1.21所示。 2.供应商修改与删除
供应商的修改与删除功能主要用于维护系统中的供应商信息。在供应商的联系方式发生改变时,必须更新系统中的记录,以提供供应商的最新信息。另外,当不再与某家供应商合作时,需要从系统中删除供应商的记录信息。其程序运行界面如图1.22所示。
图1.21 供应商添加界面 图1.22 供应商修改与删除功能界面 1.7.2 基础信息模块技术分析
基础信息模块中使用了Java Swing的JTabbedPane选项卡面板组件分别为客户信息管理、商品信息管理和供应商信息管理提供了多个操作界面,例如供应商信息管理中分别存在供应商添加和供应商修改与删除界面,而这两个界面都存在于一个窗体中,可以通过选择顶部的两个选项卡,在不同的界面间来回切换。 1.7.3 供应商添加实现过程
供应商添加使用的数据表:tb_gysinfo。
(1)创建GysTianJiaPanel类,用于实现本系统的供应商添加功能。该类将在界面中显示多个用于输入供应商信息的文本框。界面中定义的主要控件如表1.6所示。 表1.6 供应商添加界面中的主要控件
控 件 类 型 控 件 名 称 quanChengF JianChengF BianMaF DiZhiF JtextField DianHuaF ChuanZhenF LianXiRenF lianXiRenDianHuaF YinHangF EmailF 主要属性设置 用 途 无 无 无 无 无 无 无 无 无 无 供应商全称 简称 邮政编码 地址 电话 传真 联系人 联系人电话 开户银行 电子信箱 续表
控 件 类 型 控 件 名 称 主要属性设置 设置按钮文本为“添加” TjButton Jbutton ResetButton 象 设置按钮文本为“重填” 设置动作监听器为 ResetActionListener类的实例对象 设置动作监听器为 TjActionListener类的实例对用 途 添加 重填 (2)创建ResetActionListener类,该类是\重填\按钮的事件监听器,它必须实现ActionListener接口,并在actionPerformed()方法中清除界面中的所有文本框内容。关键代码如下:
例程16 代码位置:光盘\\TM\\01\\JXCManager\\src\\internalFrame\\gysGuanLi\\GysTianJiaPanel.java
1. 2. 3.
class ResetActionListener implements ActionListener { //“重填”按钮的事件监听类
public void actionPerformed( ?
final ActionEvent e) { ?
4. 5. 6. 7. 8. 9.
diZhiF.setText(\//将文本框中的内容设置为空字符串 bianMaF.setText(\ chuanZhenF.setText(\ jianChengF.setText(\ lianXiRenF.setText(\
lianXiRenDianHuaF.setText(\
10. EMailF.setText(\ 11. quanChengF.setText(\ 12. dianHuaF.setText(\ 13. yinHangF.setText(\ 14. } 15. }
ActionListener接口:该接口是控件的动作监听器接口,实现该接口的类可以成为按钮和菜单项等控件的监听器。
actionPerformed():该方法是监听器ActionListener接口定义的方法,当事件产生时,将调用监听器实现类的actionPerformed()方法处理相应的业务逻辑。
ActionEvent:该类是动作事件类,当用户单击按钮时,将产生该事件,这个事件会被监听器捕获并执行相应的业务逻辑。
(3)创建TjActionListener类,该类是\添加\按钮的事件监听器,它必须实现ActionListener接口,并在actionPerformed()方法中实现用户输入的验证和供应商信息的保存。关键代码如下:
例程17 代码位置:光盘\\TM\\01\\JXCManager\\src\\internalFrame\\gysGuanLi\\GysTianJiaPanel.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
class TjActionListener implements ActionListener { //“添加”按钮的事件监听类
public void actionPerformed(final ActionEvent e) {
if (diZhiF.getText().equals(\getText().equals(\验证用户输入
|| chuanZhenF.getText().equals(\jianChengF.getText().equals(\
|| yinHangF.getText().equals(\bianMaF.getText().equals(\
|| diZhiF.getText().equals(\lianXiRenF.getText().equals(\
|| lianXiRenDianHuaF.getText().equals(\ || EMailF.getText().equals(\dianHuaF.getText().equals(\
JOptionPane.showMessageDialog (GysTianJiaPanel.this, \请填写全部信息\
10. return; 11. }
12. try {
//验证是否存在同名供应商
13. ResultSet haveUser = Dao.query(\
from tb_gysinfo where name='\
14. + quanChengF.getText().trim() + \ 15. if (haveUser.next()) {
16. JOptionPane.showMessageDialog(GysTianJiaPanel.this,
17. \供应商信息添加失败,存在同名
供应商\供应商添加信息\
18. JOptionPane.INFORMATION_MESSAGE); 19. return; 20. }
21. ResultSet set = Dao.query(\
from tb_gysinfo\获取供应商的最大 ID 编号 22. String id = null;
23. if (set != null && set.next()) {
//创建新的供应商编号
24. String sid = set.getString(1).trim(); 25. if (sid == null) 26. id = \; 27. else {
28. String str = sid.substring(3);
29. id = \ + (Integer.parseInt(str) + 1); 30. } 31. }
32. TbGysinfo gysInfo = new TbGysinfo();
//创建供应商实体对象
33. gysInfo.setId(id);
//初始化供应商对象
34. gysInfo.setAddress(diZhiF.getText().trim()); 35. gysInfo.setBianma(bianMaF.getText().trim()); 36. gysInfo.setFax(chuanZhenF.getText().trim()); 37. gysInfo.setYh(yinHangF.getText().trim()); 38. gysInfo.setJc(jianChengF.getText().trim()); 39. gysInfo.setName(quanChengF.getText().trim()); 40. gysInfo.setLian(lianXiRenF.getText().trim());
41. gysInfo.setLtel(lianXiRenDianHuaF.getText().trim()); 42. gysInfo.setMail(EMailF.getText().trim()); 43. gysInfo.setTel(dianHuaF.getText().trim()); 44. Dao.addGys(gysInfo);
//调用addGys()方法存储供应商
45. JOptionPane.showMessageDialog(GysTianJiaPanel.
this, \已成功添加客户\
46. \客户添加信息
\
47. resetButton.doClick();
//触发“重填”按钮的单击动作
48. } catch (SQLException e1) { 49. e1.printStackTrace(); 50. } 51. } 52. }
1.7.4 供应商修改与删除实现过程(1) 供应商修改与删除使用的数据表:tb_gysinfo。
(1)创建GysXiuGaiPanel类,用于实现本系统的供应商修改功能。在程序界面中有多个用于输入供应商信息的文本框,这些文本框的内容会根据所选供应商自动填充,修改部分或全部内容后,单击\修改\按钮将修改供应商数据。界面中定义的主要控件如表1.7所示。 表1.7 供应商修改与删除界面中的主要控件
控 件 类 型 控 件 名 称 quanChengF jianChengF bianMaF diZhiF JtextField dianHuaF chuanZhenF lianXiRenF 主要属性设置 无 无 无 无 无 无 无 用 途 供应商全称 简称 邮政编码 地址 电话 传真 联系人 联系人电话 开户银行 电子信箱 lianXiRenDianHuaF 无 yinHangF EMailF 无 无 设置初始大小为(230, 21) 调用initComboBox()方 JComboBox Gys 法初始化下拉列表 设置组件的选择事件调用 doGysSelectAction()方法 设置按钮文本为“修改” Jbutton tjButton 设置动作监听器为 ModifyActionListener 类的实例对象 选择供应商 修改供应商信息
设置按钮文本为“删除” resetButton 设置动作监听器为 DelActionListener类的实例对象 (2)编写initComboBox()方法,用于初始化\选择供应商\下拉列表框。该方法调用Dao类的getGysInfos()方法获取数据库中所有的供应商信息,然后将供应商的ID编号和供应商名称封装成Item对象并添加到\选择供应商\下拉列表框中,在下拉列表框中Item的toString()方法将显示供应商的名称。initComboBox()方法的关键代码如下:
例程18 代码位置:光盘\\TM\\01\\JXCManager\\src\\internalFrame\\gysGuanLi\\GysXiuGaiPanel.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
public void initComboBox() { //初始化供应商下拉列表框的方法
List gysInfo = Dao.getGysInfos(); //调用getGysInfos()方法获取供应商列表
List
gys.removeAllItems(); //清除下拉列表框中原有的选项
for (Iterator iter = gysInfo.iterator(); iter.hasNext();) { List element = (List) iter.next();
Item item = new Item(); //封装供应商信息 item.setId(element.get(0).toString().trim()); item.setName(element.get(1).toString().trim()); //如果 Items 列表中包含该供应商的封装对象
11. continue; //跳出本次循环 12. items.add(item);
13. gys.addItem(item);
//否则添加该对象到下拉列表框中 14. }
15. doGysSelectAction();
//doGysSelectAction() 方法 16. } 17.
(3)编写doGysSelectAction()方法,它在更改下拉列表框中的供应商信息时被调用,主要用于根据选择的供应商名称,把供应商的其他信息填充到相应的文本框中。关键代码如下:
例程19 代码位置:光盘\\TM\\01\\JXCManager\\src\\internalFrame\\gysGuanLi\\GysXiuGaiPanel.java
1.
private void doGysSelectAction() { //处理供应商选择事件 2.
Item selectedItem;
删除供应商信息 10. if (items.contains(item))
3. 4. 5. 6.
if (!(gys.getSelectedItem() instanceof Item)) { return; }
selectedItem = (Item) gys.getSelectedItem(); //获取 Item 对象
7. 8. 9.
TbGysinfo gysInfo = Dao.getGysInfo(selectedItem); //通过 Item 对象调用 getGysInfo() 方法获取供应商信息 quanChengF.setText(gysInfo.getName()); //填充供应商信息到文本框中
diZhiF.setText(gysInfo.getAddress());
10. jianChengF.setText(gysInfo.getJc()); 11. bianMaF.setText(gysInfo.getBianma()); 12. dianHuaF.setText(gysInfo.getTel()); 13. chuanZhenF.setText(gysInfo.getFax()); 14. lianXiRenF.setText(gysInfo.getLian());
15. lianXiRenDianHuaF.setText(gysInfo.getLtel()); 16. EMailF.setText(gysInfo.getMail()); 17. yinHangF.setText(gysInfo.getYh()); 18. }
1.7.4 供应商修改与删除实现过程(2)
(4)创建ModifyActionListener类,该类是\修改\按钮的事件监听器,它必须实现ActionListener接口,并在actionPerformed()方法中获取所有文本框内容,其中包括修改后的信息,并通过调用updateGys()方法将这些供应商信息更新到数据库中。关键代码如下:
例程20 代码位置:光盘\\TM\\01\\JXCManager\\src\\internalFrame\\gysGuanLi\\GysXiuGaiPanel.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
class ModifyActionListener implements ActionListener { //“修改”按钮的事件监听器
public void actionPerformed(ActionEvent e) { Item item = (Item) gys.getSelectedItem(); TbGysinfo gysInfo = new TbGysinfo(); //创建供应商实体对象
gysInfo.setId(item.getId()); //初始化供应商实体对象
gysInfo.setAddress(diZhiF.getText().trim()); gysInfo.setBianma(bianMaF.getText().trim()); gysInfo.setFax(chuanZhenF.getText().trim()); gysInfo.setYh(yinHangF.getText().trim());
10. gysInfo.setJc(jianChengF.getText().trim()); 11. gysInfo.setName(quanChengF.getText().trim()); 12. gysInfo.setLian(lianXiRenF.getText().trim());
13. gysInfo.setLtel(lianXiRenDianHuaF.getText().trim()); 14. gysInfo.setMail(EMailF.getText().trim());
15. gysInfo.setTel(dianHuaF.getText().trim());
16. if (Dao.updateGys(gysInfo) == 1)
//更新供应商信息
17. JOptionPane.showMessageDialog(GysXiuGaiPanel.
this, \修改完成\ 18. else
19. JOptionPane.showMessageDialog(GysXiuGaiPanel.
this, \修改失败\ 20. } 21. }
(5)创建DelActionListener类,该类是\删除\按钮的事件监听器,它必须实现ActionListener接口,并在actionPerformed()方法中获取当前选择的供应商,然后调用Dao类的delete()方法从数据库中把该供应商删除。关键代码如下:
例程21 代码位置:光盘\\TM\\01\\JXCManager\\src\\internalFrame\\gysGuanLi\\GysXiuGaiPanel.java
1. 2. 3. 4. 5. 6. 7. 8. 9.
class DelActionListener implements ActionListener { //“删除”按钮的事件监听器
public void actionPerformed(ActionEvent e) { Item item = (Item) gys.getSelectedItem(); //获取当前选择的供应商
if (item == null || !(item instanceof Item)) return;
int confirm = JOptionPane.showConfirmDialog( //弹出确认删除对话框
GysXiuGaiPanel.this, \确认删除供应商信息吗?\ //如果确认删除
11. int rs = Dao.delete(\
id='\调用delete()方法
12. + item.getId() + \ 13. if (rs > 0) {
14. JOptionPane.showMessageDialog(GysXiuGaiPanel.
this, //显示删除成功对话框
15. \供应商:\。删除成功\ 16. gys.removeItem(item); 17. } else {
18. JOptionPane.showMessageDialog(GysXiuGaiPanel.this, 19. \无法删除客户:\。\ 20. } 21. } 22. } 23. }
10. if (confirm == JOptionPane.YES_OPTION) {
1.7.5 单元测试(1)
在现代软件开发过程中,单元测试成为与编写代码同步进行的开发活动。单元测试能够提高程序员对程序的信心,保证程序的质量,加快软件开发速度,使程序易于维护。 1.单元测试概述
单元测试是在软件开发过程中要进行的最低级别的测试活动。在单元测试活动中,软件的独立工作单元将在与程序的其他部分相隔离的情况下进行测试。
在传统的结构化编程语言中,如Java语言,要进行测试的工作单元一般是方法。在像C++这样的面向对象的语言中,要进行测试的基本单元是类。单元测试不仅仅是作为无错编码的一种辅助手段在一次性的开发过程中使用,还必须是可重复的,无论是在软件修改或是移植到新的运行环境的过程中。因此,所有的测试都必须在整个软件系统的生命周期中进行。 2.什么是单元测试 它是一种验证行为
程序中的每一项功能都可以通过单元测试来验证其正确性,为以后的开发提供支持。就算是开发后期,也可以轻松地增加功能或更改程序结构,而不用担心这个过程中会破坏重要的东西。而且,它为代码的重构提供了保障。这样,我们就可以更自由地对程序进行改进。 它是一种设计行为
编写单元测试将使我们从调用者的角度观察、思考。特别是先写测试(test-first),迫使我们把程序设计成易于调用和可测试的,即迫使我们解除软件中的耦合。 它是一种编写文档的行为
单元测试是一种无价的文档,它是展示函数或类如何使用的最佳文档。这份文档是可编译、可运行的,它永远保持与代码同步。
3.越到项目后期,单元测试为何越难进行
在很多项目的初期,项目中的大部分程序员都能够自觉地编写单元测试。但随着项目的进展、任务的加重,离交付时间越来越近,不能按时完成项目的风险越来越大,单元测试就往往成为牺牲品了。项目经理因为进度的压力也不重视了,程序员也因为编码的压力和无人看管而不再为代码编写单元测试了。笔者亲身经历的项目都或多或少地发生过类似这样的事情。越是在项目的后期,能够坚持编写单元测试的程序员在整个项目组中所占比例越来越低。
为了追赶项目进度,多数程序员将没有经过任何测试的程序代码上传到版本控制系统,项目经理也不再追问,照单全收。这样做的结果就是在项目后期,技术骨干人员只好加班加点进行系统集成。集成完成之后,下发给测试人员测试时,Bug的报告数量翻倍增长。程序员开始修改Bug,但有非常多的Bug隐藏得很深,一直潜伏到生产环境中去。
4.JUnit单元测试工具的介绍与使用 JUnit使用介绍
JUnit是一个单元测试框架,专门用于测试Java开发的程序。同类产品还包括Nunit(.NET)、CPPUnit(C++),都属于xUnit中的成员。目前JUnit的最新版本是JUnit 4.0,在Eclipse开发工具中已经集成了JUnit的多个版本。
在正式讲解JUnit之前,先来看一下单元测试的运行效果,如图1.23和图1.24所示。
(点击查看大图)图1.23 单元测试通过效果 (点击查看大图)图1.24 单元测试失败效果 在图1.23和图1.24中很容易发现不同颜色的警示条,图1.23所示是绿色的,图1.24所示是红色的。如果所有测试案例运行成功,就为绿色;反之,如果有一个不成功,则为红色。
使用JUnit进行单元测试
下面开始按步骤讲解如何在Eclipse中使用JUnit工具。
(1)为单元测试代码创建一个Java项目,将其命名为JUnitTest。
(2)创建ItemTest类,该类用于测试公共类Item的行为(即方法)。在\创建Java类\对话框中设置该类的超类为TestCase,也就是继承JUnit框架的测试用例编写单元测试,单击\完成\按钮,如图1.25所示。
(3)在项目的构建路径中添加JUnit类库。右击项目名称,在弹出的快捷菜单中选择\构建路径\添加库\命令,在弹出的\添加库\对话框中选择Junit选项,单击\下一步\按钮,如图1.26所示。
(点击查看大图)图1.25 新建测试用例类
(点击查看大图)图1.26 \添加库\对话框
1.7.5 单元测试(2)
(4)在弹出的对话框中选择JUnit的版本为JUnit 4,单击\完成\按钮。
(5)在创建的ItemTest中,对Item类进行单元测试。Item是本系统的公共类之一,要实现该类的单元测试,需要编写以test作方法名称的前缀,创建testName()方法、testID()方法和testEquals()方法。另外还要重写父类的setUp()方法,在该方法中创建并初始化测试用例中需要的数据。 完整代码如下:
1. 2. 3. 4. 5. 6. 7. 8. 9.
import internalFrame.guanli.Item; import junit.framework.TestCase;
public class ItemTest extends TestCase{ ? private Item item;
protected void setUp() throws Exception { ? item=new Item(); item.setId(\
item.setName(\测试\ }
10. public void testID(){ ?
11. assertEquals(item.getId(), \ 12. }
13. public void testName(){ ?
14. assertEquals(item.getName(), \测试\ 15. }
16. public void testEquals(){ ? 17. Item newnewItem=new Item(); 18. newItem.setId(\
19. newItem.setName(\测试\ 20. assertEquals(item, newItem); 21. } 22. } 代码贴士
TestCase:该类是JUnit框架的测试用例类,所有的单元测试都需要继承该类。 setUp():该方法将在单元测试之前,为本类的所有单元测试提供测试数据。 testID():该方法用于测试Item类的getId()方法。 testName():该方法用于测试Item类的getName()方法。 testEquals():该方法用于测试Item类的相等性。
(6)在该类上单击鼠标右键,在弹出的快捷菜单中选择\运行方式\测试\命令,运行Item类的单元测试,根据警示条中的颜色,即可判断单元测试的成功与失败,如图1.23、图1.24所示。因为在本系统中不需要判断Item实例的相等性,所以Item类没有实现父类的equals()方法,可以不进行该测试;否则在判断两个Item类的实例对象是否相等时,将出现判断失败。 1.8 进货管理模块设计
进货管理模块是进销存管理系统中不可缺少的重要组成部分之一,它主要负责为系统记录进货单及其退货信息,相应的进货商品会添加到库存管理中。 1.8.1 进货管理模块概述
企业进销存管理系统中的进货管理模块主要包括进货单和进货退货两个部分。由于它们的实现方法基本相似,本节将以进货单功能为主,介绍进货管理模块对本系统的意义和实现的业务逻辑。 1.进货单
进货单功能主要负责记录企业的商品进货信息,可以单击\添加\按钮,在商品表中添加进货的商品信息。在\供应商\下拉列表框中选择不同的供应商,将会改变商品表中可以添加的商品。进货单的程序界面如图1.27所示。
(点击查看大图)图1.27 进货单程序界面 2.进货退货
进货退货功能主要负责记录进货管理中的退货信息,其界面效果如图1.28所示。在选择了退货的商品之后,单击\退货\按钮,将把表格中的商品退货信息更新到数据库中。
(点击查看大图)图1.28 进货退货程序界面 1.8.2 进货管理模块技术分析
进货管理模块使用JDBC实现事务操作。因为进货和退货的业务逻辑涉及到3个数据表,为保证数据的完整性,将3个数据表的操作放在事务中实现。如果对任何一个数据表的操作出现错误或是不可执行的操作,那么整个事务中的所有操作都将取消,并恢复到事务执行之前的数据状态;否则3个数据表的操作全部执行。下面介绍使用JDBC实现事务操作的关键方法。 1.setAutoCommit()方法
该方法用于设置连接对象的自动提交模式。如果连接对象的自动提交模式为True,则其所有SQL语句将被执行并作为单个事务提交;否则,该连接对象的SQL语句将聚集到事务中,直到调用commit()方法或rollback()方法为止。默认情况下,新连接的自动提交模式为True。 语法:
1.
void setAutoCommit(boolean autoCommit)
autoCommit:该参数为True表示启用连接对象的自动提交模式;为False表示禁用连接对象的自动提交模式。
2.getAutoCommit()
判断此连接对象是否启用了自动提交模式。
正在阅读:
2013-2022年中国鸵鸟养殖项目投资可行性研究报告04-10
合伙协议02-17
中考英语复习策略(完型填空全解)07-24
2013-2022年中国钢材行业市场分析及投资可行性研究报告04-24
高中信息技术说课稿最新7篇03-23
第3章 食品的罐藏06-02
操作插件示例代码01-31
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- 项目开发
- 进销存
- 管理系统
- 图文
- java
- CSFB中GSM频点下发机制
- 2018年高三物理考点练习:三、计算题组合练a卷含解析
- 数据结构实验指导书
- 昆虫病原体的采集、整理和症状识别
- 细胞生物学研究方法
- 津价房地(2008)136号 关于工程造价咨询服务项目及价格的通知
- 2017秋福师《德育论》在线作业一满分答案 doc
- 念佛人必看净空老法师赞叹陶永吉居士学习《无量寿经》心得报告(第七集上)
- 再婚婚前财产协议书范本
- 江苏省常熟市第一中学2014-2015学年八年级上10月月考数学试题
- 高考英语优秀短文改错练习五篇(附带答案)
- 机械专业切管机毕业设计论文
- 山东省教师资格证考试教育学第四章-第九章要点
- GMP《机构与人员》中的关键人员相关情况要求汇总表
- 顾家北100句翻译
- 天津市2018年中考英语模拟试题及答案(附听力mp3)
- 数学模型 打孔机效率提高 - 图文
- 工程师应该掌握的20个模拟电路
- 生物化学复习题及答案
- 2006年度初始注册造价工程师名单