杰瑞科技汇

基于java的学生信息管理系统

项目概述

本项目是一个使用 Java Swing 作为图形用户界面库开发的桌面应用程序,它实现了对学生基本信息(如学号、姓名、性别、年龄、专业)的增、删、改、查功能,并将数据持久化存储在本地文件中。

主要技术栈:

  • 编程语言: Java
  • GUI库: Java Swing
  • 数据存储: 本地文本文件 (CSV格式)
  • 开发工具: IntelliJ IDEA / Eclipse / VS Code

项目结构

一个良好的项目结构是可维护和可扩展的基础。

StudentManagementSystem/
├── src/
│   ├── main/
│   │   └── java/
│   │       ├── Main.java              # 程序入口
│   │       ├── model/
│   │       │   └── Student.java       # 学生实体类 (Model)
│   │       ├── view/
│   │       │   ├── MainFrame.java     # 主窗口
│   │       │   ├── AddStudentPanel.java # 添加学生面板
│   │       │   └── StudentTablePanel.java # 学生列表表格面板
│   │       └── controller/
│   │           └── StudentController.java # 业务逻辑控制器
│   └── resources/
│       └── students.csv               # 数据存储文件
└── README.md                          # 项目说明文档

核心代码实现

我们将按照MVC(Model-View-Controller)设计模式来组织代码,使结构更清晰。

1. Model (模型层) - Student.java

这个类是数据模型,定义了学生的属性。

// src/main/java/model/Student.java
package model;
public class Student {
    private String id;
    private String name;
    private String gender;
    private int age;
    private String major;
    // 构造方法
    public Student(String id, String name, String gender, int age, String major) {
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.major = major;
    }
    // Getter 和 Setter 方法
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getGender() { return gender; }
    public void setGender(String gender) { this.gender = gender; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    public String getMajor() { return major; }
    public void setMajor(String major) { this.major = major; }
    @Override
    public String toString() {
        // 用于CSV文件格式化输出
        return id + "," + name + "," + gender + "," + age + "," + major;
    }
    // 从CSV行字符串创建Student对象
    public static Student fromString(String line) {
        String[] parts = line.split(",");
        if (parts.length == 5) {
            return new Student(parts[0], parts[1], parts[2], Integer.parseInt(parts[3]), parts[4]);
        }
        return null;
    }
}

2. Controller (控制器层) - StudentController.java

这是业务逻辑的核心,负责处理数据(读取、保存、增删改查)。

// src/main/java/controller/StudentController.java
package controller;
import model.Student;
import view.StudentTablePanel;
import javax.swing.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class StudentController {
    private List<Student> students;
    private static final String FILE_PATH = "resources/students.csv";
    public StudentController() {
        students = new ArrayList<>();
        loadStudents();
    }
    // 从文件加载学生数据
    private void loadStudents() {
        File file = new File(FILE_PATH);
        if (!file.exists()) {
            try {
                file.getParentFile().mkdirs(); // 创建resources目录
                file.createNewFile(); // 创建空文件
            } catch (IOException e) {
                JOptionPane.showMessageDialog(null, "无法创建数据文件!", "错误", JOptionPane.ERROR_MESSAGE);
            }
            return;
        }
        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = reader.readLine()) != null) {
                Student student = Student.fromString(line);
                if (student != null) {
                    students.add(student);
                }
            }
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "读取数据文件失败!", "错误", JOptionPane.ERROR_MESSAGE);
        }
    }
    // 保存学生数据到文件
    public void saveStudents() {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH))) {
            for (Student student : students) {
                writer.write(student.toString());
                writer.newLine();
            }
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "保存数据文件失败!", "错误", JOptionPane.ERROR_MESSAGE);
        }
    }
    // 添加学生
    public void addStudent(Student student) {
        if (findStudentById(student.getId()) != null) {
            JOptionPane.showMessageDialog(null, "学号已存在!", "警告", JOptionPane.WARNING_MESSAGE);
            return;
        }
        students.add(student);
        saveStudents();
    }
    // 删除学生
    public void deleteStudent(String id) {
        Student student = findStudentById(id);
        if (student != null) {
            students.remove(student);
            saveStudents();
        }
    }
    // 更新学生信息
    public void updateStudent(Student updatedStudent) {
        Student student = findStudentById(updatedStudent.getId());
        if (student != null) {
            // 更新信息
            student.setName(updatedStudent.getName());
            student.setGender(updatedStudent.getGender());
            student.setAge(updatedStudent.getAge());
            student.setMajor(updatedStudent.getMajor());
            saveStudents();
        }
    }
    // 根据ID查找学生
    public Student findStudentById(String id) {
        for (Student student : students) {
            if (student.getId().equals(id)) {
                return student;
            }
        }
        return null;
    }
    // 获取所有学生列表
    public List<Student> getAllStudents() {
        return students;
    }
}

3. View (视图层)

视图层负责显示用户界面。

StudentTablePanel.java - 显示学生列表的表格

// src/main/java/view/StudentTablePanel.java
package view;
import controller.StudentController;
import model.Student;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.util.List;
public class StudentTablePanel extends JPanel {
    private JTable studentTable;
    private DefaultTableModel tableModel;
    private StudentController controller;
    public StudentTablePanel(StudentController controller) {
        this.controller = controller;
        setLayout(new BorderLayout());
        initUI();
        refreshTable();
    }
    private void initUI() {
        // 表格模型
        String[] columnNames = {"学号", "姓名", "性别", "年龄", "专业"};
        tableModel = new DefaultTableModel(columnNames, 0) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return false; // 所有单元格不可编辑
            }
        };
        studentTable = new JTable(tableModel);
        JScrollPane scrollPane = new JScrollPane(studentTable);
        add(scrollPane, BorderLayout.CENTER);
    }
    public void refreshTable() {
        tableModel.setRowCount(0); // 清空现有数据
        List<Student> students = controller.getAllStudents();
        for (Student student : students) {
            Object[] row = {
                student.getId(),
                student.getName(),
                student.getGender(),
                student.getAge(),
                student.getMajor()
            };
            tableModel.addRow(row);
        }
    }
    // 获取当前选中的学生
    public Student getSelectedStudent() {
        int selectedRow = studentTable.getSelectedRow();
        if (selectedRow != -1) {
            String id = (String) tableModel.getValueAt(selectedRow, 0);
            return controller.findStudentById(id);
        }
        return null;
    }
}

AddStudentPanel.java - 添加/编辑学生的表单

// src/main/java/view/AddStudentPanel.java
package view;
import controller.StudentController;
import model.Student;
import javax.swing.*;
import java.awt.*;
public class AddStudentPanel extends JPanel {
    private JTextField idField, nameField, ageField, majorField;
    private JComboBox<String> genderComboBox;
    private StudentController controller;
    private boolean isEditMode = false;
    private String editingId = null;
    public AddStudentPanel(StudentController controller) {
        this.controller = controller;
        setLayout(new GridBagLayout());
        initUI();
    }
    private void initUI() {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.anchor = GridBagConstraints.WEST;
        // 学号
        gbc.gridx = 0;
        gbc.gridy = 0;
        add(new JLabel("学号:"), gbc);
        gbc.gridx = 1;
        idField = new JTextField(15);
        add(idField, gbc);
        // 姓名
        gbc.gridx = 0;
        gbc.gridy = 1;
        add(new JLabel("姓名:"), gbc);
        gbc.gridx = 1;
        nameField = new JTextField(15);
        add(nameField, gbc);
        // 性别
        gbc.gridx = 0;
        gbc.gridy = 2;
        add(new JLabel("性别:"), gbc);
        gbc.gridx = 1;
        genderComboBox = new JComboBox<>(new String[]{"男", "女"});
        add(genderComboBox, gbc);
        // 年龄
        gbc.gridx = 0;
        gbc.gridy = 3;
        add(new JLabel("年龄:"), gbc);
        gbc.gridx = 1;
        ageField = new JTextField(15);
        add(ageField, gbc);
        // 专业
        gbc.gridx = 0;
        gbc.gridy = 4;
        add(new JLabel("专业:"), gbc);
        gbc.gridx = 1;
        majorField = new JTextField(15);
        add(majorField, gbc);
    }
    public void clearForm() {
        idField.setText("");
        nameField.setText("");
        genderComboBox.setSelectedIndex(0);
        ageField.setText("");
        majorField.setText("");
        isEditMode = false;
        editingId = null;
    }
    public void fillForm(Student student) {
        idField.setText(student.getId());
        nameField.setText(student.getName());
        genderComboBox.setSelectedItem(student.getGender());
        ageField.setText(String.valueOf(student.getAge()));
        majorField.setText(student.getMajor());
        isEditMode = true;
        editingId = student.getId();
    }
    public Student getStudentFromForm() {
        try {
            String id = idField.getText().trim();
            String name = nameField.getText().trim();
            String gender = (String) genderComboBox.getSelectedItem();
            int age = Integer.parseInt(ageField.getText().trim());
            String major = majorField.getText().trim();
            if (id.isEmpty() || name.isEmpty() || major.isEmpty()) {
                throw new IllegalArgumentException("学号、姓名和专业不能为空!");
            }
            return new Student(id, name, gender, age, major);
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(this, "年龄必须为数字!", "输入错误", JOptionPane.ERROR_MESSAGE);
            return null;
        } catch (IllegalArgumentException e) {
            JOptionPane.showMessageDialog(this, e.getMessage(), "输入错误", JOptionPane.ERROR_MESSAGE);
            return null;
        }
    }
    public boolean isEditMode() {
        return isEditMode;
    }
    public String getEditingId() {
        return editingId;
    }
}

MainFrame.java - 主窗口

// src/main/java/view/MainFrame.java
package view;
import controller.StudentController;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MainFrame extends JFrame {
    private StudentController controller;
    private StudentTablePanel tablePanel;
    private AddStudentPanel addPanel;
    public MainFrame() {
        controller = new StudentController();
        setTitle("学生信息管理系统");
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        initUI();
    }
    private void initUI() {
        // 使用JSplitPane分割面板
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        splitPane.setDividerLocation(500);
        splitPane.setResizeWeight(0.7);
        // 左侧:表格
        tablePanel = new StudentTablePanel(controller);
        splitPane.setLeftComponent(new JScrollPane(tablePanel));
        // 右侧:添加/编辑表单
        addPanel = new AddStudentPanel(controller);
        splitPane.setRightComponent(addPanel);
        add(splitPane, BorderLayout.CENTER);
        // 底部:按钮
        JPanel buttonPanel = new JPanel();
        JButton addButton = new JButton("添加");
        JButton updateButton = new JButton("修改");
        JButton deleteButton = new JButton("删除");
        JButton clearButton = new JButton("清空");
        buttonPanel.add(addButton);
        buttonPanel.add(updateButton);
        buttonPanel.add(deleteButton);
        buttonPanel.add(clearButton);
        add(buttonPanel, BorderLayout.SOUTH);
        // 添加事件监听器
        addButton.addActionListener(new AddButtonListener());
        updateButton.addActionListener(new UpdateButtonListener());
        deleteButton.addActionListener(new DeleteButtonListener());
        clearButton.addActionListener(e -> addPanel.clearForm());
    }
    private class AddButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            Student student = addPanel.getStudentFromForm();
            if (student != null) {
                controller.addStudent(student);
                tablePanel.refreshTable();
                addPanel.clearForm();
                JOptionPane.showMessageDialog(MainFrame.this, "添加成功!", "成功", JOptionPane.INFORMATION_MESSAGE);
            }
        }
    }
    private class UpdateButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (!addPanel.isEditMode()) {
                Student selected = tablePanel.getSelectedStudent();
                if (selected == null) {
                    JOptionPane.showMessageDialog(MainFrame.this, "请先选择要修改的学生!", "提示", JOptionPane.WARNING_MESSAGE);
                    return;
                }
                addPanel.fillForm(selected);
            } else {
                Student student = addPanel.getStudentFromForm();
                if (student != null) {
                    controller.updateStudent(student);
                    tablePanel.refreshTable();
                    addPanel.clearForm();
                    JOptionPane.showMessageDialog(MainFrame.this, "修改成功!", "成功", JOptionPane.INFORMATION_MESSAGE);
                }
            }
        }
    }
    private class DeleteButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            Student selected = tablePanel.getSelectedStudent();
            if (selected == null) {
                JOptionPane.showMessageDialog(MainFrame.this, "请先选择要删除的学生!", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }
            int confirm = JOptionPane.showConfirmDialog(MainFrame.this,
                    "确定要删除学号为 " + selected.getId() + " 的学生吗?",
                    "确认删除", JOptionPane.YES_NO_OPTION);
            if (confirm == JOptionPane.YES_OPTION) {
                controller.deleteStudent(selected.getId());
                tablePanel.refreshTable();
                addPanel.clearForm();
                JOptionPane.showMessageDialog(MainFrame.this, "删除成功!", "成功", JOptionPane.INFORMATION_MESSAGE);
            }
        }
    }
}

4. 程序入口 - Main.java

// src/main/java/Main.java
package main;
import view.MainFrame;
public class Main {
    public static void main(String[] args) {
        // 设置界面风格 (可选)
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 在事件分发线程中创建和显示GUI
        SwingUtilities.invokeLater(() -> {
            MainFrame mainFrame = new MainFrame();
            mainFrame.setVisible(true);
        });
    }
}

功能演示

  1. 运行程序:编译并运行 Main.java
  2. 主界面:会弹出一个窗口,左侧是学生列表表格,右侧是添加/编辑表单。
  3. 添加学生:在右侧表单中填写信息,点击“添加”按钮,成功后,左侧表格会刷新显示新学生。
  4. 修改学生:在左侧表格中点击选中一行,然后点击“修改”按钮,右侧表单会自动填充该学生的信息,修改后再次点击“修改”按钮保存更改。
  5. 删除学生:在左侧表格中选中一行,点击“删除”按钮,确认后即可删除。
  6. 数据持久化:关闭程序后,重新打开,之前添加的学生信息依然存在,因为数据保存在 students.csv 文件中。

可能的扩展方向

这个基础版本已经实现了核心功能,但还有很多可以优化的地方:

  1. 数据库集成

    • StudentController 中的文件操作替换为数据库操作(如 MySQL, PostgreSQL)。
    • 使用 JDBC 或 JPA (如 Hibernate) 来管理数据,这样数据管理更安全、更高效,也更适合大规模数据。
  2. 增强查询功能

    在主界面添加一个搜索框,支持按学号、姓名等关键字进行模糊查询。

  3. 界面美化

    • 使用 FlatLaf 等第三方皮肤库来美化界面。
    • 添加图标、使用更现代的布局管理器(如 MigLayoutGridBagLayout 的高级用法)。
  4. 功能扩展

    • 成绩管理:增加对课程和成绩的管理,一个学生可以有多门课程的成绩。
    • 统计与报表:添加统计功能,如按专业统计人数、计算平均年龄等,并以图表形式展示(可以使用 JFreeChart 库)。
    • 用户登录:增加一个简单的登录系统,区分管理员和普通用户角色,实现权限控制。
  5. 代码优化

    • 异常处理:更细致地处理各种异常情况。
    • 日志记录:使用 java.util.loggingLog4j 等框架记录程序运行日志,方便排查问题。
    • 单元测试:为 StudentController 等核心类编写 JUnit 测试用例,确保代码质量。

这个项目非常适合作为Java课程设计或个人练习,它涵盖了Java基础、Swing GUI、文件I/O和简单的MVC设计模式,是学习Java桌面应用开发的绝佳起点。

分享:
扫描分享到社交APP
上一篇
下一篇