目录
第1章 任务描述
1.编程实现学生成绩管理系统,学生成绩信息记录的组成自行设定。
2.功能要求:、
(1)实现以下基本功能:
(2)增加学生及其成绩
(3)删除学生及其成绩
(4)修改学生及其成绩
(5)查找学生及其成绩
(6)升序/降序排序学生各门功课成绩
(7)统计学生成绩
(8)IO流形成文件保存/读入学生成绩
3.实现GUI图形界面程序,完成以上功能
4.实现控制台程序,自己完成功能函数,完成以上功能
第2章 总体设计
2.1框架结构
表2.1 框架结构
平台 | Window 10 |
软件 | IntelliJ IDEA Community Edition 2022.1.1 |
编程语言 | Java |
编程框架 | util,awt ,swing,io |
图2.1 目录结构
第3章 详细设计
列出了主要类和主要方法名,以及类和方法的用途,方法体内容省略,进行大概理解整体框架结构。主要有Student,StudentManager,MainJfram类
3.1 Student类
本程序中最基本的元数据
public class Student implements Comparable<Student>{
private int sid;//学生学号
private String name;//学生姓名
private double english_score;//英语成绩
private double chinese_score;//语文成绩
private double math_score;//数学成绩
private double physics_score;//物理成绩
private double chemical_score;//化学成绩
private double score;//总分
public static int sortM;//排序方式 俩位数 第一位 0-降序 1-升序 第二位排方式 1-序号。。。
//无参构造
public Student(){}
//含参构造
public Student(int sid, String name, double english_score, double chinese_score, double math_score, double physics_score, double chemical_score) {...}
// getter setter 方法 Alt+insert按键快速生成
public int getSid() {...}
public void setSid(int sid) {...}
public String getName() {...}
public void setName(String name) {...}
public double getEnglish_score() {...}
public void setEnglish_score(double english_score) {...}
public double getChinese_score() {...}
public void setChinese_score(double chinese_score) {...}
public double getMath_score() {...}
public void setMath_score(double math_score) {...}
public double getPhysics_score() {...}
public void setPhysics_score(double physics_score) {...}
public double getChemical_score() {...}
public void setChemical_score(double chemical_score) {...}
public double getScore() {return score;}{...}
public void setScore(double score) {...}
public static void setSortM(int sortM) {...}
//重写sort排序算法
@Override
public int compareTo(Student s){...}
3.2 StudentManager类
主要作为控制台程序,自定义函数体实现,增删改查排以及文件IO。含程序入口main函数
public class StudentManager {
private static String stuFile="学生及其成绩名单.txt";//保存的文件名
public static File file=new File(stuFile);
public static ArrayList<Student> array=new ArrayList<>(); //创建学生数组
//主函数
public static void main(String[] args) {...}
//写文件-保存
public static void write(File file){...}
//读文件-读取
public static void read(File file){...}
//展示下标为i个学生
public static void showIStu(ArrayList<Student> array,int i){...}
//展示所有学生
public static void showStudent(ArrayList<Student> array) {...}
//暂停
public static void pause(){...}
//增添学生
public static void addStudent(ArrayList<Student> array){...}
//判断学号是否存在,学号的唯一性
public static boolean isUsed(ArrayList<Student> array,int sid){...}
//删除学生
public static void delStudent(ArrayList<Student> array) {...}
//修改学生
public static void modStudent(ArrayList<Student> array) {...}
//查找学生下标 返回下标,-1为没有找到
public static int findStudentIn(ArrayList<Student> array){...}
//查找学生
public static void findStudent(ArrayList<Student> array) {...}
//排序学生
public static void sortStudent(ArrayList<Student> array){...}
}
3.3 MainJframe类
主要作为gui程序,用来展示表格界面,使得表格操作可视化。
public class MainJframe extends JFrame{
private static ArrayList<Student> array=new ArrayList<Student>(); //接收学生数组
//创建窗口
private static JFrame frame=new JFrame("学生成绩管理系统(操作完记得在‘功能’里‘保存文件’)");
//表格
private static JTable t=new JTable(){};
//滚动标题表格
private static JScrollPane sp=new JScrollPane();
//操作按钮
private static JButton b=new JButton(" ");
//搜索框
private static JTextField jtf;
private static JLabel searchLbl;
private static DefaultTableModel tM;
//绑定学生数组 主界面-初始化窗口 菜单栏
public MainJframe(){...}
//菜单栏 组装菜单栏 为按钮添加监听事件
public static void meau(){...}
//菜单监听器
private static class itemListener implements ActionListener {...}
//主页面
public static void mainshow(){...}
//浏览学生
public static void showStudent(){...}
//修改学生
public static void modStudent(){...}
//排序学生
public static void sortStudent(){...}
//增添学生
public static void addStudent(){...}
//删除学生
public static void delStudent(){...}
//查找学生
public static void findStudent(){...}
//IO流保存文件
private static void save(){...}
//相关介绍
public static void message(){...}
//操作按钮监听器
private static class buttonListener implements ActionListener{...}
}
4.1 控制台程序及其主界面
图4.1 控制台程序及其主界面
public class StudentManager {
...
//主函数
public static void main(String[] args) {
// 系统开始读取文件
read(file);
//界面
MainJframe f=new MainJframe();
//循环系统功能
while (true)
{
//主界面
System.out.println("------欢迎来到学生成绩管理系统------");
System.out.println("0.浏览学生及其成绩");
System.out.println("1.添加学生及其成绩");
System.out.println("2.删除学生及其成绩");
System.out.println("3.修改学生及其成绩");
System.out.println("4.查找学生及其成绩");
System.out.println("5.排序学生及其成绩");
System.out.println("6.退出");
System.out.println("--***请输入你的选择***--");
//Scanner键盘录入数据
Scanner sc=new Scanner(System.in);
String line =sc.nextLine();
//用Switch选择
switch(line)
{case "0":
System.out.println("浏览学生及其成绩");
showStudent(array);
break;
case "1":
System.out.println("添加学生");
addStudent(array);
break;
case "2":
System.out.println("删除学生");
delStudent(array);
break;
case "3":
System.out.println("修改学生");
modStudent(array);
break;
case "4":
System.out.println("查找学生");
findStudent(array);
break;
case "5":
System.out.println("排序学生");
sortStudent(array);
break;
case "6":
System.out.println("谢谢使用");
System.exit(0);
break;
}
}
...
}
}
4.2 GUI程序及其主页面
图4.2 gui程序及其主页面
public class MainJframe extends JFrame{
...
public MainJframe(){
//绑定学生数组
array=StudentManager.array;
//初始化窗口
frame.setLocation(100,100);
frame.setSize(700,800);
frame.setLayout(null);
//菜单栏
meau();
//主界面-初始化窗口
mainshow();
showStudent();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void meau()
{
//菜单栏
JMenuBar mb=new JMenuBar();
JMenu a=new JMenu("功能");
JMenu b=new JMenu("关于");
JMenuItem a1=new JMenuItem("浏览");
JMenuItem a2=new JMenuItem("添加");
JMenuItem a3=new JMenuItem("删除");
JMenuItem a4=new JMenuItem("修改");
JMenuItem a5=new JMenuItem("查找");
JMenuItem a6=new JMenuItem("排序");
JMenuItem a7=new JMenuItem("*保存文件*");
JMenuItem b1=new JMenuItem("相关介绍");
JMenuItem b2=new JMenuItem("退出系统");
//组装菜单栏
mb.add(a);
mb.add(b);
a.add(a1);
a.add(a2);
a.add(a3);
a.add(a4);
a.add(a5);
a.add(a6);
a.add(a7);
b.add(b1);
b.add(b2);
//为按钮添加监听事件
a1.addActionListener(new itemListener());
a2.addActionListener(new itemListener());
a3.addActionListener(new itemListener());
a4.addActionListener(new itemListener());
a5.addActionListener(new itemListener());
a6.addActionListener(new itemListener());
a7.addActionListener(new itemListener());
b1.addActionListener(new itemListener());
b2.addActionListener(new itemListener());
frame.setJMenuBar(mb);
}
public static void mainshow()
{
//表格上的title
String[] title =new String[]{"学号","姓名","英语成绩","语文成绩","数学成绩","物理成绩","化学成绩","总分"};
//表格里的内容
String[][] items=new String[array.size()][8];
//填充内容
for(int i=0;i<array.size();i++)
{
items[i][0]=array.get(i).getSid()+"";
items[i][1]=array.get(i).getName();
items[i][2]=array.get(i).getEnglish_score()+"";
items[i][3]=array.get(i).getChinese_score()+"";
items[i][4]=array.get(i).getMath_score()+"";
items[i][5]=array.get(i).getPhysics_score()+"";
items[i][6]=array.get(i).getChemical_score()+"";
items[i][7]=array.get(i).getScore()+"";
}
//创建表格
tM=new DefaultTableModel(items,title);
t=new JTable(tM);
t.setRowHeight(30);
//排序
t.setRowSorter(new TableRowSorter<>(t.getModel()));
//滚动标题表格
sp=new JScrollPane(t);
//操作按钮
b.setText("操作按钮");
b.setBackground(Color.gray);
b.setFont(new Font("",Font.BOLD,55));
b.addActionListener(new buttonListener());
//搜索框
jtf = new JTextField(15);
searchLbl = new JLabel("Search");
TableRowSorter sorter = new TableRowSorter<>(t.getModel());
t.setRowSorter(sorter);
jtf.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
search(jtf.getText());
}
@Override
public void removeUpdate(DocumentEvent e) {
search(jtf.getText());
}
@Override
public void changedUpdate(DocumentEvent e) {
search(jtf.getText());
}
public void search(String str) {
if (str.length() == 0) {
sorter.setRowFilter(null);
} else {
sorter.setRowFilter(RowFilter.regexFilter(str));
}
}
});
frame.setLayout(new BorderLayout());
frame.add(sp,BorderLayout.CENTER);
frame.add(b,BorderLayout.SOUTH);
frame.add(searchLbl,BorderLayout.NORTH);
frame.add(jtf,BorderLayout.NORTH);
frame.setVisible(true);
}
...
}
第5章 代码设计
此部分主要用来介绍一些主要功能代码,详细到方法体内容。
5.1.1文件IO流
//写文件-保存
public static void write(File file)
{
try {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file, false), "utf-8");
//每行一个学生,按空格中断信息
for (Student s : array) {
osw.write(s.getSid()+" ");
osw.write(s.getName()+" ");
osw.write(s.getEnglish_score()+" ");
osw.write(s.getChinese_score()+" ");
osw.write(s.getMath_score()+" ");
osw.write(s.getPhysics_score()+" ");
osw.write(s.getChemical_score()+"\n");
}
osw.close();//关闭流
System.out.println("已保存"+"《"+stuFile+"》");
}catch(IOException e){e.printStackTrace();}
}
//读文件-读取
public static void read(File file){
try{
BufferedReader br=new BufferedReader(new FileReader(file));
String line=null;//每行读取
while((line=br.readLine())!=null) {
String[] arr=new String[7];
arr=line.split(" ");//切片读取每个人信息
//创建对象并输入数组
Student s=new Student(Integer.parseInt(arr[0]),arr[1],Double.parseDouble(arr[2]),Double.parseDouble(arr[3]),Double.parseDouble(arr[4]),Double.parseDouble(arr[5]),Double.parseDouble(arr[6]));
array.add(s);
}
br.close();//关闭流
System.out.println("已读取"+"《"+stuFile+"》");
}catch (IOException e)
{
e.printStackTrace();
}
}
5.1.2 增
public static void addStudent(ArrayList<Student> array){
int sid;
Double english_score;
Double chinese_score;
Double math_score;
Double physics_score;
Double chemical_score;
//键盘录入所需要信息
Scanner sc=new Scanner(System.in);
while (true) {
System.out.println("请输入学生学号");
sid = Integer.parseInt(sc.nextLine());
boolean flag=isUsed(array,sid);
if(flag) {
System.out.println("学号已被使用!!");
}
else{break;}
}
System.out.println("请输入学生姓名");
String name=sc.nextLine();
do{
System.out.println("请输入英语成绩(0-100)");
english_score=Double.parseDouble(sc.nextLine());
}
while (!(english_score<100&&english_score>0));
do{
System.out.println("请输入语文成绩(0-100)");
chinese_score=Double.parseDouble(sc.nextLine());}
while (!(chinese_score<100&&english_score>0));
do{
System.out.println("请输入数学成绩(0-100)");
math_score=Double.parseDouble(sc.nextLine());}
while (!(math_score<100&&english_score>0));
do{
System.out.println("请输入物理成绩(0-100)");
physics_score=Double.parseDouble(sc.nextLine());}
while (!(physics_score<100&&english_score>0));
do{
System.out.println("请输入化学成绩(0-100)");
chemical_score=Double.parseDouble(sc.nextLine());}
while (!(chemical_score<100&&english_score>0));
//含参构造创建对象
Student s=new Student(sid,name,english_score,chinese_score,math_score,physics_score,chemical_score);
//将学生对象添加到集合中
array.add(s);
write(file);
}
//判断学号是否存在,学号的唯一性
public static boolean isUsed(ArrayList<Student> array,int sid)
{
boolean flag=false;
for(int i=0 ;i<array.size();i++)
{
Student s=array.get(i);
if(s.getSid()==sid)
{flag=true;
break;}
}
return flag;
}
5.1.3 删
//删除学生
public static void delStudent(ArrayList<Student> array) {
showStudent(array);
int i=findStudentIn(array);//查找下标
if(i==-1){ System.out.println("找不到此人!");pause();return;}
array.remove(i);
System.out.println("删除成功");
write(file);
pause();
}
5.1.4 改
//修改学生
public static void modStudent(ArrayList<Student> array) {
int i=findStudentIn(array);//查找下标
if(i==-1){ System.out.println("找不到此人!");return;}
//键盘录入所需要信息
int sid;
Double english_score;
Double chinese_score;
Double math_score;
Double physics_score;
Double chemical_score;
Scanner sc=new Scanner(System.in);
while (true) {
System.out.println("请输入学生学号");
sid = Integer.parseInt(sc.nextLine());
boolean flag=isUsed(array,sid);
if(flag) {
if(array.get(i).getSid()==sid){break;}
System.out.println("学号已被使用!!");
}
else{break;}
}
System.out.println("请输入新的学生姓名");
String name=sc.nextLine();
do{
System.out.println("请输入新的英语成绩(0-100)");
english_score=Double.parseDouble(sc.nextLine());
}
while (!(english_score<100&&english_score>0));
do{
System.out.println("请输入新的语文成绩(0-100)");
chinese_score=Double.parseDouble(sc.nextLine());}
while (!(chinese_score<100&&english_score>0));
do{
System.out.println("请输入新的数学成绩(0-100)");
math_score=Double.parseDouble(sc.nextLine());}
while (!(math_score<100&&english_score>0));
do{
System.out.println("请输入新的物理成绩(0-100)");
physics_score=Double.parseDouble(sc.nextLine());}
while (!(physics_score<100&&english_score>0));
do{
System.out.println("请输入新的化学成绩(0-100)");
chemical_score=Double.parseDouble(sc.nextLine());}
while (!(chemical_score<100&&english_score>0));
//含参构造创建对象
Student s=new Student(sid,name,english_score,chinese_score,math_score,physics_score,chemical_score);
//修改
array.set(i,s);
write(file);
System.out.println("修改成功!");
pause();
}
5.1.5 查
//查找学生下标 返回下标,-1为没有找到
public static int findStudentIn(ArrayList<Student> array) {
Student s=new Student(0,"查无此人",0,0,0,0,0);
System.out.println("请输入要操作的学号或姓名");
Scanner sc=new Scanner(System.in);
String line=sc.nextLine();
for(int i=0;i<array.size();i++)
{
if(array.get(i).getSid()== Integer.parseInt(line)||array.get(i).getName()== line)
{
return i;
}
}
return -1;
}
//查找学生
public static void findStudent(ArrayList<Student> array) {
int i=findStudentIn(array);
if(i==-1){
System.out.println("未找到此人!");
pause();
return;
}
showIStu(array,i);
pause();
}
5.1.6 排
//排序学生
public static void sortStudent(ArrayList<Student> array) {
Scanner sc=new Scanner(System.in);
//排序方式
System.out.println("请输入排序方式 0-降序 1-升序");
int sort=Integer.parseInt(sc.nextLine());
//排序对象
System.out.println("请输入排序对象 1-学号 2-英语成绩 3-语文成绩 4-数学成绩 5-物理成绩 6-化学成绩 7-总分");
int M=Integer.parseInt(sc.nextLine());
Student.sortM=sort*10+M%10;//修改类的静态对象sortM,全部类通用一个数
//排序,调用类的compareTo
Collections.sort(array);
write(file);
showStudent(array);
}
}
Student类下重写排序算法
public class Student implements Comparable<Student>{
...
//重写sort排序算法
@Override
public int compareTo(Student s)
{
int M=sortM%10;
if (sortM>10) {
switch (M){
case 1:return this.sid - s.sid;
case 2:return (int)Math.round(this.english_score-s.english_score);
case 3:return (int)Math.round(this.chinese_score-s.chinese_score);
case 4:return (int)Math.round(this.math_score - s.math_score);
case 5:return (int)Math.round(this.physics_score - s.physics_score);
case 6:return (int)Math.round(this.chemical_score- s.chemical_score);
case 7:return (int)Math.round(this.score - s.score);
default:
System.out.println("输入错误!!");
}
}
else{
switch (M){
case 1:return -(this.sid - s.sid);
case 2:return -(int)Math.round(this.english_score-s.english_score);
case 3:return -(int)Math.round(this.chinese_score-s.chinese_score);
case 4:return -(int)Math.round(this.math_score - s.math_score);
case 5:return -(int)Math.round(this.physics_score - s.physics_score);
case 6:return -(int)Math.round(this.chemical_score- s.chemical_score);
case 7:return -(int)Math.round(this.score - s.score);
default:
System.out.println("输入错误!!");
}
}
return -(this.sid - s.sid);
}
...
}
5.2.1文件IO流
//IO流保存文件
private static void save(){
try {
ArrayList<Student> array = new ArrayList<>();//空学生数组
int rc = t.getRowCount();//获取行数
int cc = t.getColumnCount();//获取列数
for (int i = 0; i < rc; i++) {
int sid = Integer.parseInt((String) t.getValueAt(i, 0));
String name = (String) t.getValueAt(i, 1);
double english_score = Double.parseDouble((String) t.getValueAt(i, 2));
double chinese_score = Double.parseDouble((String) t.getValueAt(i, 3));
double math_score = Double.parseDouble((String) t.getValueAt(i, 4));
double physics_score = Double.parseDouble((String) t.getValueAt(i, 5));
double chemical_score = Double.parseDouble((String) t.getValueAt(i, 6));
Student s = new Student(sid, name, english_score, chinese_score, math_score, physics_score, chemical_score);
array.add(s);
}
StudentManager.array = array;
StudentManager.write(StudentManager.file);
System.out.println("已保存" + "《" + StudentManager.file.getName() + "》");
}catch(Exception e)
{
JOptionPane.showMessageDialog(null,e.getMessage(),"错误",JOptionPane.PLAIN_MESSAGE);
}
}
5.2.2 增
//操作按钮监听器
private static class buttonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {//设置触发方法
JButton b = (JButton)arg0.getSource();//事件.getSource()---通过事件返回一个动作触发的组件(强制转换)
switch (b.getText())
{
case "操作按钮": break;
case "添加":tM.addRow(new Vector());break;
case "删除": {
int row = t.getSelectedRow();
if (row >= 0) {
tM.removeRow(row);
} else {
JOptionPane.showMessageDialog(null, "请选择你要删除的行", "删除", JOptionPane.PLAIN_MESSAGE);
} ;
save();
break;
}
};
}
}
5.2.3 删
//操作按钮监听器
private static class buttonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {//设置触发方法
JButton b = (JButton)arg0.getSource();//事件.getSource()---通过事件返回一个动作触发的组件(强制转换)
switch (b.getText())
{
case "操作按钮": break;
case "添加":tM.addRow(new Vector());break;
case "删除": {
int row = t.getSelectedRow();
if (row >= 0) {
tM.removeRow(row);
} else {
JOptionPane.showMessageDialog(null, "请选择你要删除的行", "删除", JOptionPane.PLAIN_MESSAGE);
} ;
save();
break;
}
};
}
}
5.2.4 改
public static void modStudent()
{
//表格可修改
t.setEnabled(true);
}
5.2.5 查
//搜索框
jtf = new JTextField(15);
searchLbl = new JLabel("Search");
TableRowSorter sorter = new TableRowSorter<>(t.getModel());
t.setRowSorter(sorter);
jtf.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
search(jtf.getText());
}
@Override
public void removeUpdate(DocumentEvent e) {
search(jtf.getText());
}
@Override
public void changedUpdate(DocumentEvent e) {
search(jtf.getText());
}
public void search(String str) {
if (str.length() == 0) {
sorter.setRowFilter(null);
} else {
sorter.setRowFilter(RowFilter.regexFilter(str));
}
}
});
5.2.6 排
t.setRowSorter(new TableRowSorter<>(t.getModel()));