|
|
|
@ -0,0 +1,706 @@
|
|
|
|
|
import javax.swing.*;
|
|
|
|
|
import javax.swing.table.DefaultTableModel;
|
|
|
|
|
import java.awt.*;
|
|
|
|
|
import java.awt.event.*;
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
|
|
|
|
|
//系统主界面
|
|
|
|
|
public class LibrarySystemGUI extends JFrame {
|
|
|
|
|
// 核心业务逻辑对象,处理图书、用户和借阅相关操作
|
|
|
|
|
private Library library;
|
|
|
|
|
// 当前登录用户
|
|
|
|
|
private User currentUser;
|
|
|
|
|
|
|
|
|
|
// 主面板,使用CardLayout实现面板切换(登录/注册/用户/管理员界面)
|
|
|
|
|
private JPanel mainPanel;
|
|
|
|
|
|
|
|
|
|
// 登录面板及组件
|
|
|
|
|
private JPanel loginPanel;
|
|
|
|
|
private JTextField usernameField; // 用户名输入框
|
|
|
|
|
private JPasswordField passwordField; // 密码输入框
|
|
|
|
|
|
|
|
|
|
// 注册面板及组件
|
|
|
|
|
private JPanel registerPanel;
|
|
|
|
|
private JTextField regUsernameField; // 注册用户名输入框
|
|
|
|
|
private JPasswordField regPasswordField;// 注册密码输入框
|
|
|
|
|
private JTextField regEmailField; // 注册邮箱输入框
|
|
|
|
|
private JTextField regPhoneField; // 注册电话输入框
|
|
|
|
|
|
|
|
|
|
// 用户主面板及组件
|
|
|
|
|
private JPanel userPanel;
|
|
|
|
|
private JTextField searchField; // 图书搜索框
|
|
|
|
|
private JTable booksTable; // 图书列表表格
|
|
|
|
|
private DefaultTableModel booksTableModel; // 图书表格数据模型
|
|
|
|
|
private JTable borrowedBooksTable; // 已借图书表格
|
|
|
|
|
private DefaultTableModel borrowedBooksTableModel; // 已借图书表格数据模型
|
|
|
|
|
|
|
|
|
|
// 管理员面板及组件
|
|
|
|
|
private JPanel adminPanel;
|
|
|
|
|
private JTable allBooksTable; // 所有图书表格(管理员用)
|
|
|
|
|
private DefaultTableModel allBooksTableModel; // 所有图书表格数据模型
|
|
|
|
|
private JTable usersTable; // 用户列表表格(管理员用)
|
|
|
|
|
private DefaultTableModel usersTableModel; // 用户表格数据模型
|
|
|
|
|
// 添加图书的输入框
|
|
|
|
|
private JTextField addBookTitleField;
|
|
|
|
|
private JTextField addBookAuthorField;
|
|
|
|
|
private JTextField addBookPublisherField;
|
|
|
|
|
private JTextField addBookYearField;
|
|
|
|
|
private JTextField addBookCategoryField;
|
|
|
|
|
|
|
|
|
|
//初始化界面并加载数据
|
|
|
|
|
public LibrarySystemGUI() {
|
|
|
|
|
super("在线图书管理系统"); // 设置窗口标题
|
|
|
|
|
setSize(900, 600); // 设置窗口大小
|
|
|
|
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭窗口时退出程序
|
|
|
|
|
setLocationRelativeTo(null); // 窗口居中显示
|
|
|
|
|
|
|
|
|
|
// 初始化图书馆业务对象(会自动加载文件中的数据)
|
|
|
|
|
library = new Library();
|
|
|
|
|
|
|
|
|
|
// 初始化所有界面组件
|
|
|
|
|
initComponents();
|
|
|
|
|
// 默认显示登录面板
|
|
|
|
|
showLoginPanel();
|
|
|
|
|
|
|
|
|
|
// 窗口关闭时保存所有数据到文件
|
|
|
|
|
addWindowListener(new WindowAdapter() {
|
|
|
|
|
@Override
|
|
|
|
|
public void windowClosing(WindowEvent e) {
|
|
|
|
|
library.saveAllData();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//初始化所有界面组件
|
|
|
|
|
private void initComponents() {
|
|
|
|
|
mainPanel = new JPanel(new CardLayout());
|
|
|
|
|
|
|
|
|
|
// 初始化各功能面板
|
|
|
|
|
initLoginPanel();
|
|
|
|
|
initRegisterPanel();
|
|
|
|
|
initUserPanel();
|
|
|
|
|
initAdminPanel();
|
|
|
|
|
|
|
|
|
|
// 将所有面板添加到主面板(用于切换显示)
|
|
|
|
|
mainPanel.add(loginPanel, "login");
|
|
|
|
|
mainPanel.add(registerPanel, "register");
|
|
|
|
|
mainPanel.add(userPanel, "user");
|
|
|
|
|
mainPanel.add(adminPanel, "admin");
|
|
|
|
|
|
|
|
|
|
// 将主面板添加到窗口
|
|
|
|
|
add(mainPanel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//登陆面板
|
|
|
|
|
private void initLoginPanel() {
|
|
|
|
|
loginPanel = new JPanel(new GridBagLayout());
|
|
|
|
|
GridBagConstraints gbc = new GridBagConstraints();
|
|
|
|
|
gbc.insets = new Insets(5, 5, 5, 5); // 组件间距
|
|
|
|
|
gbc.anchor = GridBagConstraints.WEST; // 组件左对齐
|
|
|
|
|
|
|
|
|
|
// 标题
|
|
|
|
|
JLabel titleLabel = new JLabel("在线图书管理系统");
|
|
|
|
|
titleLabel.setFont(new Font("宋体", Font.BOLD, 24));
|
|
|
|
|
gbc.gridx = 0;
|
|
|
|
|
gbc.gridy = 0;
|
|
|
|
|
gbc.gridwidth = 2; // 跨两列
|
|
|
|
|
gbc.anchor = GridBagConstraints.CENTER; // 居中对齐
|
|
|
|
|
loginPanel.add(titleLabel, gbc);
|
|
|
|
|
|
|
|
|
|
// 重置约束
|
|
|
|
|
gbc.anchor = GridBagConstraints.WEST;
|
|
|
|
|
gbc.gridwidth = 1;
|
|
|
|
|
gbc.gridy++;
|
|
|
|
|
|
|
|
|
|
// 用户名输入区
|
|
|
|
|
JLabel usernameLabel = new JLabel("用户名:");
|
|
|
|
|
loginPanel.add(usernameLabel, gbc);
|
|
|
|
|
|
|
|
|
|
gbc.gridx = 1;
|
|
|
|
|
usernameField = new JTextField(20);
|
|
|
|
|
loginPanel.add(usernameField, gbc);
|
|
|
|
|
|
|
|
|
|
// 密码输入区
|
|
|
|
|
gbc.gridx = 0;
|
|
|
|
|
gbc.gridy++;
|
|
|
|
|
JLabel passwordLabel = new JLabel("密码:");
|
|
|
|
|
loginPanel.add(passwordLabel, gbc);
|
|
|
|
|
|
|
|
|
|
gbc.gridx = 1;
|
|
|
|
|
passwordField = new JPasswordField(20);
|
|
|
|
|
loginPanel.add(passwordField, gbc);
|
|
|
|
|
|
|
|
|
|
// 按钮区
|
|
|
|
|
gbc.gridx = 0;
|
|
|
|
|
gbc.gridy++;
|
|
|
|
|
gbc.gridwidth = 2;
|
|
|
|
|
gbc.anchor = GridBagConstraints.CENTER;
|
|
|
|
|
JPanel buttonPanel = new JPanel();
|
|
|
|
|
|
|
|
|
|
JButton loginButton = new JButton("登录");
|
|
|
|
|
loginButton.addActionListener(e -> handleLogin()); // 绑定登录事件
|
|
|
|
|
buttonPanel.add(loginButton);
|
|
|
|
|
|
|
|
|
|
JButton registerButton = new JButton("注册");
|
|
|
|
|
registerButton.addActionListener(e -> showRegisterPanel()); // 绑定注册面板显示事件
|
|
|
|
|
buttonPanel.add(registerButton);
|
|
|
|
|
|
|
|
|
|
loginPanel.add(buttonPanel, gbc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//注册面板
|
|
|
|
|
private void initRegisterPanel() {
|
|
|
|
|
registerPanel = new JPanel(new GridBagLayout());
|
|
|
|
|
GridBagConstraints gbc = new GridBagConstraints();
|
|
|
|
|
gbc.insets = new Insets(5, 5, 5, 5);
|
|
|
|
|
gbc.anchor = GridBagConstraints.WEST;
|
|
|
|
|
|
|
|
|
|
// 标题
|
|
|
|
|
JLabel titleLabel = new JLabel("用户注册");
|
|
|
|
|
titleLabel.setFont(new Font("宋体", Font.BOLD, 18));
|
|
|
|
|
gbc.gridx = 0;
|
|
|
|
|
gbc.gridy = 0;
|
|
|
|
|
gbc.gridwidth = 2;
|
|
|
|
|
gbc.anchor = GridBagConstraints.CENTER;
|
|
|
|
|
registerPanel.add(titleLabel, gbc);
|
|
|
|
|
|
|
|
|
|
// 重置约束
|
|
|
|
|
gbc.anchor = GridBagConstraints.WEST;
|
|
|
|
|
gbc.gridwidth = 1;
|
|
|
|
|
gbc.gridy++;
|
|
|
|
|
|
|
|
|
|
// 用户名输入
|
|
|
|
|
JLabel usernameLabel = new JLabel("用户名:");
|
|
|
|
|
registerPanel.add(usernameLabel, gbc);
|
|
|
|
|
|
|
|
|
|
gbc.gridx = 1;
|
|
|
|
|
regUsernameField = new JTextField(20);
|
|
|
|
|
registerPanel.add(regUsernameField, gbc);
|
|
|
|
|
|
|
|
|
|
// 密码输入
|
|
|
|
|
gbc.gridx = 0;
|
|
|
|
|
gbc.gridy++;
|
|
|
|
|
JLabel passwordLabel = new JLabel("密码:");
|
|
|
|
|
registerPanel.add(passwordLabel, gbc);
|
|
|
|
|
|
|
|
|
|
gbc.gridx = 1;
|
|
|
|
|
regPasswordField = new JPasswordField(20);
|
|
|
|
|
registerPanel.add(regPasswordField, gbc);
|
|
|
|
|
|
|
|
|
|
// 邮箱输入
|
|
|
|
|
gbc.gridx = 0;
|
|
|
|
|
gbc.gridy++;
|
|
|
|
|
JLabel emailLabel = new JLabel("邮箱:");
|
|
|
|
|
registerPanel.add(emailLabel, gbc);
|
|
|
|
|
|
|
|
|
|
gbc.gridx = 1;
|
|
|
|
|
regEmailField = new JTextField(20);
|
|
|
|
|
registerPanel.add(regEmailField, gbc);
|
|
|
|
|
|
|
|
|
|
// 电话输入
|
|
|
|
|
gbc.gridx = 0;
|
|
|
|
|
gbc.gridy++;
|
|
|
|
|
JLabel phoneLabel = new JLabel("电话:");
|
|
|
|
|
registerPanel.add(phoneLabel, gbc);
|
|
|
|
|
|
|
|
|
|
gbc.gridx = 1;
|
|
|
|
|
regPhoneField = new JTextField(20);
|
|
|
|
|
registerPanel.add(regPhoneField, gbc);
|
|
|
|
|
|
|
|
|
|
// 按钮区
|
|
|
|
|
gbc.gridx = 0;
|
|
|
|
|
gbc.gridy++;
|
|
|
|
|
gbc.gridwidth = 2;
|
|
|
|
|
gbc.anchor = GridBagConstraints.CENTER;
|
|
|
|
|
JPanel buttonPanel = new JPanel();
|
|
|
|
|
|
|
|
|
|
JButton registerButton = new JButton("注册");
|
|
|
|
|
registerButton.addActionListener(e -> handleRegister()); // 绑定注册事件
|
|
|
|
|
buttonPanel.add(registerButton);
|
|
|
|
|
|
|
|
|
|
JButton backButton = new JButton("返回");
|
|
|
|
|
backButton.addActionListener(e -> showLoginPanel()); // 绑定返回登录事件
|
|
|
|
|
buttonPanel.add(backButton);
|
|
|
|
|
|
|
|
|
|
registerPanel.add(buttonPanel, gbc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//初始化普通用户面板
|
|
|
|
|
private void initUserPanel() {
|
|
|
|
|
userPanel = new JPanel(new BorderLayout());
|
|
|
|
|
|
|
|
|
|
// 顶部面板 - 标题和搜索区
|
|
|
|
|
JPanel topPanel = new JPanel(new BorderLayout());
|
|
|
|
|
|
|
|
|
|
JLabel titleLabel = new JLabel("图书管理系统 - 用户界面", SwingConstants.CENTER);
|
|
|
|
|
titleLabel.setFont(new Font("宋体", Font.BOLD, 18));
|
|
|
|
|
topPanel.add(titleLabel, BorderLayout.NORTH);
|
|
|
|
|
|
|
|
|
|
// 搜索面板
|
|
|
|
|
JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
|
|
|
|
searchField = new JTextField(30);
|
|
|
|
|
JButton searchButton = new JButton("搜索图书");
|
|
|
|
|
searchButton.addActionListener(e -> searchBooks()); // 绑定搜索事件
|
|
|
|
|
|
|
|
|
|
JButton refreshButton = new JButton("显示所有图书");
|
|
|
|
|
refreshButton.addActionListener(e -> refreshBooksTable()); // 绑定刷新事件
|
|
|
|
|
|
|
|
|
|
JButton logoutButton = new JButton("退出登录");
|
|
|
|
|
logoutButton.addActionListener(e -> logout()); // 绑定退出事件
|
|
|
|
|
|
|
|
|
|
searchPanel.add(new JLabel("搜索: "));
|
|
|
|
|
searchPanel.add(searchField);
|
|
|
|
|
searchPanel.add(searchButton);
|
|
|
|
|
searchPanel.add(refreshButton);
|
|
|
|
|
searchPanel.add(logoutButton);
|
|
|
|
|
|
|
|
|
|
topPanel.add(searchPanel, BorderLayout.SOUTH);
|
|
|
|
|
userPanel.add(topPanel, BorderLayout.NORTH);
|
|
|
|
|
|
|
|
|
|
// 中间分割面板(上下分栏)
|
|
|
|
|
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
|
|
|
|
|
|
|
|
|
|
// 图书列表区域
|
|
|
|
|
JPanel booksPanel = new JPanel(new BorderLayout());
|
|
|
|
|
booksPanel.setBorder(BorderFactory.createTitledBorder("图书列表"));
|
|
|
|
|
|
|
|
|
|
// 图书表格列名
|
|
|
|
|
String[] booksColumnNames = {"ID", "标题", "作者", "出版社", "年份", "类别", "状态"};
|
|
|
|
|
booksTableModel = new DefaultTableModel(booksColumnNames, 0) {
|
|
|
|
|
// 表格不可编辑
|
|
|
|
|
@Override
|
|
|
|
|
public boolean isCellEditable(int row, int column) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
booksTable = new JTable(booksTableModel);
|
|
|
|
|
booksTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // 单选模式
|
|
|
|
|
JScrollPane booksScrollPane = new JScrollPane(booksTable); // 滚动面板
|
|
|
|
|
booksPanel.add(booksScrollPane, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
|
|
// 借阅按钮
|
|
|
|
|
JButton borrowButton = new JButton("借阅选中图书");
|
|
|
|
|
borrowButton.addActionListener(e -> borrowSelectedBook()); // 绑定借阅事件
|
|
|
|
|
booksPanel.add(borrowButton, BorderLayout.SOUTH);
|
|
|
|
|
|
|
|
|
|
// 已借图书区域
|
|
|
|
|
JPanel borrowedPanel = new JPanel(new BorderLayout());
|
|
|
|
|
borrowedPanel.setBorder(BorderFactory.createTitledBorder("我的借阅"));
|
|
|
|
|
|
|
|
|
|
// 已借图书表格列名
|
|
|
|
|
String[] borrowedColumnNames = {"ID", "标题", "作者", "借阅日期", "应还日期", "状态"};
|
|
|
|
|
borrowedBooksTableModel = new DefaultTableModel(borrowedColumnNames, 0) {
|
|
|
|
|
@Override
|
|
|
|
|
public boolean isCellEditable(int row, int column) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
borrowedBooksTable = new JTable(borrowedBooksTableModel);
|
|
|
|
|
borrowedBooksTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
|
|
|
|
JScrollPane borrowedScrollPane = new JScrollPane(borrowedBooksTable);
|
|
|
|
|
borrowedPanel.add(borrowedScrollPane, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
|
|
// 归还按钮
|
|
|
|
|
JButton returnButton = new JButton("归还选中图书");
|
|
|
|
|
returnButton.addActionListener(e -> returnSelectedBook()); // 绑定归还事件
|
|
|
|
|
borrowedPanel.add(returnButton, BorderLayout.SOUTH);
|
|
|
|
|
|
|
|
|
|
// 设置分割面板内容
|
|
|
|
|
splitPane.setTopComponent(booksPanel);
|
|
|
|
|
splitPane.setBottomComponent(borrowedPanel);
|
|
|
|
|
splitPane.setDividerLocation(250); // 分割位置
|
|
|
|
|
|
|
|
|
|
userPanel.add(splitPane, BorderLayout.CENTER);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//管理员面板
|
|
|
|
|
private void initAdminPanel() {
|
|
|
|
|
adminPanel = new JPanel(new BorderLayout());
|
|
|
|
|
|
|
|
|
|
// 顶部面板
|
|
|
|
|
JPanel topPanel = new JPanel(new BorderLayout());
|
|
|
|
|
|
|
|
|
|
JLabel titleLabel = new JLabel("图书管理系统 - 管理员界面", SwingConstants.CENTER);
|
|
|
|
|
titleLabel.setFont(new Font("宋体", Font.BOLD, 18));
|
|
|
|
|
topPanel.add(titleLabel, BorderLayout.NORTH);
|
|
|
|
|
|
|
|
|
|
// 退出按钮
|
|
|
|
|
JButton logoutButton = new JButton("退出登录");
|
|
|
|
|
logoutButton.addActionListener(e -> logout());
|
|
|
|
|
JPanel logoutPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
|
|
|
|
logoutPanel.add(logoutButton);
|
|
|
|
|
topPanel.add(logoutPanel, BorderLayout.SOUTH);
|
|
|
|
|
|
|
|
|
|
adminPanel.add(topPanel, BorderLayout.NORTH);
|
|
|
|
|
|
|
|
|
|
// 中间分割面板(左右分栏)
|
|
|
|
|
JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
|
|
|
|
|
|
|
|
|
|
// 左侧 - 书籍管理
|
|
|
|
|
JPanel booksManagementPanel = new JPanel(new BorderLayout());
|
|
|
|
|
booksManagementPanel.setBorder(BorderFactory.createTitledBorder("书籍管理"));
|
|
|
|
|
|
|
|
|
|
// 图书表格
|
|
|
|
|
String[] booksColumnNames = {"ID", "标题", "作者", "出版社", "年份", "类别", "状态"};
|
|
|
|
|
allBooksTableModel = new DefaultTableModel(booksColumnNames, 0) {
|
|
|
|
|
@Override
|
|
|
|
|
public boolean isCellEditable(int row, int column) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
allBooksTable = new JTable(allBooksTableModel);
|
|
|
|
|
JScrollPane booksScrollPane = new JScrollPane(allBooksTable);
|
|
|
|
|
booksManagementPanel.add(booksScrollPane, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
|
|
// 添加书籍面板
|
|
|
|
|
JPanel addBookPanel = new JPanel(new GridLayout(2, 6, 5, 5));
|
|
|
|
|
addBookPanel.setBorder(BorderFactory.createTitledBorder("添加新书籍"));
|
|
|
|
|
|
|
|
|
|
addBookPanel.add(new JLabel("标题:"));
|
|
|
|
|
addBookTitleField = new JTextField();
|
|
|
|
|
addBookPanel.add(addBookTitleField);
|
|
|
|
|
|
|
|
|
|
addBookPanel.add(new JLabel("作者:"));
|
|
|
|
|
addBookAuthorField = new JTextField();
|
|
|
|
|
addBookPanel.add(addBookAuthorField);
|
|
|
|
|
|
|
|
|
|
addBookPanel.add(new JLabel("出版社:"));
|
|
|
|
|
addBookPublisherField = new JTextField();
|
|
|
|
|
addBookPanel.add(addBookPublisherField);
|
|
|
|
|
|
|
|
|
|
addBookPanel.add(new JLabel("年份:"));
|
|
|
|
|
addBookYearField = new JTextField();
|
|
|
|
|
addBookPanel.add(addBookYearField);
|
|
|
|
|
|
|
|
|
|
addBookPanel.add(new JLabel("类别:"));
|
|
|
|
|
addBookCategoryField = new JTextField();
|
|
|
|
|
addBookPanel.add(addBookCategoryField);
|
|
|
|
|
|
|
|
|
|
JButton addBookButton = new JButton("添加书籍");
|
|
|
|
|
addBookButton.addActionListener(e -> addNewBook()); // 绑定添加书籍事件
|
|
|
|
|
addBookPanel.add(addBookButton);
|
|
|
|
|
|
|
|
|
|
booksManagementPanel.add(addBookPanel, BorderLayout.SOUTH);
|
|
|
|
|
|
|
|
|
|
// 右侧 - 用户管理
|
|
|
|
|
JPanel usersManagementPanel = new JPanel(new BorderLayout());
|
|
|
|
|
usersManagementPanel.setBorder(BorderFactory.createTitledBorder("用户管理"));
|
|
|
|
|
|
|
|
|
|
// 用户表格
|
|
|
|
|
String[] usersColumnNames = {"ID", "用户名", "邮箱", "电话", "角色"};
|
|
|
|
|
usersTableModel = new DefaultTableModel(usersColumnNames, 0) {
|
|
|
|
|
@Override
|
|
|
|
|
public boolean isCellEditable(int row, int column) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
usersTable = new JTable(usersTableModel);
|
|
|
|
|
JScrollPane usersScrollPane = new JScrollPane(usersTable);
|
|
|
|
|
usersManagementPanel.add(usersScrollPane, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
|
|
// 设置分割面板内容
|
|
|
|
|
mainSplitPane.setLeftComponent(booksManagementPanel);
|
|
|
|
|
mainSplitPane.setRightComponent(usersManagementPanel);
|
|
|
|
|
mainSplitPane.setDividerLocation(450);
|
|
|
|
|
|
|
|
|
|
adminPanel.add(mainSplitPane, BorderLayout.CENTER);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//处理用户登录
|
|
|
|
|
private void handleLogin() {
|
|
|
|
|
String username = usernameField.getText().trim();
|
|
|
|
|
String password = new String(passwordField.getPassword()).trim();
|
|
|
|
|
|
|
|
|
|
// 验证输入不为空
|
|
|
|
|
if (username.isEmpty() || password.isEmpty()) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "请输入用户名和密码", "提示", JOptionPane.WARNING_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 调用图书馆业务逻辑进行登录验证
|
|
|
|
|
currentUser = library.login(username, password);
|
|
|
|
|
if (currentUser == null) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "用户名或密码错误", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查是否有逾期书籍并提醒
|
|
|
|
|
List<Book> overdueBooks = library.checkOverdueBooks(currentUser.getId());
|
|
|
|
|
if (!overdueBooks.isEmpty()) {
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
sb.append("您有").append(overdueBooks.size()).append("本图书已逾期:\n");
|
|
|
|
|
for (Book book : overdueBooks) {
|
|
|
|
|
sb.append("- ").append(book.getTitle()).append("\n");
|
|
|
|
|
}
|
|
|
|
|
sb.append("请尽快归还!");
|
|
|
|
|
JOptionPane.showMessageDialog(this, sb.toString(), "逾期提醒", JOptionPane.WARNING_MESSAGE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据用户角色显示对应界面
|
|
|
|
|
if (currentUser.isAdmin()) {
|
|
|
|
|
refreshAdminPanelData();
|
|
|
|
|
showAdminPanel();
|
|
|
|
|
} else {
|
|
|
|
|
refreshUserPanelData();
|
|
|
|
|
showUserPanel();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//用户注册
|
|
|
|
|
private void handleRegister() {
|
|
|
|
|
String username = regUsernameField.getText().trim();
|
|
|
|
|
String password = new String(regPasswordField.getPassword()).trim();
|
|
|
|
|
String email = regEmailField.getText().trim();
|
|
|
|
|
String phone = regPhoneField.getText().trim();
|
|
|
|
|
|
|
|
|
|
// 验证输入完整性
|
|
|
|
|
if (username.isEmpty() || password.isEmpty() || email.isEmpty() || phone.isEmpty()) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "请填写所有字段", "提示", JOptionPane.WARNING_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 调用业务逻辑注册用户
|
|
|
|
|
boolean success = library.registerUser(username, password, email, phone);
|
|
|
|
|
if (success) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "注册成功,请登录", "成功", JOptionPane.INFORMATION_MESSAGE);
|
|
|
|
|
showLoginPanel();
|
|
|
|
|
|
|
|
|
|
// 清空注册表单
|
|
|
|
|
regUsernameField.setText("");
|
|
|
|
|
regPasswordField.setText("");
|
|
|
|
|
regEmailField.setText("");
|
|
|
|
|
regPhoneField.setText("");
|
|
|
|
|
} else {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "用户名已存在", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//搜索图书(按标题、作者或类别)
|
|
|
|
|
private void searchBooks() {
|
|
|
|
|
String keyword = searchField.getText().trim();
|
|
|
|
|
if (keyword.isEmpty()) {
|
|
|
|
|
refreshBooksTable(); // 空关键词时显示所有图书
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 调用业务逻辑搜索图书
|
|
|
|
|
List<Book> results = library.searchBooks(keyword);
|
|
|
|
|
updateBooksTable(results);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//刷新列表
|
|
|
|
|
private void refreshBooksTable() {
|
|
|
|
|
List<Book> allBooks = library.getAllBooks();
|
|
|
|
|
updateBooksTable(allBooks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//更新图书表格数据
|
|
|
|
|
private void updateBooksTable(List<Book> books) {
|
|
|
|
|
booksTableModel.setRowCount(0); // 清空表格
|
|
|
|
|
for (Book book : books) {
|
|
|
|
|
// 构造表格行数据
|
|
|
|
|
Object[] row = {
|
|
|
|
|
book.getId(),
|
|
|
|
|
book.getTitle(),
|
|
|
|
|
book.getAuthor(),
|
|
|
|
|
book.getPublisher(),
|
|
|
|
|
book.getPublicationYear(),
|
|
|
|
|
book.getCategory(),
|
|
|
|
|
book.isAvailable() ? "可借阅" : "已借出"
|
|
|
|
|
};
|
|
|
|
|
booksTableModel.addRow(row);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//更新借阅图书数据
|
|
|
|
|
private void updateBorrowedBooksTable() {
|
|
|
|
|
borrowedBooksTableModel.setRowCount(0); // 清空表格
|
|
|
|
|
List<Book> borrowedBooks = library.getUserBorrowedBooks(currentUser.getId());
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
Date today = new Date();
|
|
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
|
|
|
|
|
|
|
for (Book book : borrowedBooks) {
|
|
|
|
|
String status = "正常";
|
|
|
|
|
// 检查是否逾期
|
|
|
|
|
if (!book.getDueDate().isEmpty()) {
|
|
|
|
|
Date dueDate = sdf.parse(book.getDueDate());
|
|
|
|
|
if (dueDate.before(today)) {
|
|
|
|
|
status = "已逾期";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构造表格行数据
|
|
|
|
|
Object[] row = {
|
|
|
|
|
book.getId(),
|
|
|
|
|
book.getTitle(),
|
|
|
|
|
book.getAuthor(),
|
|
|
|
|
book.getBorrowDate(),
|
|
|
|
|
book.getDueDate(),
|
|
|
|
|
status
|
|
|
|
|
};
|
|
|
|
|
borrowedBooksTableModel.addRow(row);
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//借阅选中的图书
|
|
|
|
|
private void borrowSelectedBook() {
|
|
|
|
|
int selectedRow = booksTable.getSelectedRow();
|
|
|
|
|
if (selectedRow == -1) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "请先选择一本图书", "提示", JOptionPane.WARNING_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取选中图书的ID
|
|
|
|
|
String bookId = (String) booksTableModel.getValueAt(selectedRow, 0);
|
|
|
|
|
// 调用业务逻辑借阅图书
|
|
|
|
|
boolean success = library.borrowBook(currentUser.getId(), bookId);
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "借阅成功", "成功", JOptionPane.INFORMATION_MESSAGE);
|
|
|
|
|
refreshUserPanelData(); // 刷新界面数据
|
|
|
|
|
} else {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "借阅失败,该书可能已被借出", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//归还选中的图书
|
|
|
|
|
private void returnSelectedBook() {
|
|
|
|
|
int selectedRow = borrowedBooksTable.getSelectedRow();
|
|
|
|
|
if (selectedRow == -1) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "请先选择一本要归还的图书", "提示", JOptionPane.WARNING_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取选中图书的ID
|
|
|
|
|
String bookId = (String) borrowedBooksTableModel.getValueAt(selectedRow, 0);
|
|
|
|
|
// 调用业务逻辑归还图书
|
|
|
|
|
boolean success = library.returnBook(bookId);
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "归还成功", "成功", JOptionPane.INFORMATION_MESSAGE);
|
|
|
|
|
refreshUserPanelData(); // 刷新界面数据
|
|
|
|
|
} else {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "归还失败", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//添加新书籍
|
|
|
|
|
private void addNewBook() {
|
|
|
|
|
String title = addBookTitleField.getText().trim();
|
|
|
|
|
String author = addBookAuthorField.getText().trim();
|
|
|
|
|
String publisher = addBookPublisherField.getText().trim();
|
|
|
|
|
String yearStr = addBookYearField.getText().trim();
|
|
|
|
|
String category = addBookCategoryField.getText().trim();
|
|
|
|
|
|
|
|
|
|
// 验证输入完整性
|
|
|
|
|
if (title.isEmpty() || author.isEmpty() || publisher.isEmpty() || yearStr.isEmpty() || category.isEmpty()) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "请填写所有字段", "提示", JOptionPane.WARNING_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 验证年份格式
|
|
|
|
|
int year;
|
|
|
|
|
try {
|
|
|
|
|
year = Integer.parseInt(yearStr);
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "请输入有效的年份", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 调用业务逻辑添加图书
|
|
|
|
|
library.addBook(title, author, publisher, year, category);
|
|
|
|
|
JOptionPane.showMessageDialog(this, "书籍添加成功", "成功", JOptionPane.INFORMATION_MESSAGE);
|
|
|
|
|
|
|
|
|
|
// 清空表单并刷新表格
|
|
|
|
|
addBookTitleField.setText("");
|
|
|
|
|
addBookAuthorField.setText("");
|
|
|
|
|
addBookPublisherField.setText("");
|
|
|
|
|
addBookYearField.setText("");
|
|
|
|
|
addBookCategoryField.setText("");
|
|
|
|
|
refreshAdminPanelData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//刷新用户面板数据
|
|
|
|
|
private void refreshUserPanelData() {
|
|
|
|
|
refreshBooksTable();
|
|
|
|
|
updateBorrowedBooksTable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//刷新管理员面板数据
|
|
|
|
|
private void refreshAdminPanelData() {
|
|
|
|
|
// 更新书籍表格
|
|
|
|
|
allBooksTableModel.setRowCount(0);
|
|
|
|
|
List<Book> allBooks = library.getAllBooks();
|
|
|
|
|
for (Book book : allBooks) {
|
|
|
|
|
Object[] row = {
|
|
|
|
|
book.getId(),
|
|
|
|
|
book.getTitle(),
|
|
|
|
|
book.getAuthor(),
|
|
|
|
|
book.getPublisher(),
|
|
|
|
|
book.getPublicationYear(),
|
|
|
|
|
book.getCategory(),
|
|
|
|
|
book.isAvailable() ? "可借阅" : "已借出"
|
|
|
|
|
};
|
|
|
|
|
allBooksTableModel.addRow(row);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新用户表格
|
|
|
|
|
usersTableModel.setRowCount(0);
|
|
|
|
|
List<User> allUsers = library.getAllUsers();
|
|
|
|
|
for (User user : allUsers) {
|
|
|
|
|
Object[] row = {
|
|
|
|
|
user.getId(),
|
|
|
|
|
user.getUsername(),
|
|
|
|
|
user.getEmail(),
|
|
|
|
|
user.getPhone(),
|
|
|
|
|
user.isAdmin() ? "管理员" : "普通用户"
|
|
|
|
|
};
|
|
|
|
|
usersTableModel.addRow(row);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//退出登录
|
|
|
|
|
private void logout() {
|
|
|
|
|
currentUser = null;
|
|
|
|
|
// 清空登录表单
|
|
|
|
|
usernameField.setText("");
|
|
|
|
|
passwordField.setText("");
|
|
|
|
|
showLoginPanel();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//面板切换方法
|
|
|
|
|
private void showLoginPanel() {
|
|
|
|
|
CardLayout cl = (CardLayout) mainPanel.getLayout();
|
|
|
|
|
cl.show(mainPanel, "login");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showRegisterPanel() {
|
|
|
|
|
CardLayout cl = (CardLayout) mainPanel.getLayout();
|
|
|
|
|
cl.show(mainPanel, "register");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showUserPanel() {
|
|
|
|
|
CardLayout cl = (CardLayout) mainPanel.getLayout();
|
|
|
|
|
cl.show(mainPanel, "user");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showAdminPanel() {
|
|
|
|
|
CardLayout cl = (CardLayout) mainPanel.getLayout();
|
|
|
|
|
cl.show(mainPanel, "admin");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//主方法
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
// 在事件调度线程中启动GUI,确保线程安全
|
|
|
|
|
SwingUtilities.invokeLater(() -> {
|
|
|
|
|
new LibrarySystemGUI().setVisible(true);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|