当前位置: 首页 > news >正文

基于SWT的图书管理系统设计

功能说明

用SWT做一个图书管理系统,要求实现如下功能:

用户从登录窗口登录。用户身份有3种:高级管理员,普通管理员,普通用户。权限如下:

高级管理员具有所有权限,包括增、删、改、查书籍和用户,借书和还书,设置借阅数量限制,查看所有人的借阅记录;

普通管理员只能增、删、改、查书籍,借书,还书,查看所有人的借阅记录;

普通用户只能借书和还书,查看自己的借阅记录。

所有用户和书籍均有正常和冻结两种状态。

高级管理员可以设置所有用户和书籍的状态,普通管理员只可以设置书籍的状态。

被冻结的用户只能进行还书和查询操作,被冻结的书籍只能被还而不能被借。

架构设计

数据表

使用MySQL建立library数据库,创建5个表:

表books存储所有书籍的信息,包括ISBN(唯一标识)、书名、作者、书籍类型(文学、科学等)、出版社、出版日期、馆藏总数、借出数量、未借出数量、书籍状态(正常或冻结)和添加日期;

表users存储所有用户(包括高级管理员,普通管理员和普通用户)的信息,包括用户名、姓名、登录密码、身份类型(上述三种身份之一)、用户状态(正常或冻结)和添加日期;

表records存储用户的借还记录信息,包括操作时间、用户名、姓名、ISBN、书名、操作类型(借阅或归还)和操作数量;

表states存储用户借还书籍的状态信息,包括用户名、姓名、ISBN、书名、共借过该本书的数量、已还数量、未还数量。这里用户名和ISBN共同确定一条记录,某用户多次借还该本书会以累加的计算方法改变该条记录;

表settings只存储两个数,最大允许借阅总数和单本最大允许借阅数量,只能由高级管理员设置。

各个表的字段信息设置如下:

books字段设置:

下面是分行展示的books的几条记录:

 users字段设置:

books的几条记录:

records字段设置:

records的几条记录:

 states字段设置:

states的几条记录:

settings字段设置:

settings存储的记录:

UI

所有用户共用一个登录窗口,根据所输入的用户名是否存储在users表中及密码是否正确来决定是否允许登录。登录时从users表获取用户的身份,不同身份有不同的展示项。

高级管理员界面展示所有书籍、所有用户、所有借阅状态、我的借阅状态四个表格界面,这里通过SWT中的扩展栏实现四个界面的切换展示。

所有书籍和所有用户界面提供增删改查按钮,所有借阅状态和我的借阅状态只提供查找按钮,其表格内容由用户的操作自动存入数据库,不能更改。借阅记录详情通过表格的上下文菜单弹出。

高级管理员界面同时展示设置、更新、返回登录界面、退出四个按钮。设置按钮用于设置用户的最大可借阅总数和最大单本可借阅数量;更新按钮用于当进行增删改查操作后更新展示的信息。

 

普通管理员展示所有书籍、所有借阅状态和我的借阅状态三项:

普通用户只展示所有书籍和我的借阅状态两项:

 图书借还功能通过选中书籍表格行时右键弹出的上下文菜单提供。图书和登录用户的状态不同,右键菜单也不同。图书和登录用户有任一个冻结时,不弹出借阅按钮。图书未被登录用户借阅时,不弹出归还按钮。

当点击添加、删除、修改、借阅和归还按钮时,弹出相应的操作面板:

 点击查找按钮,弹出响应的查询面板,其中可以通过设置一些条件筛选:

类实现 

考虑到上述界面有大量的共同点,因此通过类来实现,通过传入不同的构造参数即可展示不同的面板。

这里建立MainUI类,不同身份的用户登录时,传入的构造参数决定了展示哪些表格和按钮项;

建立OperationComposition类,继承Composition类,用于在扩展项中包含操作按钮和表格;

建立ExtendedTable类,继承Table类,根据传入的构造参数(包括要展示的数据等)绘制表格,类中还会根据登录用户的身份选择在表格上弹出哪些上下文菜单;

 建立OperationPanel类,用于点击增、删、改和借还按钮时弹出面板,构造参数包括要展示的输入项等;

建立SearchUI类,用于点击查找按钮时弹出查询面板,可以设置一些查询条件。SearchUI类中构造了ExtendedTable对象用于展示查询到的表格数据。

关键部分代码:

登录界面LoginShell:
protected void createContents(){loginShell = new Shell();loginShell.setSize(314, 187);loginShell.setText("\u767B\u5F55");loginShell.setMaximumSize(314, 187);loginShell.setMinimumSize(314, 187);Label label = new Label(loginShell, SWT.NONE);label.setBounds(31, 23, 40, 17);label.setText("\u8D26\u53F7");Label lblNewLabel = new Label(loginShell, SWT.NONE);lblNewLabel.setBounds(31, 69, 40, 17);lblNewLabel.setText("\u5BC6\u7801");Account_textField = new Text(loginShell, SWT.BORDER);Account_textField.setText("");Account_textField.setBounds(80, 20, 163, 23);Password_textField = new Text(loginShell, SWT.BORDER | SWT.PASSWORD);Password_textField.setText("");Password_textField.setBounds(80, 66, 163, 23);try {connection=DriverManager.getConnection("jdbc:mysql://localhost/Library","scott","tiger");statement=connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}Button LoginButton = new Button(loginShell, SWT.NONE);LoginButton.addSelectionListener(new SelectionAdapter() {@Overridepublic void widgetSelected(SelectionEvent e){//连接数据库try {					account=Account_textField.getText();password=Password_textField.getText();ResultSet resultSet=statement.executeQuery("select userpassword,userrole from users where userAccount='"+account+"'");resultSet.next();String queried_role;if(!account.equals("")) {if(!password.equals("")) {if(resultSet.getString(1).equals(password)) {switch (resultSet.getString(2)) {case "高级管理员":MainUI mainUI=new MainUI(account,"高级管理员",new String[] {"所有书籍","所有用户","所有借阅状态","我的借阅状态"},statement);break;case "普通管理员":mainUI=new MainUI(account,"普通管理员",new String[] {"所有书籍","所有借阅状态","我的借阅状态"},statement);break;case "普通用户":mainUI=new MainUI(account,"普通用户",new String[] {"所有书籍","我的借阅状态"},statement);break;default:break;}loginShell.close();MainUI.main(null);																}else {MessageBox messageBox=new MessageBox(loginShell,SWT.ICON_INFORMATION|SWT.OK);messageBox.setText("提示");messageBox.setMessage("用户名或密码错误,请重新输入!");int message=messageBox.open();}}else {MessageBox messageBox=new MessageBox(loginShell,SWT.ICON_INFORMATION|SWT.OK);messageBox.setText("提示");messageBox.setMessage("密码不能为空!");int message=messageBox.open();}}else {MessageBox messageBox=new MessageBox(loginShell,SWT.ICON_INFORMATION|SWT.OK);messageBox.setText("提示");messageBox.setMessage("用户名不能为空!");int message=messageBox.open();//e.doit=message==SWT.YES;return ;}} catch (Exception e2) {// TODO: handle exceptione2.printStackTrace();}}});LoginButton.setBounds(31, 106, 80, 27);LoginButton.setText("\u767B\u5F55");Button CancelButton = new Button(loginShell, SWT.NONE);CancelButton.addSelectionListener(new SelectionAdapter() {@Overridepublic void widgetSelected(SelectionEvent e) {loginShell.close();	}});CancelButton.setBounds(163, 106, 80, 27);CancelButton.setText("\u53D6\u6D88");}
MainUI:
protected void createContents() {shell = new Shell();shell.setSize(786,499);String userName="";try {resultSet= statement.executeQuery("select userName from users where userAccount='"+account+"'");resultSet.next();userName=resultSet.getString(1);} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}shell.setText("欢迎使用图书管理系统-"+account+"-"+userName+"("+role+")");shell.setMaximumSize(786, 500);shell.setMinimumSize(786,500);if(role.equals("高级管理员")) {Button settingBtn=new Button(shell,SWT.None);settingBtn.setText("设置");settingBtn.setBounds(410,10,80,27);settingBtn.addSelectionListener(new SelectionListener() {@Overridepublic void widgetSelected(SelectionEvent arg0) {// TODO Auto-generated method stubtry {					resultSet=statement.executeQuery("select * from settings");resultSet.next();String maxAllowedTotalBorrowCountStr=resultSet.getString(1);String maxAllowedSingleBorrowCountStr=resultSet.getString(2);//new OperationPanel(account,userName, operationStr,objectStr,tipStr,labelStrArray,defaultValuesArray,editAllowedArray, statement);OperationPanel settingOperationPanel=new OperationPanel("","","设置","","请输入以下选项",new String[] {"最大可借数量","单本最大可借数量"},new String[] {maxAllowedTotalBorrowCountStr,maxAllowedSingleBorrowCountStr},new Boolean[] {true,true},statement);settingOperationPanel.main(null);}catch (Exception e) {// TODO: handle exceptione.printStackTrace();}}@Overridepublic void widgetDefaultSelected(SelectionEvent arg0) {// TODO Auto-generated method stub}});}update();Button updateBtn = new Button(shell, SWT.NONE);updateBtn.setBounds(500, 10, 80, 27);updateBtn.setText("\u66F4\u65B0");updateBtn.addSelectionListener(new SelectionListener() {			@Overridepublic void widgetSelected(SelectionEvent arg0) {// TODO Auto-generated method stub//expandBar.setupdate();}			@Overridepublic void widgetDefaultSelected(SelectionEvent arg0) {// TODO Auto-generated method stub				}});Button BackwardBtn = new Button(shell, SWT.NONE);BackwardBtn.addSelectionListener(new SelectionAdapter() {@Overridepublic void widgetSelected(SelectionEvent e) {shell.close();LoginShell2 loginShell2=new LoginShell2();loginShell2.main(null);}});BackwardBtn.setBounds(590, 10, 80, 27);BackwardBtn.setText("\u8FD4\u56DE\u767B\u5F55\u9875\u9762");Button exitBtn = new Button(shell, SWT.NONE);exitBtn.addSelectionListener(new SelectionAdapter() {@Overridepublic void widgetSelected(SelectionEvent e) {shell.close();}});exitBtn.setBounds(680, 10, 80, 27);exitBtn.setText("退出");}	void update() {		if(expandBar!=null)expandBar.dispose();expandBar=new ExpandBar(shell, 0);expandBar.setBounds(10, 38, 750, 425);expandBar.addExpandListener(new ExpandListener() {		@Overridepublic void itemExpanded(ExpandEvent arg0) {// TODO Auto-generated method stubfor(ExpandItem item:expandBar.getItems()) {item.setExpanded(false);//这里循环设置其他扩展项关闭}}			@Overridepublic void itemCollapsed(ExpandEvent arg0) {// TODO Auto-generated method stub 这个不用管}});for(String expandItemStr:itemArray) {			String[] tableHeadersStrArray= {};String[] operationStrArray= {};String tableName="";switch (expandItemStr) {case "所有书籍":try {tableName="books";if (role.indexOf("管理员")!=-1)operationStrArray=new String[] {"添加","删除","修改","查找"};elseoperationStrArray=new String[] {"查找"};					tableHeadersStrArray=new String[] {"ISBN","书名","作者","类型","出版社","出版日期","馆藏数量","借出数量","未借出数量","状态","添加日期"};resultSet=statement.executeQuery("select isbn,bookName,author,bookType,publisher,publishDate,totalCount,borrowedCount,unborrowedCount,bookState,

相关文章:

  • Android之高级UI
  • 代码块01-Java
  • MySQL递归查询:洞悉数据的层层关联
  • flutter编译和构建鸿蒙应用程序(windows环境)
  • 卸载软件最最最彻底的工具——Uninstall Tool
  • 项目启动出现白屏问题需要刷新后才能显示解决方案
  • 通付盾Web3专题 | SharkTeam:起底朝鲜APT组织Lazarus Group,攻击手法及洗钱模式
  • 代码随想录算法训练营第五十三天|1143. 最长公共子序列、1035.不相交的线、53.最大子数组和
  • 实用高效 无人机光伏巡检系统助力电站可持续发展
  • 【代码随想录刷题】Day18 二叉树05
  • 【开源】基于Vue和SpringBoot的食品生产管理系统
  • 黑马点评Redis笔记
  • word因导入mathtype不能使用复制粘贴(ctrl+c, ctrl+v)快捷键的解决方法
  • oracle数据库巡检常见脚本-系列二
  • 注意力机制(Q,K,V)基本概念
  • C++类的相互关联
  • dva中组件的懒加载
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • Java反射-动态类加载和重新加载
  • JS实现简单的MVC模式开发小游戏
  • mockjs让前端开发独立于后端
  • Python爬虫--- 1.3 BS4库的解析器
  • spark本地环境的搭建到运行第一个spark程序
  • Spring框架之我见(三)——IOC、AOP
  • uni-app项目数字滚动
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 阿里云Kubernetes容器服务上体验Knative
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 技术胖1-4季视频复习— (看视频笔记)
  • 小程序button引导用户授权
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 原生JS动态加载JS、CSS文件及代码脚本
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 转载:[译] 内容加速黑科技趣谈
  • 字符串匹配基础上
  • 《天龙八部3D》Unity技术方案揭秘
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • ​【已解决】npm install​卡主不动的情况
  • #HarmonyOS:Web组件的使用
  • (1)SpringCloud 整合Python
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • .NET 5种线程安全集合
  • .NET BackgroundWorker
  • .NET gRPC 和RESTful简单对比
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • /*在DataTable中更新、删除数据*/
  • [autojs]逍遥模拟器和vscode对接
  • [BZOJ 4129]Haruna’s Breakfast(树上带修改莫队)
  • [C#]winform部署yolov5-onnx模型
  • [C#基础]说说lock到底锁谁?
  • [caffe(二)]Python加载训练caffe模型并进行测试1
  • [ComfyUI进阶教程] animatediff视频提示词书写要点
  • [Editor]Unity Editor类常用方法