我为你设计了一个Java课程设计案例,这是一个综合运用了面向对象、GUI、集合、异常处理和文件IO的学生成绩管理系统,这个案例结构完整,适合作为期末课程设计或课程大作业。

学生成绩管理系统(Java Swing + 文件存储)
本系统是一个基于 Java Swing 的桌面应用程序,用于管理学生的基本信息及其课程成绩,系统实现了学生信息的增删改查、成绩录入与统计、数据持久化存储等功能。
技术栈:
- 语言:Java(JDK 8+)
- GUI:Swing
- 存储:本地文件(TXT/CSV格式)
- 设计模式:MVC(Model-View-Controller)分层架构
系统功能结构
学生成绩管理系统
├── 登录模块(管理员身份验证)
├── 学生信息管理
│ ├── 添加学生
│ ├── 删除学生
│ ├── 修改学生信息
│ └── 查询学生(按姓名/学号)
├── 成绩管理
│ ├── 录入成绩(语文/数学/英语)
│ ├── 修改成绩
│ └── 删除成绩
├── 统计报表
│ ├── 按总分排名
│ ├── 班级平均分
│ └── 各科最高/最低分
└── 数据持久化(保存至文件)
核心代码实现
学生实体类 Student.java
import java.io.Serializable;
/**
* 学生实体类
*/
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private String id; // 学号
private String name; // 姓名
private String gender; // 性别
private int age; // 年龄
private String className; // 班级
// 三门课程成绩
private double chinese;
private double math;
private double english;
public Student() {}
public Student(String id, String name, String gender, int age, String className) {
this.id = id;
this.name = name;
this.gender = gender;
this.age = age;
this.className = className;
this.chinese = 0;
this.math = 0;
this.english = 0;
}
// 计算总分
public double getTotalScore() {
return chinese + math + english;
}
// 计算平均分
public double getAverageScore() {
return getTotalScore() / 3;
}
// 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 getClassName() { return className; }
public void setClassName(String className) { this.className = className; }
public double getChinese() { return chinese; }
public void setChinese(double chinese) { this.chinese = chinese; }
public double getMath() { return math; }
public void setMath(double math) { this.math = math; }
public double getEnglish() { return english; }
public void setEnglish(double english) { this.english = english; }
@Override
public String toString() {
return String.format("学号: %s, 姓名: %s, 性别: %s, 年龄: %d, 班级: %s, " +
"语文: %.1f, 数学: %.1f, 英语: %.1f, 总分: %.1f",
id, name, gender, age, className, chinese, math, english, getTotalScore());
}
}
数据访问层 StudentDao.java
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* 数据访问层 - 负责学生数据的增删改查和文件存储
*/
public class StudentDao {
private static final String FILE_PATH = "students.dat";
private List<Student> students;
public StudentDao() {
students = new ArrayList<>();
loadData();
}
/**
* 添加学生
*/
public boolean addStudent(Student student) {
// 检查学号是否已存在
for (Student s : students) {
if (s.getId().equals(student.getId())) {
return false;
}
}
students.add(student);
saveData();
return true;
}
/**
* 删除学生
*/
public boolean deleteStudent(String id) {
for (int i = 0; i < students.size(); i++) {
if (students.get(i).getId().equals(id)) {
students.remove(i);
saveData();
return true;
}
}
return false;
}
/**
* 更新学生信息
*/
public boolean updateStudent(Student student) {
for (int i = 0; i < students.size(); i++) {
if (students.get(i).getId().equals(student.getId())) {
students.set(i, student);
saveData();
return true;
}
}
return false;
}
/**
* 根据学号查找学生
*/
public Student findById(String id) {
for (Student s : students) {
if (s.getId().equals(id)) {
return s;
}
}
return null;
}
/**
* 根据姓名模糊查找
*/
public List<Student> findByName(String name) {
List<Student> result = new ArrayList<>();
for (Student s : students) {
if (s.getName().contains(name)) {
result.add(s);
}
}
return result;
}
/**
* 获取所有学生
*/
public List<Student> getAllStudents() {
return new ArrayList<>(students);
}
/**
* 按总分排序(从高到低)
*/
public List<Student> sortByTotalScore() {
List<Student> sorted = new ArrayList<>(students);
sorted.sort((s1, s2) -> Double.compare(s2.getTotalScore(), s1.getTotalScore()));
return sorted;
}
/**
* 保存数据到文件
*/
private void saveData() {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_PATH))) {
oos.writeObject(students);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 从文件加载数据
*/
@SuppressWarnings("unchecked")
private void loadData() {
File file = new File(FILE_PATH);
if (!file.exists()) {
return;
}
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
students = (List<Student>) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取班级平均分
*/
public double getClassAverage(String className) {
List<Student> classStudents = new ArrayList<>();
for (Student s : students) {
if (s.getClassName().equals(className)) {
classStudents.add(s);
}
}
if (classStudents.isEmpty()) {
return 0;
}
double sum = 0;
for (Student s : classStudents) {
sum += s.getTotalScore();
}
return sum / classStudents.size();
}
/**
* 统计各科成绩统计(最高/最低/平均)
*/
public double[] getSubjectStatistics(String subject) {
if (students.isEmpty()) {
return new double[]{0, 0, 0};
}
double max = Double.MIN_VALUE;
double min = Double.MAX_VALUE;
double sum = 0;
for (Student s : students) {
double score;
switch (subject) {
case "语文": score = s.getChinese(); break;
case "数学": score = s.getMath(); break;
case "英语": score = s.getEnglish(); break;
default: score = 0;
}
if (score > max) max = score;
if (score < min) min = score;
sum += score;
}
double average = sum / students.size();
return new double[]{max, min, average};
}
}
主界面 MainFrame.java
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.util.List;
/**
* 主窗口 - 系统核心界面
*/
public class MainFrame extends JFrame {
private StudentDao studentDao;
private JTable studentTable;
private DefaultTableModel tableModel;
private JTextField idField, nameField, ageField, classNameField;
private JComboBox<String> genderBox;
private JTextField chineseField, mathField, englishField;
private JTextField searchField;
public MainFrame() {
studentDao = new StudentDao();
initUI();
refreshTable();
}
/**
* 初始化界面
*/
private void initUI() {
setTitle("学生成绩管理系统");
setSize(1000, 650);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
// 主面板 - 使用BorderLayout
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// 顶部功能按钮面板
mainPanel.add(createToolBar(), BorderLayout.NORTH);
// 中央表格面板
mainPanel.add(createTablePanel(), BorderLayout.CENTER);
// 右侧编辑面板
mainPanel.add(createEditPanel(), BorderLayout.EAST);
add(mainPanel);
}
/**
* 创建顶部工具栏
*/
private JPanel createToolBar() {
JPanel toolBar = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
JButton addBtn = new JButton("添加学生");
JButton deleteBtn = new JButton("删除学生");
JButton updateBtn = new JButton("更新信息");
JButton clearBtn = new JButton("清空表单");
JButton sortBtn = new JButton("按总分排名");
JButton statsBtn = new JButton("成绩统计");
addBtn.addActionListener(e -> addStudent());
deleteBtn.addActionListener(e -> deleteStudent());
updateBtn.addActionListener(e -> updateStudent());
clearBtn.addActionListener(e -> clearForm());
sortBtn.addActionListener(e -> showRanking());
statsBtn.addActionListener(e -> showStatistics());
toolBar.add(addBtn);
toolBar.add(deleteBtn);
toolBar.add(updateBtn);
toolBar.add(clearBtn);
toolBar.add(sortBtn);
toolBar.add(statsBtn);
return toolBar;
}
/**
* 创建表格面板
*/
private JPanel createTablePanel() {
JPanel panel = new JPanel(new BorderLayout());
// 表格模型
String[] columns = {"学号", "姓名", "性别", "年龄", "班级", "语文", "数学", "英语", "总分", "平均分"};
tableModel = new DefaultTableModel(columns, 0) {
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
studentTable = new JTable(tableModel);
studentTable.setRowHeight(25);
studentTable.getTableHeader().setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
// 点击表格行时加载学生信息
studentTable.getSelectionModel().addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
loadSelectedStudent();
}
});
JScrollPane scrollPane = new JScrollPane(studentTable);
panel.add(scrollPane, BorderLayout.CENTER);
// 搜索面板
JPanel searchPanel = new JPanel(new FlowLayout());
searchPanel.add(new JLabel("搜索:"));
searchField = new JTextField(15);
JButton searchBtn = new JButton("搜索");
JButton searchResetBtn = new JButton("重置");
searchBtn.addActionListener(e -> searchStudents());
searchResetBtn.addActionListener(e -> {
searchField.setText("");
refreshTable();
});
searchPanel.add(searchField);
searchPanel.add(searchBtn);
searchPanel.add(searchResetBtn);
panel.add(searchPanel, BorderLayout.SOUTH);
return panel;
}
/**
* 创建右侧编辑面板
*/
private JPanel createEditPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createTitledBorder("学生信息编辑"));
panel.setPreferredSize(new Dimension(300, 0));
// 表单面板
JPanel formPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
// 学号
gbc.gridx = 0; gbc.gridy = 0;
formPanel.add(new JLabel("学号:"), gbc);
gbc.gridx = 1; gbc.gridy = 0;
idField = new JTextField(15);
formPanel.add(idField, gbc);
// 姓名
gbc.gridx = 0; gbc.gridy = 1;
formPanel.add(new JLabel("姓名:"), gbc);
gbc.gridx = 1; gbc.gridy = 1;
nameField = new JTextField(15);
formPanel.add(nameField, gbc);
// 性别
gbc.gridx = 0; gbc.gridy = 2;
formPanel.add(new JLabel("性别:"), gbc);
gbc.gridx = 1; gbc.gridy = 2;
genderBox = new JComboBox<>(new String[]{"男", "女"});
formPanel.add(genderBox, gbc);
// 年龄
gbc.gridx = 0; gbc.gridy = 3;
formPanel.add(new JLabel("年龄:"), gbc);
gbc.gridx = 1; gbc.gridy = 3;
ageField = new JTextField(15);
formPanel.add(ageField, gbc);
// 班级
gbc.gridx = 0; gbc.gridy = 4;
formPanel.add(new JLabel("班级:"), gbc);
gbc.gridx = 1; gbc.gridy = 4;
classNameField = new JTextField(15);
formPanel.add(classNameField, gbc);
// 成绩输入分隔线
gbc.gridx = 0; gbc.gridy = 5;
gbc.gridwidth = 2;
formPanel.add(new JSeparator(), gbc);
gbc.gridwidth = 1;
// 语文成绩
gbc.gridx = 0; gbc.gridy = 6;
formPanel.add(new JLabel("语文:"), gbc);
gbc.gridx = 1; gbc.gridy = 6;
chineseField = new JTextField(15);
formPanel.add(chineseField, gbc);
// 数学成绩
gbc.gridx = 0; gbc.gridy = 7;
formPanel.add(new JLabel("数学:"), gbc);
gbc.gridx = 1; gbc.gridy = 7;
mathField = new JTextField(15);
formPanel.add(mathField, gbc);
// 英语成绩
gbc.gridx = 0; gbc.gridy = 8;
formPanel.add(new JLabel("英语:"), gbc);
gbc.gridx = 1; gbc.gridy = 8;
englishField = new JTextField(15);
formPanel.add(englishField, gbc);
panel.add(formPanel, BorderLayout.CENTER);
// 底部提示
JLabel tip = new JLabel("提示: 点击表格行可加载信息");
tip.setForeground(Color.GRAY);
panel.add(tip, BorderLayout.SOUTH);
return panel;
}
/**
* 添加学生
*/
private void addStudent() {
try {
String id = idField.getText().trim();
String name = nameField.getText().trim();
String gender = (String) genderBox.getSelectedItem();
int age = Integer.parseInt(ageField.getText().trim());
String className = classNameField.getText().trim();
if (id.isEmpty() || name.isEmpty() || className.isEmpty()) {
JOptionPane.showMessageDialog(this, "学号、姓名、班级不能为空!", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
Student student = new Student(id, name, gender, age, className);
// 设置成绩
if (!chineseField.getText().trim().isEmpty()) {
student.setChinese(Double.parseDouble(chineseField.getText().trim()));
}
if (!mathField.getText().trim().isEmpty()) {
student.setMath(Double.parseDouble(mathField.getText().trim()));
}
if (!englishField.getText().trim().isEmpty()) {
student.setEnglish(Double.parseDouble(englishField.getText().trim()));
}
if (studentDao.addStudent(student)) {
JOptionPane.showMessageDialog(this, "学生添加成功!");
refreshTable();
clearForm();
} else {
JOptionPane.showMessageDialog(this, "学号已存在!", "错误", JOptionPane.ERROR_MESSAGE);
}
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(this, "请正确填写数字字段!", "错误", JOptionPane.ERROR_MESSAGE);
}
}
/**
* 删除学生
*/
private void deleteStudent() {
int selectedRow = studentTable.getSelectedRow();
if (selectedRow == -1) {
JOptionPane.showMessageDialog(this, "请先选择一个学生!", "提示", JOptionPane.WARNING_MESSAGE);
return;
}
String id = (String) tableModel.getValueAt(selectedRow, 0);
String name = (String) tableModel.getValueAt(selectedRow, 1);
int confirm = JOptionPane.showConfirmDialog(this,
"确认删除学生 " + name + " (学号: " + id + ") ?",
"确认删除", JOptionPane.YES_NO_OPTION);
if (confirm == JOptionPane.YES_OPTION) {
if (studentDao.deleteStudent(id)) {
JOptionPane.showMessageDialog(this, "删除成功!");
refreshTable();
clearForm();
}
}
}
/**
* 更新学生信息
*/
private void updateStudent() {
int selectedRow = studentTable.getSelectedRow();
if (selectedRow == -1) {
JOptionPane.showMessageDialog(this, "请先选择一个学生!", "提示", JOptionPane.WARNING_MESSAGE);
return;
}
String id = idField.getText().trim();
if (id.isEmpty()) {
JOptionPane.showMessageDialog(this, "学号不能为空!", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
Student student = studentDao.findById(id);
if (student == null) {
JOptionPane.showMessageDialog(this, "学生不存在!", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
try {
student.setName(nameField.getText().trim());
student.setGender((String) genderBox.getSelectedItem());
student.setAge(Integer.parseInt(ageField.getText().trim()));
student.setClassName(classNameField.getText().trim());
if (!chineseField.getText().trim().isEmpty()) {
student.setChinese(Double.parseDouble(chineseField.getText().trim()));
}
if (!mathField.getText().trim().isEmpty()) {
student.setMath(Double.parseDouble(mathField.getText().trim()));
}
if (!englishField.getText().trim().isEmpty()) {
student.setEnglish(Double.parseDouble(englishField.getText().trim()));
}
if (studentDao.updateStudent(student)) {
JOptionPane.showMessageDialog(this, "学生信息更新成功!");
refreshTable();
}
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(this, "请正确填写数字字段!", "错误", JOptionPane.ERROR_MESSAGE);
}
}
/**
* 加载选中的学生信息到表单
*/
private void loadSelectedStudent() {
int selectedRow = studentTable.getSelectedRow();
if (selectedRow == -1) {
return;
}
idField.setText((String) tableModel.getValueAt(selectedRow, 0));
nameField.setText((String) tableModel.getValueAt(selectedRow, 1));
genderBox.setSelectedItem(tableModel.getValueAt(selectedRow, 2));
ageField.setText(String.valueOf(tableModel.getValueAt(selectedRow, 3)));
classNameField.setText((String) tableModel.getValueAt(selectedRow, 4));
chineseField.setText(String.valueOf(tableModel.getValueAt(selectedRow, 5)));
mathField.setText(String.valueOf(tableModel.getValueAt(selectedRow, 6)));
englishField.setText(String.valueOf(tableModel.getValueAt(selectedRow, 7)));
}
/**
* 清空表单
*/
private void clearForm() {
idField.setText("");
nameField.setText("");
genderBox.setSelectedIndex(0);
ageField.setText("");
classNameField.setText("");
chineseField.setText("");
mathField.setText("");
englishField.setText("");
}
/**
* 刷新表格
*/
private void refreshTable() {
tableModel.setRowCount(0);
List<Student> students = studentDao.getAllStudents();
for (Student s : students) {
tableModel.addRow(new Object[]{
s.getId(), s.getName(), s.getGender(), s.getAge(), s.getClassName(),
s.getChinese(), s.getMath(), s.getEnglish(), s.getTotalScore(),
String.format("%.1f", s.getAverageScore())
});
}
}
/**
* 搜索学生
*/
private void searchStudents() {
String keyword = searchField.getText().trim();
if (keyword.isEmpty()) {
refreshTable();
return;
}
tableModel.setRowCount(0);
List<Student> students;
// 先尝试按学号精确查询
Student byId = studentDao.findById(keyword);
if (byId != null) {
students = List.of(byId);
} else {
// 再按姓名模糊查询
students = studentDao.findByName(keyword);
}
for (Student s : students) {
tableModel.addRow(new Object[]{
s.getId(), s.getName(), s.getGender(), s.getAge(), s.getClassName(),
s.getChinese(), s.getMath(), s.getEnglish(), s.getTotalScore(),
String.format("%.1f", s.getAverageScore())
});
}
}
/**
* 显示排名
*/
private void showRanking() {
List<Student> sorted = studentDao.sortByTotalScore();
StringBuilder sb = new StringBuilder("=== 学生总分排名 ===\n");
sb.append("排名\t学号\t姓名\t总分\n");
int rank = 1;
for (Student s : sorted) {
sb.append(rank).append("\t")
.append(s.getId()).append("\t")
.append(s.getName()).append("\t")
.append(s.getTotalScore()).append("\n");
rank++;
}
JTextArea textArea = new JTextArea(sb.toString(), 15, 30);
textArea.setEditable(false);
JOptionPane.showMessageDialog(this, new JScrollPane(textArea), "成绩排名",
JOptionPane.INFORMATION_MESSAGE);
}
/**
* 显示成绩统计
*/
private void showStatistics() {
StringBuilder sb = new StringBuilder("=== 成绩统计 ===\n\n");
String[] subjects = {"语文", "数学", "英语"};
for (String subject : subjects) {
double[] stats = studentDao.getSubjectStatistics(subject);
sb.append(subject).append(":\n")
.append(" 最高分: ").append(stats[0]).append("\n")
.append(" 最低分: ").append(stats[1]).append("\n")
.append(" 平均分: ").append(String.format("%.1f", stats[2])).append("\n\n");
}
// 获取所有班级的平均分
java.util.Set<String> classes = new java.util.HashSet<>();
for (Student s : studentDao.getAllStudents()) {
classes.add(s.getClassName());
}
sb.append("=== 各班平均分 ===\n");
for (String className : classes) {
double avg = studentDao.getClassAverage(className);
sb.append(className).append(": ").append(String.format("%.1f", avg)).append("\n");
}
JTextArea textArea = new JTextArea(sb.toString(), 20, 25);
textArea.setEditable(false);
JOptionPane.showMessageDialog(this, new JScrollPane(textArea), "成绩统计",
JOptionPane.INFORMATION_MESSAGE);
}
}
登录界面 LoginFrame.java
import javax.swing.*;
import java.awt.*;
/**
* 登录界面
*/
public class LoginFrame extends JFrame {
private final String ADMIN_USERNAME = "admin";
private final String ADMIN_PASSWORD = "123456";
private JTextField usernameField;
private JPasswordField passwordField;
public LoginFrame() {
initUI();
}
private void initUI() {
setTitle("登录 - 学生成绩管理系统");
setSize(400, 250);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setResizable(false);
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 30, 20, 30));
// 标题
JLabel title = new JLabel("学生成绩管理系统", SwingConstants.CENTER);
title.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
mainPanel.add(title, BorderLayout.NORTH);
// 表单
JPanel formPanel = new JPanel(new GridLayout(2, 2, 10, 10));
formPanel.add(new JLabel("用户名:"));
usernameField = new JTextField();
formPanel.add(usernameField);
formPanel.add(new JLabel("密码:"));
passwordField = new JPasswordField();
formPanel.add(passwordField);
mainPanel.add(formPanel, BorderLayout.CENTER);
// 按钮
JPanel btnPanel = new JPanel(new FlowLayout());
JButton loginBtn = new JButton("登录");
JButton resetBtn = new JButton("重置");
loginBtn.addActionListener(e -> login());
resetBtn.addActionListener(e -> {
usernameField.setText("");
passwordField.setText("");
});
btnPanel.add(loginBtn);
btnPanel.add(resetBtn);
mainPanel.add(btnPanel, BorderLayout.SOUTH);
add(mainPanel);
}
private void login() {
String username = usernameField.getText().trim();
String password = new String(passwordField.getPassword());
if (username.equals(ADMIN_USERNAME) && password.equals(ADMIN_PASSWORD)) {
JOptionPane.showMessageDialog(this, "登录成功!", "欢迎", JOptionPane.INFORMATION_MESSAGE);
// 打开主界面
new MainFrame().setVisible(true);
dispose();
} else {
JOptionPane.showMessageDialog(this, "用户名或密码错误!", "登录失败", JOptionPane.ERROR_MESSAGE);
}
}
}
程序入口 Main.java
import javax.swing.*;
/**
* 程序入口
*/
public class Main {
public static void main(String[] args) {
// 设置系统UI风格
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
// 启动登录界面
SwingUtilities.invokeLater(() -> {
new LoginFrame().setVisible(true);
});
}
}
系统亮点与设计说明
设计特点:
- 分层架构 - 清晰的MVC设计,实体类、数据访问层、视图层分离
- 数据持久化 - 使用对象序列化保存到本地文件
- 异常处理 - 对输入进行合法性校验
- 用户体验 - 表格点击联动加载、搜索功能、排序功能
扩展方向:
- 增加数据库支持(MySQL替换文件存储)
- 增加图表统计(JFreeChart)
- 增加多用户权限管理
- 增加成绩导入导出(Excel)
使用方法
-
编译运行:
javac Main.java java Main -
登录账号:
- 用户名:
admin - 密码:
123456
- 用户名:
-
测试数据:
添加几个学生,录入成绩,测试排序和统计功能
这个课程设计涵盖了Java面向对象程序设计的核心知识点,代码结构清晰,功能完整,非常适合作为课程设计作业提交,你可以根据课程要求修改包名、类名,或者加入自己的创新功能。