【Java基础开发】 基于Swing GUI 组件实现图书管理系统

博主介绍:✌全网粉丝阅读量30W+,CSDN特邀作者、博客专家、CSDN新星计划导师,博客之星、平台优质作者、专注于Java技术领域和项目实战✌

🍅文末获取源码联系🍅

一、前言介绍

1.1 选题背景与意义

在信息化时代,传统的图书管理方式已难以满足高效、精准的管理需求。手工记录图书信息不仅效率低下,而且容易出现数据丢失、检索困难等问题。随着计算机技术的普及,开发一套功能完善、操作简便的图书管理系统,对于提升图书管理效率、降低人工出错率具有重要的现实意义。

本系统以 Java 语言为开发基础,采用 Swing 图形用户界面框架,设计并实现了一款面向单机环境的桌面图书管理系统。系统涵盖图书的添加、查询、删除及列表展示等核心功能,界面友好、交互直观,适用于小型图书馆、班级图书角或个人藏书管理等场景。

1.2 系统简介

本系统是一款基于 Java Swing 的桌面应用程序,采用 MVC(Model-View-Controller) 设计思想进行架构组织。系统以内存中的动态列表作为数据载体,实现了图书信息的增删查改功能。用户通过图形化界面即可完成全部操作,无需掌握任何数据库或命令行知识。

系统主要特点包括:

  • 操作简便:所有功能通过按钮和输入框即可完成,零学习成本;
  • 即时反馈:每次操作均通过弹窗给予明确的成功或失败提示;
  • 数据校验:对输入内容进行非空检查和重复性校验,保证数据质量;
  • 跨平台运行:基于 Java 开发,可在 Windows、macOS、Linux 等操作系统上运行。

1.3 开发目的

通过本项目的开发,旨在达到以下目标:

  1. 掌握 Java 面向对象编程思想及 Swing GUI 组件的使用方法;
  2. 理解桌面应用的事件驱动模型和界面布局管理;
  3. 培养软件工程思维,体验从需求分析、系统设计到编码实现的完整开发流程;
  4. 为后续学习数据库编程、网络编程及企业级开发奠定实践基础。

二、主要技术

2.1 Java 编程语言

Java 是一种面向对象、跨平台的编程语言,具有"一次编写,到处运行"(Write Once, Run Anywhere)的特性。本系统采用 Java SE 8 及以上版本进行开发,充分利用其以下核心特性:

特性 在本系统中的应用
面向对象 封装 Book 实体类,将书名、作者、ISBN 封装为对象属性
集合框架 使用 ArrayList<Book> 存储图书数据,支持动态增删
异常处理 通过 try-catch 捕获界面外观设置等潜在异常
Lambda 表达式 简化事件监听器代码(如 e -> addBook()

2.2 Swing 图形用户界面框架

Swing 是 Java 提供的轻量级 GUI 工具包,用于构建跨平台的桌面应用程序。本系统主要使用了以下 Swing 组件:

组件类别 具体组件 功能说明
顶层容器 JFrame 系统主窗口,承载所有界面元素
面板容器 JPanel 组织功能区域(输入区、搜索区)
表格组件 JTable 展示图书列表,支持行选择和滚动浏览
表格模型 DefaultTableModel 管理表格数据,控制单元格是否可编辑
输入组件 JTextField 接收用户输入的书名、作者、ISBN 及搜索关键字
按钮组件 JButton 触发添加、删除、查询、刷新等业务操作
对话框 JOptionPane 弹出信息提示、警告提示及确认对话框
滚动面板 JScrollPane 包裹表格,实现大数据量下的滚动查看

2.3 布局管理器

为实现界面的合理排布,本系统综合运用了多种 AWT/Swing 布局管理器:

布局管理器 应用区域 特点
BorderLayout 主窗口整体布局 将界面划分为东、西、南、北、中五个区域
GridLayout 左侧输入面板 网格状排列标签和输入框,整齐对齐
FlowLayout 底部搜索面板 组件从左到右流式排列,自动换行

2.4 开发工具与环境

项目 版本/工具 说明
JDK JDK 8 及以上 Java 开发工具包,提供编译和运行环境
IDE IntelliJ IDEA / Eclipse 集成开发环境,提供代码编辑、调试和构建功能
构建工具 手动编译 / Maven(可选) 管理项目依赖和构建流程
版本控制 Git(推荐) 代码版本管理和团队协作

2.5 系统架构设计

本系统采用简化的 MVC 分层架构,各层职责如下:

复制代码
┌─────────────────────────────────────────┐
│              View(视图层)              │
│    ├─ LibraryGUI(主界面窗口)           │
│    ├─ JTable(数据展示表格)             │
│    └─ 各类输入框、按钮组件               │
├─────────────────────────────────────────┤
│           Controller(控制层)           │
│    ├─ addBook()      ──→ 添加图书逻辑   │
│    ├─ deleteSelectedBook() ──→ 删除逻辑 │
│    ├─ searchBook()   ──→ 查询逻辑       │
│    └─ refreshTable() ──→ 刷新逻辑       │
├─────────────────────────────────────────┤
│             Model(模型层)              │
│    ├─ Book(图书实体类)                 │
│    └─ List<Book>(数据集合)             │
└─────────────────────────────────────────┘
  • Model(模型层):Book 类封装图书属性,List 负责数据存储;
  • View(视图层):Swing 组件构成用户界面,负责数据展示和用户交互;
  • Controller(控制层):界面类中的业务方法,负责接收用户输入、调用模型、更新视图。

2.6 关键技术点

  • 事件驱动编程:通过 ActionListener 监听按钮点击事件,实现用户操作响应;
  • 表格模型定制:重写 DefaultTableModel.isCellEditable() 方法,实现表格只读;
  • 数据绑定机制:业务数据变更后调用 refreshTable() 同步更新界面显示;
  • Look and Feel 设置:调用 UIManager.setLookAndFeel() 使界面风格与操作系统保持一致,提升用户体验。

三、 图书管理系统需求分析

3.1 项目概述

项目 内容
系统名称 图书管理系统 (Library Management System)
开发语言 Java (Swing GUI)
运行环境 JRE 8+
目标用户 图书馆管理员、图书室工作人员
系统定位 单机版桌面应用,管理图书的增删查

3.2 功能模块图

复制代码
┌─────────────────────────────────────────┐
│           图书管理系统                    │
├─────────────┬─────────────┬─────────────┤
│   图书管理   │   查询统计   │   系统维护   │
├─────────────┼─────────────┼─────────────┤
│ • 添加图书   │ • 书名查询   │ • 数据刷新   │
│ • 删除图书   │ • 模糊搜索   │ • 界面重置   │
│ • 查看列表   │ • 结果展示   │ • 异常处理   │
└─────────────┴─────────────┴─────────────┘

3.3 详细功能需求

功能编号 功能名称 优先级 详细描述
FR-001 添加图书 输入书名、作者、ISBN,系统自动校验非空和重复书名,成功后添加到列表并刷新表格
FR-002 删除图书 选中表格中的图书,弹出确认对话框,确认后从列表移除并刷新显示
FR-003 查询图书 输入书名关键字,支持模糊匹配(忽略大小写),只显示匹配结果
FR-004 刷新列表 清空搜索条件,重新加载并显示所有图书
FR-005 输入验证 书名、作者、ISBN 均不能为空;书名不能重复(忽略大小写)
FR-006 数据展示 以表格形式展示,列包括:书名、作者、ISBN;表格只读不可编辑
FR-007 用户反馈 所有操作(成功/失败)均通过对话框给出明确提示

3.4 数据需求

3.41 实体定义
复制代码
┌────────────────────────────────────┐
│             Book (图书)            │
├────────────────────────────────────┤
│ PK │ title   │ String │ 书名      │
│    │ author  │ String │ 作者      │
│    │ isbn    │ String │ ISBN编号  │
└────────────────────────────────────┘
3.42 数据存储
存储方式 说明 当前状态
内存存储 (ArrayList) 程序运行时保存在内存,关闭后数据丢失 ✅ 已实现
文件存储 (TXT/JSON) 保存到本地文件,下次启动可读取 ⏳ 待扩展
数据库存储 (SQLite/MySQL) 持久化存储,支持大数据量 ⏳ 待扩展

四、系统原型设计

4.1 界面布局原型

复制代码
┌──────────────────────────────────────────────────────────────────┐
│  📚 图书管理系统                                    [---] [□] [×]   │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌──────────────┐  ┌──────────────────────────────────────────┐  │
│  │  添加新书     │  │  书名          │ 作者        │ ISBN     │  │
│  │              │  ├───────────────┼─────────────┼──────────┤  │
│  │  书名: [    ] │  │  西游记          │ 吴承恩       │ 978-7-02-018.. │  │
│  │  作者: [    ] │  │  红楼梦          │ 曹雪芹      │ 978-7-02-000.. │  │
│  │  ISBN: [    ] │  │  三国演义      │ 罗贯中    │ 978-7-02-017.. │  │
│  │              │  │  ...           │ ...         │ ...      │  │
│  │  [添加图书]   │  │              │             │          │  │
│  └──────────────┘  └──────────────────────────────────────────┘  │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────────┐ │
│  │  书名查询: [                    ] [🔍 查询] [🗑️ 删除选中] [🔄 刷新] │
│  └─────────────────────────────────────────────────────────────┘ │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘

4.2 界面组件详细设计

区域 组件 类型 说明
左侧输入区 书名输入框 JTextField 必填,接受任意文本
作者输入框 JTextField 必填,接受任意文本
ISBN输入框 JTextField 必填,接受任意文本
添加按钮 JButton 点击触发添加图书逻辑
面板标题 TitledBorder "添加新书"
中央表格区 图书表格 JTable 3列(书名/作者/ISBN),单选模式,只读
滚动面板 JScrollPane 包裹表格,支持滚动
底部操作区 搜索框 JTextField 输入查询关键字,宽度20字符
查询按钮 JButton 模糊搜索书名
删除按钮 JButton 删除当前选中行对应的图书
刷新按钮 JButton 重置搜索,显示全部图书

4.3 对话框设计

场景 对话框类型 标题 消息内容
添加成功 INFORMATION_MESSAGE 成功 ✅ 图书添加成功!
添加失败-空值 WARNING_MESSAGE 输入错误 ❌ 所有字段不能为空!
添加失败-重复 WARNING_MESSAGE 重复图书 ⚠️ 书名 "xxx" 已存在!
删除确认 YES_NO_OPTION 确认删除 确定要删除《xxx》吗?
删除成功 INFORMATION_MESSAGE 删除成功 ✅ 图书已删除!
未选择删除 WARNING_MESSAGE 未选择 ❌ 请先选择要删除的图书!
查询无结果 INFORMATION_MESSAGE 查询结果 ❌ 未找到包含 "xxx" 的图书。

五、 核心代码

5.1 添加详细注释后的完整代码

java 复制代码
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 图书管理系统主窗口类
 * 继承自 JFrame,提供图形化界面进行图书的增删查操作
 */
public class LibraryGUI extends JFrame {
    
    // ==================== 数据层 ====================
    /** 内存中的图书列表,作为数据存储(程序关闭后数据丢失) */
    private List<Book> books;
    
    // ==================== 表格相关组件 ====================
    /** 表格数据模型,负责管理表格的行数据和列结构 */
    private DefaultTableModel tableModel;
    /** 图书展示表格,用于显示所有图书信息 */
    private JTable bookTable;
    
    // ==================== 输入相关组件 ====================
    /** 书名输入框 - 用于添加新书时输入书名 */
    private JTextField titleField;
    /** 作者输入框 - 用于添加新书时输入作者名 */
    private JTextField authorField;
    /** ISBN输入框 - 用于添加新书时输入国际标准书号 */
    private JTextField isbnField;
    /** 搜索输入框 - 用于按书名关键字查询图书 */
    private JTextField searchField;

    /**
     * 构造方法:初始化图书列表并构建图形界面
     */
    public LibraryGUI() {
        books = new ArrayList<>();  // 初始化空的图书列表
        initializeGUI();            // 调用界面初始化方法
    }

    /**
     * 初始化图形用户界面(GUI)
     * 设置窗口属性、创建各功能面板、绑定事件监听器
     */
    private void initializeGUI() {
        // ---------- 窗口基础设置 ----------
        setTitle("📚 图书管理系统");                    // 设置窗口标题
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 点击关闭按钮时退出程序
        setSize(800, 600);                              // 设置窗口大小
        setLocationRelativeTo(null);                    // 窗口在屏幕居中显示

        // ---------- 表格模型配置 ----------
        // 定义表格列名:书名、作者、ISBN
        String[] columns = {"书名", "作者", "ISBN"};
        
        // 创建自定义表格模型,重写 isCellEditable 禁止直接编辑单元格
        tableModel = new DefaultTableModel(columns, 0) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return false; // 返回 false 表示所有单元格不可编辑(只读表格)
            }
        };
        
        // 使用自定义模型创建表格
        bookTable = new JTable(tableModel);
        // 设置选择模式为单选(每次只能选中一行)
        bookTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        
        // ---------- 左侧:添加新书面板 ----------
        // 使用 4行2列 的网格布局,水平/垂直间距均为5像素
        JPanel inputPanel = new JPanel(new GridLayout(4, 2, 5, 5));
        // 设置带标题的边框,标题为"添加新书"
        inputPanel.setBorder(BorderFactory.createTitledBorder("添加新书"));

        // 初始化三个输入框
        titleField = new JTextField();
        authorField = new JTextField();
        isbnField = new JTextField();

        // 向面板添加标签和输入框(按网格布局顺序填充)
        inputPanel.add(new JLabel("书名:"));
        inputPanel.add(titleField);
        inputPanel.add(new JLabel("作者:"));
        inputPanel.add(authorField);
        inputPanel.add(new JLabel("ISBN:"));
        inputPanel.add(isbnField);

        // 创建"添加图书"按钮,并绑定点击事件
        JButton addButton = new JButton("添加图书");
        // 使用 Lambda 表达式简化事件监听:点击时调用 addBook() 方法
        addButton.addActionListener(e -> addBook());
        
        inputPanel.add(new JLabel()); // 空标签占位,保持网格对齐
        inputPanel.add(addButton);

        // ---------- 底部:搜索与操作面板 ----------
        // 使用流式布局(FlowLayout),组件从左到右排列
        JPanel searchPanel = new JPanel(new FlowLayout());
        searchField = new JTextField(20); // 搜索框宽度为20个字符
        
        // 创建功能按钮
        JButton searchButton = new JButton("🔍 查询");      // 搜索按钮
        JButton deleteButton = new JButton("🗑️ 删除选中");  // 删除按钮
        JButton refreshButton = new JButton("🔄 刷新");      // 刷新按钮

        // 为各按钮绑定对应的事件处理方法
        searchButton.addActionListener(e -> searchBook());      // 查询
        deleteButton.addActionListener(e -> deleteSelectedBook()); // 删除
        refreshButton.addActionListener(e -> refreshTable());   // 刷新

        // 将组件添加到搜索面板
        searchPanel.add(new JLabel("书名查询:"));
        searchPanel.add(searchField);
        searchPanel.add(searchButton);
        searchPanel.add(deleteButton);
        searchPanel.add(refreshButton);

        // ---------- 整体布局 ----------
        // 使用边界布局(BorderLayout)
        setLayout(new BorderLayout());
        add(new JScrollPane(bookTable), BorderLayout.CENTER); // 表格居中(带滚动条)
        add(inputPanel, BorderLayout.WEST);                   // 输入面板在左侧
        add(searchPanel, BorderLayout.SOUTH);                 // 搜索面板在底部

        // 初始化时刷新表格(显示空列表或预加载数据)
        refreshTable();
    }

    /**
     * 添加图书方法
     * 从输入框读取数据,验证后添加到图书列表
     */
    private void addBook() {
        // 获取输入框内容并去除首尾空格
        String title = titleField.getText().trim();
        String author = authorField.getText().trim();
        String isbn = isbnField.getText().trim();

        // ---------- 输入验证 ----------
        // 检查是否有空字段
        if (title.isEmpty() || author.isEmpty() || isbn.isEmpty()) {
            // 显示警告对话框:父组件、消息内容、标题、消息类型
            JOptionPane.showMessageDialog(this, 
                "❌ 所有字段不能为空!", 
                "输入错误", 
                JOptionPane.WARNING_MESSAGE);
            return; // 终止方法执行
        }

        // ---------- 重复性检查 ----------
        // 遍历现有图书列表,检查是否已存在同名图书(忽略大小写)
        for (Book b : books) {
            if (b.getTitle().equalsIgnoreCase(title)) {
                JOptionPane.showMessageDialog(this,
                    "⚠️ 书名 \"" + title + "\" 已存在!",
                    "重复图书",
                    JOptionPane.WARNING_MESSAGE);
                return; // 发现重复,终止添加
            }
        }

        // ---------- 添加图书 ----------
        // 创建新的 Book 对象并添加到列表
        books.add(new Book(title, author, isbn));
        refreshTable();      // 刷新表格显示
        clearInputFields();  // 清空输入框
        
        // 显示成功提示
        JOptionPane.showMessageDialog(this,
            "✅ 图书添加成功!",
            "成功",
            JOptionPane.INFORMATION_MESSAGE);
    }

    /**
     * 删除选中的图书
     * 获取表格选中行,确认后从列表中移除对应图书
     */
    private void deleteSelectedBook() {
        // 获取用户选中的行索引(未选中时返回 -1)
        int selectedRow = bookTable.getSelectedRow();
        
        // 检查是否已选中行
        if (selectedRow == -1) {
            JOptionPane.showMessageDialog(this,
                "❌ 请先选择要删除的图书!",
                "未选择",
                JOptionPane.WARNING_MESSAGE);
            return;
        }

        // 从表格模型中获取选中行的书名(第0列)
        String title = (String) tableModel.getValueAt(selectedRow, 0);

        // 显示确认对话框,询问是否确定删除
        int confirm = JOptionPane.showConfirmDialog(this,
                "确定要删除《" + title + "》吗?",  // 提示消息
                "确认删除",                           // 对话框标题
                JOptionPane.YES_NO_OPTION);           // 显示"是/否"按钮
        
        // 如果用户点击"否",直接返回不执行删除
        if (confirm != JOptionPane.YES_OPTION) return;

        // 使用 Lambda 表达式移除列表中书名匹配的图书(忽略大小写)
        books.removeIf(book -> book.getTitle().equalsIgnoreCase(title));
        
        refreshTable(); // 刷新表格显示最新数据
        
        JOptionPane.showMessageDialog(this,
            "✅ 图书已删除!",
            "删除成功",
            JOptionPane.INFORMATION_MESSAGE);
    }

    /**
     * 搜索图书方法
     * 按书名关键字进行模糊匹配,只显示匹配结果
     */
    private void searchBook() {
        // 获取搜索关键字并去除首尾空格
        String keyword = searchField.getText().trim();
        
        // 如果搜索框为空,显示所有图书(等同于刷新)
        if (keyword.isEmpty()) {
            refreshTable();
            return;
        }

        // ---------- 执行搜索 ----------
        tableModel.setRowCount(0); // 清空表格现有数据
        boolean found = false;     // 标记是否找到匹配项
        
        // 遍历所有图书,进行模糊匹配(忽略大小写)
        for (Book book : books) {
            // 将书名和关键字都转为小写后进行包含判断
            if (book.getTitle().toLowerCase().contains(keyword.toLowerCase())) {
                // 匹配成功,添加到表格显示
                tableModel.addRow(new Object[]{
                    book.getTitle(), 
                    book.getAuthor(), 
                    book.getIsbn()
                });
                found = true;
            }
        }

        // 如果没有找到任何匹配图书,显示提示信息
        if (!found) {
            JOptionPane.showMessageDialog(this,
                "❌ 未找到包含 \"" + keyword + "\" 的图书。",
                "查询结果",
                JOptionPane.INFORMATION_MESSAGE);
        }
    }

    /**
     * 刷新表格方法
     * 清空表格并重新加载所有图书数据
     */
    private void refreshTable() {
        tableModel.setRowCount(0); // 将表格行数设为0,清空所有数据
        
        // 遍历图书列表,将每本图书添加到表格中
        for (Book book : books) {
            tableModel.addRow(new Object[]{
                book.getTitle(),   // 第0列:书名
                book.getAuthor(),  // 第1列:作者
                book.getIsbn()     // 第2列:ISBN
            });
        }
        
        clearInputFields(); // 清空输入框并将焦点重置到书名框
    }

    /**
     * 清空所有输入框并将焦点设置到书名输入框
     * 提升用户体验,方便连续添加多本图书
     */
    private void clearInputFields() {
        titleField.setText("");   // 清空书名
        authorField.setText("");  // 清空作者
        isbnField.setText("");    // 清空ISBN
        titleField.requestFocus(); // 将输入焦点设置到书名框
    }

    /**
     * 程序入口方法(主方法)
     * 使用 SwingUtilities.invokeLater 确保GUI在事件调度线程中创建
     * 
     * @param args 命令行参数(未使用)
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                // 设置系统原生外观(Look and Feel),使界面风格与操作系统一致
                // 例如 Windows 显示 Windows 风格,macOS 显示 macOS 风格
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e) {
                // 如果设置外观失败,打印异常但继续运行(使用默认Java外观)
                e.printStackTrace();
            }
            // 创建主窗口实例并显示
            new LibraryGUI().setVisible(true);
        });
    }
}

5.2 关键设计要点总结

设计点 说明
线程安全 使用 SwingUtilities.invokeLater() 确保GUI在事件调度线程(EDT)中创建
数据验证 添加图书时进行空值检查和重复书名检查
用户体验 操作后自动清空输入框、设置焦点、显示反馈对话框
防御性编程 删除前要求确认,搜索为空时显示全部数据
外观一致性 使用系统原生 Look and Feel 提升界面亲和力

六、系统运行截图

6.1 初始化运行GUI界面

6.2 添加图书功能

6.3 查询图书功能

点击查询按钮

七、 源码获取

【Java开发学习/项目实战/源代码】👇点击下方获取👇

相关推荐
陌殇殇2 小时前
004 Spring AI Alibaba框架整合百炼大模型平台 — MCP服务
java·spring·ai
014-code2 小时前
JUC 常用工具类:CountDownLatch、CyclicBarrier、Semaphore
java
William Dawson2 小时前
【一文吃透 Spring Boot 面向切面编程(AOP):实例\+实现\+注意事项】
java·spring boot
xyq20242 小时前
Font Awesome 加载中图标
开发语言
fengxin_rou2 小时前
JVM 核心笔记:对象创建、生命周期与类加载器详解
java·jvm·笔记
one_love_zfl2 小时前
java面试-JVM篇
java·jvm·面试
skiy2 小时前
Spring之DataSource配置
java·后端·spring
石榴树下的七彩鱼2 小时前
医疗票据OCR识别API实战:从医保结算单到结构化数据提取(附Python/Java示例)
java·人工智能·python·ocr·api·ocr识别·医疗票据识别
Cat_Rocky2 小时前
k8s-单Master集群部署(简练理解)
java·容器·kubernetes