目录
一、选题与前期调查
1.选题
学生基本信息管理系统(2人)等级:C-
功能要求:
1、添加学生功能:学号、姓名、性别、出生日期、政治面貌、家庭住址、电话、宿舍号。
2、根据学号查找学生信息:输入学号,根据学号查找学生的信息,查找不到则返回查找失败。
3、删除学生信息:根据输入的学号查找到该学生相应信息并且删除。
4、修改学生信息:根据输入的学号找到该学生相应信息,并且自主选择要修改的信息条目。
5、读取文件并存入文件:初始信息会从文件中读取,修改的信息也会写入文件。
6、GUI:使用GUI界面进行操作。
2.前期调查
使用gpt完成选题的研究。
二、人员分工
分工 | 姓名 | 任务 |
组长 | 林礼豪 | AddStudentDialog类、CustomCellRenderer类、FindStudentDialog类、MainWindow类、StudentTableModel类、UpdateStudentDialog类、代码规范设计 |
组员 | 洪希炀 | StudentController类、Student类、StudentDataStorage类、DeleteStudentDialog类、博客编写、前期调查 |
三、项目描述
1.项目简介
该项目是一款学生信息管理系统,用于学生基本信息的增删查改功能
2.项目技术
1.GUI界面
2.文件存储
3.git代码管理
3.功能需求分析
1.展示已有学生信息
2.修改和删除学生信息
3.查找和添加学生信息
4.系统细节
系统目录:
系统包含以下对象:
1.StudentController类:
操控学生信息的增删查改
2.AddStudentDialog类:
通过GUI界面实现添加学生信息功能
3.CustomCellRenderer类:
自定义表格
4.FindStudentDialog类:
通过GUI界面实现用学号查找学生信息功能
5.DeleteStudentDialog类:
通过GUI界面实现用学号删除相应学生信息功能
6.MainWindow类:
进入系统所展示的GUI功能界面
7.StudentTableModel类:
表格模型,定义如何在JTable中显示学生数据
8.UpdateStudentDialog类:
通过GUI界面实现修改学生信息功能
9.Student类:
定义一个学生类:包括姓名、性别、学号等等信息。
10.StudentDataStorage类:
用于导入文件和读取存储文件。
5.代码规范
使用阿里巴巴代码规范扫描插件对项目代码进行扫描,并解决项目中的所有警告
修改后:
四、系统功能架构图
五、系统功能运行结果截图展示
1.进入界面,显示文件中已有学生信息。
2.添加学生信息
3.修改学生信息
4.查找学生
5.删除学生
六、关键代码
1.查找信息
package gui;
import javax.swing.*;
import java.awt.*;
import controller.StudentController;
import model.Student;
public class FindStudentDialog extends JDialog {
private JTextField studentIdField;
private JTextArea studentInfoArea;
private JButton findButton;
private StudentController controller;
public FindStudentDialog(Frame parent, StudentController controller) {
super(parent, "查找学生", true);
this.controller = controller;
setLayout(new BorderLayout());
JPanel inputPanel = new JPanel(new GridLayout(1, 2));
inputPanel.add(new JLabel("学号:"));
studentIdField = new JTextField(20);
inputPanel.add(studentIdField);
add(inputPanel, BorderLayout.NORTH);
studentInfoArea = new JTextArea(15, 30);
studentInfoArea.setEditable(false);
add(new JScrollPane(studentInfoArea), BorderLayout.CENTER);
findButton = new JButton("查找");
findButton.addActionListener(e -> findStudent());
add(findButton, BorderLayout.SOUTH);
pack();
setLocationRelativeTo(parent);
}
private void findStudent() {
String studentId = studentIdField.getText();
Student student = controller.getStudentById(studentId);
if (student != null) {
// 显示学生信息
studentInfoArea.setFont(new Font("宋体", Font.PLAIN, 16)); // 设置字体大小为16
studentInfoArea.setText(" 学号: " + student.getStudentId() + "\n" +
" 姓名: " + student.getName() + "\n" +
" 性别: " + student.getGender() + "\n" +
"出生日期: " + student.getBirthDate() + "\n" +
"政治面貌: " + student.getPoliticalStatus() + "\n" +
"家庭住址: " + student.getAddress() + "\n" +
" 电话: " + student.getPhone() + "\n" +
" 宿舍号: " + student.getDormitoryNumber() + "\n");
} else {
studentInfoArea.setText("未找到学号为 " + studentId + " 的学生。");
}
}
}
2.增加学生信息
package gui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import controller.StudentController;
import model.Student;
public class AddStudentDialog extends JDialog {
private JTextField studentIdField, nameField, genderField, birthDateField, politicalStatusField, addressField, phoneField, dormitoryNumberField;
private JButton submitButton;
private StudentController controller;
// 对话框的构造函数
public AddStudentDialog(Frame parent, StudentController controller,StudentTableModel studentTableModel) {
super(parent, "添加学生", true);
this.controller = controller;
// 设置布局并添加标签和文本字段
setLayout(new GridLayout(9, 2));
add(new JLabel("学号:"));
studentIdField = new JTextField(20);
add(studentIdField);
add(new JLabel("姓名:"));
nameField = new JTextField(20);
add(nameField);
add(new JLabel("性别:"));
genderField = new JTextField(20);
add(genderField);
add(new JLabel("出生日期(xxxx-xx-xx):"));
birthDateField = new JTextField(20);
add(birthDateField);
add(new JLabel("政治面貌:"));
politicalStatusField = new JTextField(20);
add(politicalStatusField);
add(new JLabel("家庭住址:"));
addressField = new JTextField(20);
add(addressField);
add(new JLabel("电话:"));
phoneField = new JTextField(20);
add(phoneField);
add(new JLabel("宿舍号:"));
dormitoryNumberField = new JTextField(20);
add(dormitoryNumberField);
// 提交按钮
submitButton = new JButton("添加");
submitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
submitStudent(studentTableModel);// 提交学生信息
}
});
add(submitButton);
// 设置对话框的大小和位置
setSize(400, 500);
setLocationRelativeTo(parent);
}
// 提交学生信息的方法
private void submitStudent(StudentTableModel studentTableModel) {
// 从文本字段中获取数据
// 数据验证和学生对象的创建逻辑
String studentId = studentIdField.getText();
if (controller.getStudentById(studentId) != null) {
JOptionPane.showMessageDialog(this, "学号 " + studentId + " 已存在,请使用其他学号。");
return; // 中断提交流程
}
String name = nameField.getText();
String gender = genderField.getText();
if (!gender.equals("男") && !gender.equals("女")) {
JOptionPane.showMessageDialog(this, "性别必须为‘男’或‘女’。");
return;
}
String birthDate = birthDateField.getText();
if (!isValidDate(birthDate)) {
JOptionPane.showMessageDialog(this, "生日必须为 'xxxx-xx-xx' 格式。");
return;
}
String politicalStatus = politicalStatusField.getText();
if (!politicalStatus.equals("群众") && !politicalStatus.equals("共青团员")&&!politicalStatus.equals("共产党员")&&!politicalStatus.equals("入党积极分子")&&!politicalStatus.equals("少先队员")&&!politicalStatus.equals("党员")&&!politicalStatus.equals("中共党员")&& !politicalStatus.equals("团员")) {
JOptionPane.showMessageDialog(this, "请输入正确的政治面貌。");
return;
}
String address = addressField.getText();
String phone = phoneField.getText();
if (!phone.matches("\\d{11}")) {
JOptionPane.showMessageDialog(this, "电话号码必须为11位数字。");
return;
}
String dormitoryNumber = dormitoryNumberField.getText();
// 创建 Student 对象并添加到系统中
Student student = new Student(studentId, name,gender,birthDate,politicalStatus,address,phone,dormitoryNumber);
controller.addStudent(student);
// 关闭对话框
setVisible(false);
dispose();
List<Student> updatedStudents = controller.getAllStudents();
studentTableModel.setStudents(updatedStudents);
}
// 验证日期格式是否有效的方法
private boolean isValidDate(String dateString) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
try {
dateFormat.parse(dateString);
return true;
} catch (ParseException e) {
return false;
}
}
}
3.删除学生信息
package gui;
import controller.StudentController;
import model.Student;
import javax.swing.*;
import java.awt.*;
import java.util.List;
// 用于删除学生信息的对话框类
public class DeleteStudentDialog extends JDialog {
private JTextField studentIdField;
private JButton deleteButton, findButton;
private JTextArea studentInfoArea;
private StudentController controller;
public DeleteStudentDialog(Frame parent, StudentController controller,StudentTableModel studentTableModel) {
super(parent, "删除学生", true);
this.controller = controller;
// 设置布局管理器为边界布局
setLayout(new BorderLayout());
// 创建顶部面板,包括学号输入和查找按钮
JPanel inputPanel = new JPanel();
studentIdField = new JTextField(20);
findButton = new JButton("查找");
inputPanel.add(new JLabel("学号:"));
inputPanel.add(studentIdField);
inputPanel.add(findButton);
// 将面板添加到对话框的上方
add(inputPanel, BorderLayout.NORTH);
// 学生信息显示区域
studentInfoArea = new JTextArea(20, 50);
studentInfoArea.setEditable(false);// 设置为不可编辑
studentInfoArea.setFont(new Font("宋体", Font.PLAIN, 16));
// 添加滚动面板到对话框的中心区域
add(new JScrollPane(studentInfoArea), BorderLayout.CENTER);
// 删除按钮
deleteButton = new JButton("删除");
add(deleteButton, BorderLayout.SOUTH);
// 查找按钮事件处理
findButton.addActionListener(e -> findStudent());
// 删除按钮事件处理
deleteButton.addActionListener(e -> deleteStudent(studentTableModel));
pack();
setLocationRelativeTo(parent);
}
private void findStudent() {
String studentId = studentIdField.getText();
Student student = controller.getStudentById(studentId);
if (student != null) {
// 显示学生信息
studentInfoArea.setText("学号: " + student.getStudentId() + "\n" +
"姓名: " + student.getName() + "\n" +
"性别: " + student.getGender() + "\n" +
"出生日期: " + student.getBirthDate() + "\n" +
"政治面貌: " + student.getPoliticalStatus() + "\n" +
"家庭住址: " + student.getAddress() + "\n" +
"电话: " + student.getPhone() + "\n" +
"宿舍号: " + student.getDormitoryNumber() + "\n");
} else {
studentInfoArea.setText("未找到学号为 " + studentId + " 的学生。");
}
}
private void deleteStudent(StudentTableModel studentTableModel) {
String studentId = studentIdField.getText();
if (studentId.isEmpty() || controller.getStudentById(studentId) == null) {
JOptionPane.showMessageDialog(this, "请先查找有效的学生信息。");
return;
}
// 再次确认删除
int confirm = JOptionPane.showConfirmDialog(this,
"确定要删除学号为 " + studentId + " 的学生吗?", "确认删除",
JOptionPane.YES_NO_OPTION);
if (confirm == JOptionPane.YES_OPTION) {
controller.deleteStudent(studentId);
studentInfoArea.setText("");
JOptionPane.showMessageDialog(this, "学生已被删除。");
List<Student> updatedStudents = controller.getAllStudents();
studentTableModel.setStudents(updatedStudents);
}
}
}
4.修改学生信息
package gui;
import javax.swing.*;
import java.awt.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import controller.StudentController;
import model.Student;
public class UpdateStudentDialog extends JDialog {
private JTextField studentIdField, nameField, genderField, birthDateField, politicalStatusField, addressField, phoneField, dormitoryNumberField;
private JButton findButton, updateButton;
private StudentController controller;
private Student currentStudent;
public UpdateStudentDialog(Frame parent, StudentController controller,StudentTableModel studentTableModel) {
super(parent, "修改学生信息", true);
this.controller = controller;
setLayout(new BorderLayout());
setPreferredSize(new Dimension(600, 400));
// 输入学号和查找按钮
JPanel findPanel = new JPanel();
studentIdField = new JTextField(20);
findButton = new JButton("查找");
findPanel.add(new JLabel("学号:"));
findPanel.add(studentIdField);
findPanel.add(findButton);
add(findPanel, BorderLayout.NORTH);
// 学生信息编辑区域
JPanel infoPanel = new JPanel(new GridLayout(9, 2));
// 添加姓名、性别、出生日期等其他字段
nameField = new JTextField(20);
genderField = new JTextField(20);
birthDateField = new JTextField(20);
politicalStatusField = new JTextField(20);
addressField = new JTextField(20);
phoneField = new JTextField(20);
dormitoryNumberField = new JTextField(20);
infoPanel.add(new JLabel("姓名:"));
infoPanel.add(nameField);
infoPanel.add(new JLabel("性别:"));
infoPanel.add(genderField);
infoPanel.add(new JLabel("出生日期:"));
infoPanel.add(birthDateField);
infoPanel.add(new JLabel("政治面貌:"));
infoPanel.add(politicalStatusField);
infoPanel.add(new JLabel("家庭住址:"));
infoPanel.add(addressField);
infoPanel.add(new JLabel("电话号码:"));
infoPanel.add(phoneField);
infoPanel.add(new JLabel("宿舍号:"));
infoPanel.add(dormitoryNumberField);
add(infoPanel, BorderLayout.CENTER);
// 更新按钮
updateButton = new JButton("更新");
add(updateButton, BorderLayout.SOUTH);
// 查找按钮事件处理
findButton.addActionListener(e -> {
String studentId = studentIdField.getText();
currentStudent = controller.getStudentById(studentId);
if (currentStudent != null) {
// 显示学生信息以供编辑
nameField.setText(currentStudent.getName());
genderField.setText(currentStudent.getGender());
birthDateField.setText(currentStudent.getBirthDate());
politicalStatusField.setText(currentStudent.getPoliticalStatus());
addressField.setText(currentStudent.getAddress());
phoneField.setText(currentStudent.getPhone());
dormitoryNumberField.setText(currentStudent.getDormitoryNumber());
} else {
JOptionPane.showMessageDialog(this, "未找到学号为 " + studentId + " 的学生");
}
});
// 更新按钮事件处理
updateButton.addActionListener(e -> {
if (currentStudent != null) {
// 更新学生信息
String name = nameField.getText();
String gender = genderField.getText();
if (!gender.equals("男") && !gender.equals("女")) {
JOptionPane.showMessageDialog(this, "性别必须为‘男’或‘女’。");
return; // 中断提交流程
}
String birthDate = birthDateField.getText();
if (!isValidDate(birthDate)) {
JOptionPane.showMessageDialog(this, "生日必须为 'xxxx-xx-xx' 格式。");
return; // 中断提交流程
}
String politicalStatus = politicalStatusField.getText();
if (!politicalStatus.equals("群众") && !politicalStatus.equals("共青团员")&&!politicalStatus.equals("共产党员")&&!politicalStatus.equals("入党积极分子")&&!politicalStatus.equals("少先队员")&&!politicalStatus.equals("党员")&&!politicalStatus.equals("中共党员")&& !politicalStatus.equals("团员")) {
JOptionPane.showMessageDialog(this, "请输入正确的政治面貌。");
return; // 中断提交流程
}
String address = addressField.getText();
String phone = phoneField.getText();
if (!phone.matches("\\d{11}")) {
JOptionPane.showMessageDialog(this, "电话号码必须为11位数字。");
return; // 中断提交流程
}
String dormitoryNumber = dormitoryNumberField.getText();
currentStudent.setName(name);
currentStudent.setGender(gender);
currentStudent.setBirthDate(birthDate);
currentStudent.setPoliticalStatus(politicalStatus);
currentStudent.setAddress(address);
currentStudent.setPhone(phone);
currentStudent.setDormitoryNumber(dormitoryNumber);
controller.updateStudent(currentStudent);
JOptionPane.showMessageDialog(this, "学生信息已更新");
List<Student> updatedStudents = controller.getAllStudents();
studentTableModel.setStudents(updatedStudents);
}
});
pack();
setLocationRelativeTo(parent);
}
private boolean isValidDate(String dateString) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
try {
dateFormat.parse(dateString);
return true;
} catch (ParseException e) {
return false;
}
}
}
5.文件
package storage;
import model.Student;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class StudentDataStorage {
private final String fileName; // 文件名,用于存储和读取学生数据
// 构造函数,初始化数据存储时要使用的文件名
public StudentDataStorage(String fileName) {
this.fileName = fileName;
}
// 从文件中加载学生列表
public List<Student> loadStudents() {
List<Student> students = new ArrayList<>(); // 创建学生列表
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = reader.readLine()) != null) { // 逐行读取
Student student = parseStudent(line); // 将每行文本解析为学生对象
if (student != null) {
students.add(student); // 添加到学生列表
}
}
} catch (IOException e) {
e.printStackTrace(); // 打印异常堆栈信息
}
return students; // 返回学生列表
}
// 将学生列表保存到文件
public void saveStudents(List<Student> students) {
try (PrintWriter out = new PrintWriter(new FileWriter(fileName))) {
for (Student student : students) { // 遍历学生列表
out.println(studentToFileString(student)); // 将每个学生对象转换为文本行并写入文件
}
} catch (IOException e) {
e.printStackTrace(); // 打印异常堆栈信息
}
}
// 将一行文本解析为学生对象
private Student parseStudent(String line) {
try {
String[] parts = line.split("\t"); // 假设使用制表符作为分隔符
// 解析学生信息的各个部分
String studentId = parts[0];
String name = parts[1];
String gender = parts[2];
String birthDate = parts[3];
String politicalStatus = parts[4];
String address = parts[5];
String phone = parts[6];
String dormitoryNumber = parts[7];
// 创建并返回学生对象
return new Student(studentId, name, gender, birthDate, politicalStatus, address, phone, dormitoryNumber);
} catch (Exception e) {
e.printStackTrace(); // 打印异常堆栈信息
return null; // 在解析出错时返回null
}
}
// 将学生对象转换为一行文本
private String studentToFileString(Student student) {
// 使用制表符分隔学生信息,并返回合成的字符串
return student.getStudentId() + "\t" +
student.getName() + "\t" +
student.getGender() + "\t" +
student.getBirthDate() + "\t" +
student.getPoliticalStatus() + "\t" +
student.getAddress() + "\t" +
student.getPhone() + "\t" +
student.getDormitoryNumber();
}
}
七、使用git管理代码
八、遇到的困难
添加修改,删除学生信息后表格内容不更新
解决方法:每次修改表格内容后重新载入表格