目录
1 题目描述
我完成的是一个学生成绩管理系统
(1)本程序带有登录图形界面。
(2)本程序可以存在有管理员和学生两种用户,登录时各自输入用户名密码。若信息正确则可以登录,信息不正确则不可以登录。
(3)系统至少能够管理100名学生,每一个学生有高数、英语、大学物理等三项成绩,每个学生登录后能够查看自己的成绩。
(4)管理员登录后能够录入、修改、查询、删除任意学生任意课程的成绩。
(5)能够将学生信息保存到硬盘,下次打开程序时还能够从硬盘读取。
2 程序设计
2.1 student类
该类的作用是对学生对象进行封装,包含以下变量和方法:
表1 student的变量
名字 | 类型 | 作用 |
studentId | String | 表示学生用户名(学号) |
studentName | String | 表示学生姓名 |
studentPassword | String | 表示学生密码 |
math | int | 表示学生数学成绩 |
english | int | 表示学生英语成绩 |
physics | int | 表示学生物理成绩 |
表2 student的方法
名字及类型 | 参数列表及用途 | 方法作用 |
Student() | 无 | 空参构造方法 |
Student() | String studentId,传递学生学号 String studentName,传递学生姓名 String studentPassword,传递学生密码 int math,传递学生数学成绩 int english,传递学生英语成绩 int physics传递学生物理成绩 | 有参数构造方法 |
void setStudentId(String studentId) | String studentId传递学生学号 | 设置学生学号 |
void setStudentName(String studentName) | String studentName传递学生姓名 | 设置学生姓名 |
void setStudentPassword(String studentPassword) | String studentPassword传递学生密码 | 设置学生学生密码 |
void setMath(int math) | int math传递学生数学成绩 | 设置数学成绩 |
void setEnglish(int english) | int english传递学生英语成绩 | 设置英语成绩 |
void setPhysics(int physics) | int physics传递学生物理成绩 | 设置物理成绩 |
String getStudentId() | 无 | 获取学生学号 |
String getStudentName() | 无 | 获取学生姓名 |
String getStudentPassword() | 无 | 获取学生学生密码 |
int getMath() | 无 | 获取数学成绩 |
int getEnglish() | 无 | 获取英语成绩 |
int getPhysics() | 无 | 获取物理成绩 |
2.2 manager类
该类的作用是对管理员对象进行封装,包含以下变量和方法:
表3 manager的变量
名字 | 类型 | 作用 |
managerId | String | 表示管理员用户名 |
managerName | String | 表示管理员姓名 |
managerPassword | String | 表示管理员密码 |
表4 manager的方法
名字及类型 | 参数列表及用途 | 方法作用 |
manager() | 无 | 空参构造方法 |
manager() | String managerId,传递管理员学号 String managerName,传递管理员姓名 String managerPassword,传递管理员密码 | 有参数构造方法 |
void setManagerId(String managerId) | String studentId传递管理员学号 | 设置管理员学号 |
void setManagerName(String managerName) | String studentName传递管理员姓名 | 设置管理员姓名 |
void setManagerPassword(String managerPassword) | String studentPassword传递管理员密码 | 设置管理员密码 |
String getManagerId() | 无 | 获取管理员学号 |
String getManagerName() | 无 | 获取管理员姓名 |
String getManagerPassword() | 无 | 获取管理员密码 |
2.3loginUI类
该类的作用是对登录图形界面进行封装,包含以下变量和方法:
表3 loginUI的变量
名字 | 类型 | 作用 |
JLabel nameLabel | 图形界面 | |
JTextField nameField | 图形界面 | |
JLabel passwordLabel | 图形界面 | |
JPasswordField passwordField | 图形界面 | |
JButton loginButton | 图形界面 | |
表4 loginUI的方法
名字及类型 | 参数列表及用途 | 方法作用 |
void loginUi() | 设置登陆的图形界面 | |
void actionPerformed(ActionEvent e) | 实现登陆的图形界面,若输入学生的学号与密码,则输出学生的信息;若登录管理员的账号,则输出的功能菜单。 | |
2.4test类
该类的作用是对学生成绩管理系统的方法进行封装,包含以下变量和方法:
表5 test的变量
名字 | 类型 | 作用 |
students | ArrayList<student> | 存储学生 |
managers | ArrayList<manager> | 存储管理员 |
表6 test的方法
名字及类型 | 参数列表及用途 | 方法作用 |
void main | manager1设置管理员,学工号01,张老师,密码123456 loginUi图形界面 | main函数,运行程序 |
void studentManagement() | select2选择功能 | 管理员的管理系统选择 |
boolean studentLogin (String studentId, String studentPassword ) | String studentId,传入想要登录的学号 String studentPassword传入想要登录的密码 | 学生登陆方法 |
Boolean managerLogin (String managerId, String managerPassword ) | String managerId,传入想要登录的学号 String managerPassword传入想要登录的密码 | 管理员登录方法 |
void addStudent (ArrayList<student> list) | 录入学生信息 添加学生的姓名 添加学生的密码 添加学生的高数成绩 添加学生的英语成绩 添加学生的大物成绩 | |
boolean occupyId (ArrayList<student> list, String id) | 判断id是否已经使用方法,返回值为真假,添加时需要用到 | |
void updateStudent (ArrayList<student> list) | 修改学生信息 | |
void deleteStudent (ArrayList<student> list) | 删除学生信息 | |
int getIndex(ArrayList<student> list,String id) | 通过学号找到索引的方法,删除与查询时会用 | |
void oneQueryStudent (ArrayList<student> list) | 管理员查询学生信息,可以通过学号查询学生信息 | |
void saveStudent() | 保存学生信息到硬盘生成的 students.txt文件 | |
void readStudent() | 读取学生信息文件,保存到学生数组列表 | |
3代码实现
3.1学生类
package courseDesign;
public class student {
//用户名(学号)
private String studentId;
//姓名
private String studentName;
//密码
private String studentPassword;
//高数
private int math;
//英语
private int english;
//物理
private int physics;
//无参构造方法
public student()
{
}
//有参构造方法
public student(String studentId,String studentName,
String studentPassword,int math,
int english,int physics)
{
this.studentId = studentId;
this.studentName = studentName;
this.studentPassword = studentPassword;
this.math = math;
this.english = english;
this.physics = physics;
}
//设置学生id
public void setStudentId(String studentId)
{
this.studentId = studentId;
}
//获取学生id
public String getStudentId()
{
return studentId;
}
//设置学生name
public void setStudentName(String studentName)
{
this.studentName = studentName;
}
//获取学生name
public String getStudentName()
{
return studentName;
}
//设置学生password
public void setStudentPassword(String studentPassword)
{
this.studentPassword = studentPassword;
}
//获取学生password
public String getStudentPassword()
{
return studentPassword;
}
//设置学生高数
public void setMath(int math)
{
this.math = math;
}
//获取学生高数
public int getMath()
{
return math;
}
//设置学生英语
public void setEnglish(int english)
{
this.english = english;
}
//获取学生英语
public int getEnglish()
{
return english;
}
//设置学生大物
public void setPhysics(int physics)
{
this.physics = physics;
}
//获取学生大物
public int getPhysics()
{
return physics;
}
}
3.2管理员类
package courseDesign;
public class manager {
//用户名(工号)
private String managerId;
//姓名
private String managerName;
//密码
private String managerPassword;
//无参构造方法
public manager()
{
}
//有参构造方法
public manager(String managerId,
String managerName,
String managerPassword)
{
this.managerId = managerId;
this.managerName = managerName;
this.managerPassword = managerPassword;
}
//设置管理员id
public void setManagerId(String managerId)
{
this.managerId = managerId;
}
//获取管理员id
public String getManagerId()
{
return managerId;
}
//设置管理员name
public void setManagerName(String managerName)
{
this.managerName = managerName;
}
//获取管理员name
public String getManagerName()
{
return managerName;
}
//设置管理员password
public void setManagerPassword(String managerPassword)
{
this.managerPassword = managerPassword;
}
//获取管理员password
public String getManagerPassword()
{
return managerPassword;
}
}
3.3图形界面类
package courseDesign;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Scanner;
import courseDesign.test;
public class loginUI extends JFrame implements ActionListener{
/*
这个错误是因为 loginUI 类实现了 Serializable 接口,
但是没有定义一个静态的、最终的 serialVersionUID 常量。
在 Java 中,当一个对象需要被序列化或反序列化时,
需要一个 serialVersionUID 常量来确定对象版本的兼容性,
以确保对象在不同版本间的正确传递和解析。为了解决这个问题,
你需要在 loginUI 类中添加一个静态并且最终的 serialVersionUID 常量
所以加入了private static final long serialVersionUID = 1L;
*/
private static final long serialVersionUID = 1L;
private JLabel nameLabel;//文本标签元素
private JTextField nameField;//文本值用户名文本框
private JLabel passwordLabel;//文本值密码文本框
private JPasswordField passwordField;//具有单击行为的按钮元素
private JButton loginButton;//具有单击行为的按钮元素
public void loginUi()
{
this.setTitle("学生成绩管理系统");
this.setSize(450, 200);
this.setLocationRelativeTo(null);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 2));
nameLabel = new JLabel("学工号:");
panel.add(nameLabel);
//名字文本框
nameField = new JTextField();
panel.add(nameField);
passwordLabel = new JLabel("密码:");
panel.add(passwordLabel);
//密码文本框
passwordField = new JPasswordField();
panel.add(passwordField);
loginButton = new JButton("登录");
loginButton.addActionListener(this);
panel.add(loginButton);
this.setContentPane(panel);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == loginButton)
{
String id = nameField.getText();
String password = new String(passwordField.getPassword());
if(test.studentLogin(id, password))
{
//使用登录判断方法,登录后可以查询自己成绩
int i = test.getIndex(test.students, id);
student s = test.students.get(i);
System.out.println(
"你的高数成绩是"+s.getMath()+','
+"英语成绩是"+s.getEnglish()+','
+"大物成绩是"+s.getPhysics());
this.setVisible(false);
}
else if (test.managerLogin(id,password))
{
test.studentManagement();
this.setVisible(false);
}
else
{
JOptionPane.showMessageDialog(this, "学工号或密码错误!");
}
}
}
}
3.4test类
package courseDesign;
import java.util.ArrayList;
import java.util.Scanner;
import java.io.*;
public class test {
static ArrayList<student> students = new ArrayList<>();
static ArrayList<manager> managers = new ArrayList<>();
public static void main(String[] args)
{
readStudent();
//设置管理员,学工号01,张老师,密码123456
manager manager1 = new manager("01","zhanglaoshi","123456");
managers.add(manager1);
Scanner sc=new Scanner(System.in);
//调用登录图形界面方法
loginUI loginUi = new loginUI();
loginUi.loginUi();
System.out.println("欢迎使用学生成绩管理系统!");
}
public static void studentManagement()
{
int select2;
Scanner sc = new Scanner(System.in);
boolean isRunning = true; // 循环控制变量
readStudent();
while (isRunning)
{
// 绘制二级菜单
System.out.println("=====学生管理系统=====");
System.out.println("=====管理员您好!=====");
System.out.println(" 1. 添加学生信息");
System.out.println(" 2. 修改学生信息");
System.out.println(" 3. 查询学生信息");
System.out.println(" 4. 删除学生信息");
System.out.println(" 5. 返回上级");
System.out.println("===================");
System.out.print("输入菜单编号[1,2,3,4,5]:");
select2 = sc.nextInt();
switch (select2)
{
case 1:
System.out.println("----执行添加学生信息功能----");
addStudent(students); // 调用添加学生信息方法
saveStudent(); // 调用保存学生信息方法
break;
case 2:
System.out.println("----执行修改学生信息功能----");
updateStudent(students); // 调用修改学生信息方法
saveStudent(); // 调用保存学生信息方法
break;
case 3:
System.out.println("----执行查询学生信息功能----");
oneQueryStudent(students); // 调用查询学生信息方法
break;
case 4:
System.out.println("----执行删除学生信息功能----");
deleteStudent(students); //调用删除学生信息方法
saveStudent(); // 调用保存学生信息方法
break;
case 5:
isRunning = false; // 结束二级菜单循环
break;
default:
System.out.println("输入的菜单编号有误!");
}
}
}
//管理员是提前设定的,学生可以添加
//输入学工号,自动判定是管理员还是学生,管理员登录后可以选择功能,学生只可以查看自己成绩
//判定需要学工号和密码相匹配
//登录页面
//学生登陆方法
public static boolean studentLogin(String studentId,String studentPassword )
{
//遍历集合,判断学号和姓名是否同时正确,如果正确则查询,错误则返回
for (int i = 0; i<students.size();i++)
{
student ifStu = students.get(i);
if((ifStu.getStudentId().equals(studentId))&&
(ifStu.getStudentPassword().equals(studentPassword)))
{
System.out.println("登录成功");
return true;
}
}
System.out.println("学号和姓名不同时正确,请您检查");
return false;
}
//管理员登录方法
public static boolean managerLogin(String managerId,String managerPassword )
{
//遍历集合,判断学号和姓名是否同时正确,如果正确则查询,错误则返回
for (int i = 0; i<managers.size();i++)
{
manager ifManager = managers.get(i);
if((ifManager.getManagerId().equals(managerId))&&
(ifManager.getManagerPassword().equals(managerPassword)))
{
return true;
}
}
System.out.println("学工号和姓名不同时正确,请您检查");
return false;
}
//录入学生信息
public static void addStudent(ArrayList<student> list)
{
System.out.println("添加学生信息");
student s = new student();
Scanner sc = new Scanner(System.in);
String id = null;
while (true)
{
System.out.println("请输入学生的学号");
id=sc.next();
//判断此id是否已经被用
boolean flag = occupyId(list,id);
if(flag==true)
{
System.out.println("这个ID已经被使用,请重新输入");
}
else
{
//未使用的id被添加
s.setStudentId(id);
System.out.println("该学生的id录入成功");
break;
}
}
//添加学生的姓名
System.out.println("请输入学生的姓名");
String name=sc.next();
s.setStudentName(name);
System.out.println("该学生的姓名录入成功");
//添加学生的密码
System.out.println("请输入学生的密码");
String password=sc.next();
s.setStudentPassword(password);
System.out.println("该学生的姓名录入成功");
boolean temp1 = true;
//添加学生的高数成绩
while(temp1)
{
System.out.println("请输入该学生的高数成绩");
int math=sc.nextInt();
if(math >= 0 && math <= 100)
{
//如果分数合理,则添加学生的高数成绩
s.setMath(math);
System.out.println("该学生的高数成绩录入成功");
temp1 = false;
}
else
{
System.out.println("分数不合理,该学生的高数成绩录入失败");
}
//输入成绩失败将继续输入
}
//添加学生的英语成绩
boolean temp2 = true;
while(temp2)
{
System.out.println("请输入该学生的英语成绩");
int english=sc.nextInt();
if(english >= 0 && english <= 100)
{
//如果分数合理,则添加学生的英语成绩
s.setEnglish(english);
System.out.println("该学生的英语成绩录入成功");
temp2 = false;
}
else
{
System.out.println("分数不合理,该学生的英语成绩录入失败");
}
//输入成绩失败将继续输入
}
//添加学生的大物成绩
boolean temp3 = true;
while(temp3)
{
System.out.println("请输入该学生的大物成绩");
int physics=sc.nextInt();
if(physics >= 0 && physics <= 100)
{
//如果分数合理,则添加学生的大物成绩
s.setPhysics(physics);
System.out.println("该学生的大物成绩录入成功");
temp3 = false;
}
else
{
System.out.println("分数不合理,该学生的大物成绩录入失败");
}
//输入成绩失败将继续输入
}
list.add(s);
System.out.println("学生信息添加成功!");
}
//判断id是否已经使用方法,返回值为真假,添加时需要用到
public static boolean occupyId(ArrayList<student> list,String id)
{
for (int i = 0; i < list.size(); i++)
{
student s = list.get(i);
String StudentId = s.getStudentId();
if(StudentId.equals(id))
{
return true;
}
}
return false;
}
//修改学生信息
public static void updateStudent(ArrayList<student> list)
{
//键盘录入要修改的学生学号
Scanner sc = new Scanner(System.in);
System.out.println("请输入要修改成绩的学生的学号");
String findId = sc.next();
//键盘输入要修改的学生姓名
System.out.println("请输入要修改成绩的学生姓名");
String findName = sc.next();
//遍历集合,判断学号和姓名是否同时正确,如果正确则修改,错误则返回
for (int i = 0; i<list.size();i++)
{
student lastStu = list.get(i);
if((lastStu.getStudentId().equals(findId))&&
(lastStu.getStudentName().equals(findName)))
{
//键盘输入要修改的学生成绩
System.out.println("请输入该学生的修改后的高数成绩");
int nextMath=sc.nextInt();
System.out.println("请输入该学生的修改后的英语成绩");
int nextEnglish=sc.nextInt();
System.out.println("请输入该学生的修改后的大物成绩");
int nextPhysics=sc.nextInt();
//创建学生对象
student updateStu = new student();
updateStu.setStudentName(findName);
updateStu.setMath(nextMath);
updateStu.setEnglish(nextEnglish);
updateStu.setPhysics(nextPhysics);
list.set(i, updateStu);
//给出修改成功提示
System.out.println("修改成功");
System.out.println(updateStu.getStudentName()
+"的高数成绩是"+updateStu.getMath()+','
+"的英语成绩是"+updateStu.getEnglish()+','
+"的大物成绩是"+updateStu.getPhysics());
}
else
{
System.out.println("学号和姓名不同时正确,请您检查");
}
}
}
//删除学生信息
public static void deleteStudent(ArrayList<student> list)
{
System.out.println("请输入要删除成绩的学生的学号");
Scanner sc=new Scanner(System.in);
String id=sc.next();
int index=getIndex(list,id);
if(index>=0)
{
list.remove(index);
System.out.println("删除成功");
}
else
{
System.out.println("学号输入有误,请检查");
}
}
//通过学号找到索引的方法,删除与查询时会用
public static int getIndex(ArrayList<student> list,String id)
{
for (int i = 0; i < list.size(); i++)
{
student stu = list.get(i);
String sid = stu.getStudentId();
//如果要找的id和集合里的sid相同,则返回集合的索引
if(sid.equals(id))
{
return i;
}
}
return -1;
}
//因为管理员和学生需求不同,管理员可以按学号查询学生成绩,学生只需要进入查看自己成绩就好,因此写两个方法
//管理员查询学生信息
public static void oneQueryStudent(ArrayList<student> list)
{
//没有学生时不支持查询
if(list.size()==0)
{
System.out.println("目前无学生,请添加后查询");
return;
}
//有学生时支持查询
else
{
System.out.println("请输入要查询成绩的学生的学号");
Scanner sc=new Scanner(System.in);
String id=sc.next();
int index=getIndex(list,id);
if(index>=0)
{
student s = list.get(index);
System.out.println(s.getStudentName()
+"的高数成绩是"+s.getMath()
+",英语成绩是"+s.getEnglish()
+",大物成绩是"+s.getPhysics());
}
else
{
System.out.println("学号输入有误,请检查");
}
}
}
//学生查询学生信息
/*public static void twoQueryStudent(ArrayList<student> list)
{
Scanner sc = new Scanner(System.in);
String id = sc.next();
int index = getIndex(list,id);
if(index >= 0)
{
student s = list.get(index);
System.out.println(
"你的高数成绩是"+s.getMath()+','
+"英语成绩是"+s.getEnglish()+','
+"大物成绩是"+s.getPhysics());
}
else
{
System.out.println("学号输入有误,请检查");
}
}
*/
//保存学生信息到文件
public static void saveStudent()
{
try (BufferedWriter writer = new BufferedWriter(new FileWriter("students.txt")))
{
for (student student : students)
{
//调用writer的write方法写入
writer.write(student.getStudentId() + ","+
student.getStudentName() + ","+
student.getStudentPassword()+","+
student.getMath()+ "," +
student.getEnglish()+ "," +
student.getPhysics());
writer.newLine();
}
}
catch (IOException e)
{
e.getMessage();
}
System.out.println("保存学生信息到文件\"students.txt\"成功!");
}
//读取学生信息文件,保存到学生数组列表
public static void readStudent()
{
try (BufferedReader reader = new BufferedReader(new FileReader("students.txt")))
{
String line;
while ((line = reader.readLine()) != null)
{
String[] imformation = line.split(",");
if(imformation.length>=6)
{
String id = imformation[0];
String name = imformation[1];
String password = imformation[2];
int math = Integer.parseInt(imformation[3]);
int english = Integer.parseInt(imformation[4]);
int physics = Integer.parseInt(imformation[5]);
student stu = new student(id,name,password,math,english,physics);
students.add(stu);
}
}
}
catch (IOException e)
{
e.getMessage();
}
}
}
4写程序中发现的问题及不足
写完图形界面后,发现报错The package javax.swing is not accessible,查找资料得知,
这个错误表示你正在尝试使用 javax.swing
包,但它是不可访问的。在 Java 9 中,模块化系统被引入,这意味着每个库都被分割成一个或多个模块,以允许更严格的访问控制。因此,一些库可能已被标记为不可访问模块。
对于 javax.swing
包,从 Java 9 开始,它已被标记为不可访问的模块。这意味着你需要在模块描述文件 (module-info.java
) 中将其声明为需要使用的模块,才能在你的代码中访问该包。如果你不使用模块化系统,则可以将程序编译为旧版的 Java,这样 javax.swing
包就可以被访问了。
如果你需要在 Java 9 或更高版本中使用 javax.swing
包,以下是解决方法:
在模块描述文件 (module-info.java
) 中声明 javax.swing
模块,如下所示:
module mymodule {
requires java.desktop; // 声明需要使用 java.desktop 模块
}
在这里,requires
声明需要使用的模块,包含了 javax.swing
包的所在模块 java.desktop
,它是包含 Swing 组件的标准 Java 桌面模块。通过这个声明,你的程序就能够访问 javax.swing
包了。
代码的不足就是写入和读取文件时,以及修改和删除后,会有bug
5测试部分截图
5.1管理员登录
提前设置管理员,学工号01,张老师,密码123456
输入不正确的信息,会提示登录不正确
输入正确的信息后,管理员就进入管理系统。输入学工号,自动判定是管理员还是学生,管理员登录后可以选择功能,学生只可以查看自己成绩。
5.2添加学生信息
添加成功后就可以保存学生信息到文件
5.3查询学生信息
5.4修改学生信息
如果修改时不能正确输入学号和姓名,则不能修改
5.5删除学生信息
删除后打开文件,发现文件里的信息也被删除
添加了一个学生,学号001,姓名小明,密码123456,高数99,英语98,大物97
如果输入不正确的账号密码,则会报错
输入信息正确后,学生则可以查看自己的成绩
6总结
还要再努力呀!!!