跳转至主要内容

财务自由之路

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

工具:

IDE:Eclipse IDE for Java Developers-2023-09

数据库:MySQL 8

功能说明

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

  • 用户从登录窗口登录。用户身份有3种:高级管理员,普通管理员,普通用户。权限如下:
  1. 高级管理员具有所有权限,包括增、删、改、查书籍和用户,借书和还书,设置借阅数量限制,查看所有人的借阅记录;
  2. 普通管理员只能增、删、改、查书籍,借书,还书,查看所有人的借阅记录;
  3. 普通用户只能借书和还书,查看自己的借阅记录。

  • 所有用户和书籍均有正常和冻结两种状态。
  • 高级管理员可以设置所有用户和书籍的状态,普通管理员只可以设置书籍的状态。
  • 被冻结的用户只能进行还书和查询操作,被冻结的书籍只能被还而不能被借。

数据库设计

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

  1. 表books存储所有书籍的信息,包括ISBN(唯一标识)、书名、作者、书籍类型(文学、科学等)、出版社、出版日期、馆藏总数、借出数量、未借出数量、书籍状态(正常或冻结)和添加日期;
  2. 表users存储所有用户(包括高级管理员,普通管理员和普通用户)的信息,包括用户名、姓名、登录密码、身份类型(上述三种身份之一)、用户状态(正常或冻结)和添加日期;
  3. 表records存储用户的借还记录信息,包括操作时间、用户名、姓名、ISBN、书名、操作类型(借阅或归还)和操作数量;
  4. 表states存储用户借还书籍的状态信息,包括用户名、姓名、ISBN、书名、共借过该本书的数量、已还数量、未还数量。这里用户名和ISBN共同确定一条记录,某用户多次借还该本书会以累加的计算方法改变该条记录;
  5. 表settings只存储两个数,最大允许借阅总数和单本最大允许借阅数量,只能由高级管理员设置。

创建数据库:

create database Library;

各个表的字段信息设置如下所述。

books表

字段设置:

建表books语句:

create table books(bookId int not null auto_increment,isbn varchar(20) not null,bookName varchar(20) not null,author varchar(20),bookType varchar(10),publisher varchar(20),publishDate date, totalCount int not null,borrowedCount int not null default 0,unborrowedCount int,bookState varchar(2) default '正常',primary key (bookId))engine=innodb default charset=utf8;

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

users表

字段设置:

建表users语句:

create table users(userId int(5) not null auto_increment,userAccount char(8) not null,userName varchar(20) not null,userPassword varchar(20) not null,userRole varchar(5) not null default '普通用户',userState char(2) not null default '正常',primary key (userId))engine=innodb default charset=utf8;

由于需要登录使用,需要先预置一个高级管理员角色:

insert into users(userAccount,userName,userPassword,userRole) values('00000000','张三','password','高级管理员');

还可以手动添加其他用户。

users的几条记录:

records表

字段设置:

建表records语句:

create table records(operationId int not null auto_increment,operationDatetime datetime not null,userAccount char(8) not null,userName varchar(20),isbn varchar(20) not null,bookName varchar(20),operationType char(1) not null,operationCount int not null,primary key (operationId))engine=innodb default charset=utf8;

records的几条记录:

states表

字段设置:

建表states语句:

create table states(stateId int not null,userAccount char(8) not null,userName varchar(20),isbn varchar(20) not null,bookName varchar(20),borrowedCount int not null,returnedCount int not null,unReturnedCount int not null,primary key (stateId))engine=innodb default charset=utf8;

states的几条记录:

settings表

字段设置:

建表settings语句:

create table settings(maxAllowedTotalBorrowCount int not null,maxAllowedSingleBorrowCount int not null)engine=innodb default charset=utf8;

同样,settings的记录也需要预置:

insert into settings values(10,5);

settings存储的记录:

用户预置

需要预置一个数据库用户用于连接数据库,用户名为scott,密码为tiger,赋予所有权限:

create user 'scott' identified by 'tiger';
grant all privileges on *.* to 'scott'@'%' with grant option;

UI设计

登录窗口

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

主界面

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

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

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

 

 

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

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

上下文菜单

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

对话框

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

查询界面

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

类实现 

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

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

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

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

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

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

关键部分代码:

登录界面 LoginShell2

LoginShell2.java:

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;

//import java.beans.Statement;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Text;
//import org.eclipse.wb.swt.NormUserUI;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;

public class LoginShell2 {

	protected Shell loginShell;
	private Text Account_textField;
	private Text Password_textField;
	Connection connection;
	public Statement statement;
	String account;
	String password;
	//static Shell parentShell;
	/**
	 * Launch the application.
	 * @param args
	 */
	public static void main(String[] args){
		try {
			LoginShell2 window = new LoginShell2();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Open the window.
	 */
	public void open() {
		Display display = Display.getDefault();
		createContents();
		loginShell.open();
		loginShell.layout();
		while (!loginShell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	/**
	 * Create contents of the window.
	 */
	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("00000000");
		Account_textField.setBounds(80, 20, 163, 23);
		
		Password_textField = new Text(loginShell, SWT.BORDER | SWT.PASSWORD);
		Password_textField.setText("password");
		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 exception
			e.printStackTrace();
		}
		
		Button LoginButton = new Button(loginShell, SWT.NONE);
		LoginButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e){
				//连接数据库
				try {
					//Class.forName("com.mysql.jdbc.Driver");
					//Class.forName("om.mysql.cj.jdbc.Driver");
					//Connection connection=DriverManager.getConnection("jdbc:mysql://localhost/Library","scott","tiger");
					//Statement statement=connection.createStatement();
					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 exception
					e2.printStackTrace();
				}
			}
		});
		LoginButton.setBounds(31, 106, 80, 27);
		LoginButton.setText("\u767B\u5F55");
		
		Button CancelButton = new Button(loginShell, SWT.NONE);
		CancelButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				loginShell.close();	
			}
		});
		CancelButton.setBounds(163, 106, 80, 27);
		CancelButton.setText("\u53D6\u6D88");

	}

}

主界面 MainUI

MainUI.java:

import java.sql.ResultSet;
import java.sql.Statement;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ExpandEvent;
import org.eclipse.swt.events.ExpandListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ExpandBar;
import org.eclipse.swt.widgets.ExpandItem;
import org.eclipse.swt.widgets.Shell;

public class MainUI {

	protected Shell shell;
	static String account="";
	static String role="";
	static String[] itemArray= {};
	static ResultSet resultSet=null;
	static Statement statement=null;
	Composite itemComposite=null;
	ExpandBar expandBar=null;
	public MainUI(String newAccount,String newRole,String [] newItemArray,Statement newStatement) {
		// TODO Auto-generated constructor stub
		account=newAccount;
		role=newRole;
		itemArray=newItemArray;
		//resultSet=newResultSet;
		statement=newStatement;		
	}

	/**
	 * Launch the application.
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			MainUI window = new MainUI(account,role,itemArray,statement);
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * Open the window.
	 */
	public void open() {
		Display display = Display.getDefault();
		createContents();
		shell.open();
		shell.layout();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	/**
	 * Create contents of the window.
	 */
	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 exception
			e.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() {
				
				@Override
				public void widgetSelected(SelectionEvent arg0) {
					// TODO Auto-generated method stub
					try {					
						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 exception
						e.printStackTrace();
					}
				}
				
				@Override
				public 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() {			
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				// TODO Auto-generated method stub
				//expandBar.set
				update();
			}			
			@Override
			public void widgetDefaultSelected(SelectionEvent arg0) {
				// TODO Auto-generated method stub				
			}
		});
		Button BackwardBtn = new Button(shell, SWT.NONE);
		BackwardBtn.addSelectionListener(new SelectionAdapter() {
			@Override
			public 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() {
			@Override
			public 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() {		
			@Override
			public void itemExpanded(ExpandEvent arg0) {
				// TODO Auto-generated method stub
				for(ExpandItem item:expandBar.getItems()) {
					item.setExpanded(false);//这里循环设置其他扩展项关闭
				}
			}			
			@Override
			public 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[] {"添加","删除","修改","查找"};
					else
						operationStrArray=new String[] {"查找"};					
					tableHeadersStrArray=new String[] {"ISBN","书名","作者","类型","出版社","出版日期","馆藏数量","借出数量","未借出数量","状态","添加日期"};
					resultSet=statement.executeQuery("select isbn,bookName,author,bookType,publisher,publishDate,totalCount,borrowedCount,unborrowedCount,bookState,addBookDate from books");
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}				
				break;
			case "所有用户":
				try {
					tableName="users";
					operationStrArray=new String[] {"添加","删除","修改","查找"};
					tableHeadersStrArray=new String[] {"用户名","姓名","密码","身份","状态","添加日期"};
					resultSet=statement.executeQuery("select userAccount,userName,userPassword,userRole,userState,addUserDate from users");				
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
				break;
				
			case "所有借阅状态":
				try {
					tableName="states";
					operationStrArray=new String[] {"查找"};
					tableHeadersStrArray=new String[] {"用户名","姓名","ISBN","书名","共借","已还","未还"};
					resultSet=statement.executeQuery("select userAccount,userName,isbn,bookName,borrowedCount,returnedCount,unReturnedCount from states");
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
				break;
			case "我的借阅状态":
				try {
					tableName="mystates";
					operationStrArray=new String[] {"查找"};
					tableHeadersStrArray=new String[] {"用户名","姓名","ISBN","书名","共借","已还","未还"};
					resultSet=statement.executeQuery("select userAccount,userName,isbn,bookName,borrowedCount,returnedCount,unReturnedCount from states where userAccount='"+account+"'");
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
				break;
			default:
				break;
			}
			itemComposite=new Composite(expandBar, 0);
			//OperationComposite(Composite parent, int style,String newAccount,String newRole,String tableName,String[] btnStrArray,String[] tableHeadersStrArray,String [] contextStrArray,ResultSet resultSet,Statement newStatement) {
			new OperationComposite(shell, itemComposite, SWT.MULTI,account,role, tableName,operationStrArray,tableHeadersStrArray, resultSet,statement);
			ExpandItem expandItem=new ExpandItem(expandBar, 0);			
			expandItem.setControl(itemComposite);
			expandItem.setHeight(310);
			expandItem.setText(expandItemStr);
			if(expandItemStr.equals("所有书籍"))
				expandItem.setExpanded(true);
		}
	}

}
支付 ¥10 购买本节后解锁剩余59%的内容
分类:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注