Skip to content

RealBeBetter/exam-system

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

【软件工程课程设计】学生在线考试系统

所有密码默认均为 123456

测试系统环境:

  • Windows10 系统
  • MySQL 8.0.23
  • JDK 14

导入试卷:

如果发生文件找不到,请在下面的代码中修改

src/com/company/testpaper/AddPaper.java

将其中的文件读取信息修改成相对路径

BufferedReader br = new BufferedReader(new FileReader("D:\\Java\\IdeaProjects\\StudentOnlineExaminationSystem\\Test.txt"));

修改为:

BufferedReader br = new BufferedReader(new FileReader("StudentOnlineExaminationSystem\\Test.txt"));

阅前注意

系统中所有密码均已默认设置为123456

开发时使用的Java版本为JDK 14.0.1 使用的开发工具为 IntelliJ IDEA Community 2019.2 数据库为MySQL 8.0.23.0 已在Windows10下通过测试

一、数据库设计

  • 数据库

    • 考试系统 ExamSystem
  • 数据表

    • 学生表 STUDENT

      create table student ( sname varchar(10) not null, -- 姓名 sno varchar(20) primary key not null, -- 学号 password varchar(20) not null, -- 密码 ssex varchar(4) not null, -- 性别 sage varchar(4) not null, -- 年龄 major varchar(10) not null, -- 专业 department varchar(10) not null -- 系别 );

      
      
    • 教师表 TEACHER

      create table teacher ( tno varchar(20) not null primary key, -- 教师工号 password varchar(20) not null, -- 教师密码 tname varchar(10) not null, -- 教师姓名 tsex varchar(4) not null -- 教师性别 );

      
      
    • 学生课程表 SC

      create table sc ( sno varchar(20) not null primary key, -- 学生学号 score int not null, -- 课程得分 foreign key(sno) references student(sno) );

      
      
    • 题目答案表 TEST

      create table test ( num int auto_increment primary key not null, -- 题目号码 question varchar(500) not null, -- 题目文本 answer varchar(10) not null -- 标准答案 );

      
      
    • 管理员表 ADMINISTRATOR

      create table administrator ( password varchar(20) not null -- 管理员密码 )comment = '后期使用JDBC时候,不允许添加';

      
      

创建数据库代码:

create database examsystem;
use examsystem;
create table administrator
(
    password varchar(20) not null            -- 管理员密码
)comment = '后期使用JDBC时候,不允许添加';
insert into administrator values("123456");
create table test
(
    num int auto_increment primary key not null, 			
    question varchar(500) not null,    		 
    answer varchar(10) not null			     
);
create table student
(
    sname varchar(10) not null,				 -- 姓名
    sno varchar(20) primary key not null,  	 -- 学号
    password varchar(20) not null,	  		 -- 密码
    ssex varchar(4) not null,				 -- 性别
    sage varchar(4) not null,				 -- 年龄
    major varchar(10) not null,				 -- 专业
    department varchar(10) not null			 -- 系别
);
create table teacher
(
    tno varchar(20) not null primary key, 		-- 教师工号
    password varchar(20) not null,				-- 教师密码
    tname varchar(10) not null,					-- 教师姓名
    tsex varchar(4) not null					-- 教师性别
);
create table sc
(
    sno varchar(20) not null primary key,		-- 学生学号
    score int not null,							-- 课程得分
    foreign key(sno) references student(sno)
);

二、逻辑设计

整个考试系统应该结合实际情况来,先让考生登录自己的账号。

之后进入考试系统,答题,系统判断答题情况,打分。

记录学生分数,提供查询通道。

实现功能顺序 V1.0

  • 学生输入学号密码进行登录
  • 系统按照顺序出题
  • 学生答题同时开始考试倒计时
  • 学生提交答案
  • 系统批改试卷
  • 成绩上传至数据库
  • 学生成绩展示

实现功能顺序 V2.0

  • 用户选择身份 SelectIdentity
    • 用户为学生,选择学生注册/登录 【选做:添加回到上一级菜单】 StudentSelect
      • 学生注册,存储学生信息 StudentRegister
      • 学生登录,登录成功则开始考试答题【选做:可以提供更改密码功能】StudentLogin
        • 学生答题同时开始考试倒计时 MainView Countdown
        • 学生提交答案或者倒计时结束自动提交答案 MainView showScore
        • 答案批改,并将成绩上传数据库,同时予以前台展示 showScore
    • 用户选择为教师,需要输入管理员密码验证身份 CheckIdentity
      • 教师选择注册/登录 TeacherSelect
        • 教师注册,需要输入管理员密码来验证身份【选做:可加入管理员密码修改功能】 TeacherRegister
        • 教师登录,登录之后可选相应的功能【选做:可以提供更改密码功能】TeacherLogin
          • 教师信息展示 TeacherView
          • 教师可以修改学生分数、查询学生分数、添加题目【选做:修改分数需要留下日志】TeacherView

程序运行逻辑顺序

  • 用户选择身份--> 学生/教师
    • 学生选择注册/登录 (同时关闭选择页面)
      • 注册-->输入各项信息,注册成功,进入登录界面(同时关闭注册页面)
      • 登录--> 登录成功,进入考试主页面(同时关闭登录页面)
        • 考生开始答题,结束的时候计算成绩,弹出成绩
    • 教师身份验证-->输入管理员密码(防止学生进入后台进行操作)-->正确即可选择注册/登录
      • 注册--> 输入信息成功注册,进入登录界面
      • 登录-->进入教师主页面,可以选择查询成绩/修改成绩/添加试题操作
        • 查询成绩,查询所有学生的成绩
        • 修改成绩,根据学生的学号对成绩进行修改
        • 添加试题,根据提示添加试题信息进行添加
        • 添加试卷,利用准备好的试卷直接批量导入试题

三、代码实现

首先查看代码的结构如下:

image-20210512105753569

配置文件:resources/jdbc.properties

url=jdbc:mysql://localhost:3306/ExamSystem?serverTimezone=UTC
user=root
password=123456
driver=com.mysql.cj.jdbc.Driver

学生类:student/Student.java

package com.company.student;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:22
 */
public class Student {
    // 创建学生类,包含学生对象的各种属性信息
    private String studentName;
    private long studentId;
    private String studentSex;
    private int studentAge;
    private int studentScore;
    // 学生学院、专业信息
    private String studentDepartment;
    private String studentMajor;

    @Override
    public String toString() {
        return "Student{" +
                "studentName='" + studentName + '\'' +
                ", studentId=" + studentId +
                ", studentSex='" + studentSex + '\'' +
                ", studentAge=" + studentAge +
                ", studentScore=" + studentScore +
                ", studentDepartment='" + studentDepartment + '\'' +
                ", studentMajor='" + studentMajor + '\'' +
                '}';
    }

    public Student() {
    }

    public Student(String studentName, long studentId, String studentSex, int studentAge, int studentScore, String studentDepartment, String studentMajor) {
        this.studentName = studentName;
        this.studentId = studentId;
        this.studentSex = studentSex;
        this.studentAge = studentAge;
        this.studentScore = studentScore;
        this.studentDepartment = studentDepartment;
        this.studentMajor = studentMajor;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public long getStudentId() {
        return studentId;
    }

    public void setStudentId(long studentId) {
        this.studentId = studentId;
    }

    public String getStudentSex() {
        return studentSex;
    }

    public void setStudentSex(String studentSex) {
        this.studentSex = studentSex;
    }

    public int getStudentAge() {
        return studentAge;
    }

    public void setStudentAge(int studentAge) {
        this.studentAge = studentAge;
    }

    public int getStudentScore() {
        return studentScore;
    }

    public void setStudentScore(int studentScore) {
        this.studentScore = studentScore;
    }

    public String getStudentDepartment() {
        return studentDepartment;
    }

    public void setStudentDepartment(String studentDepartment) {
        this.studentDepartment = studentDepartment;
    }

    public String getStudentMajor() {
        return studentMajor;
    }

    public void setStudentMajor(String studentMajor) {
        this.studentMajor = studentMajor;
    }
}

添加试题:teacher/AddQuestion.java

package com.company.teacher;

import com.company.utils.JDBCUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:41
 */
public class AddQuestion extends JFrame implements ActionListener {
    String[] stringAnswer = {"-请选择-", "A", "B", "C", "D"};

    int questionFlag = 0;

    JLabel questionNum = new JLabel("现有题号从:" + getQuestionFlag() + " 开始:");
    JLabel questionText = new JLabel("请输入题目内容:");
    JLabel questionAnswer = new JLabel("请选择题目答案:");

    // JTextField jtfNum = new JTextField();
    JTextArea jtfText = new JTextArea(20, 40);
    JComboBox jcbAnswer = new JComboBox(stringAnswer);

    JButton btnOk = new JButton("确认");
    JButton btnCancel = new JButton("取消");

    public AddQuestion() {
        JPanel jPanel1 = new JPanel();
        questionNum.setBounds(350, 50, 200, 30);
        // jtfNum.setBounds(350, 80, 300, 25);
        add(questionNum);
        // add(jtfNum);
        JPanel jPanel2 = new JPanel();
        questionText.setBounds(350, 120, 200, 30);
        jtfText.setBounds(350, 150, 300, 200);
        add(questionText);
        add(jtfText);
        JPanel jPanel3 = new JPanel();
        questionAnswer.setBounds(350, 370, 200, 30);
        jcbAnswer.setBounds(350, 400, 300, 25);
        add(questionAnswer);
        add(jcbAnswer);
        btnOk.setBounds(400, 450, 75, 30);
        btnCancel.setBounds(500, 450, 75, 30);
        add(btnOk);
        add(btnCancel);
        btnOk.addActionListener(this);
        btnCancel.addActionListener(this);

        this.add(jPanel1, BorderLayout.NORTH);
        this.add(jPanel2, BorderLayout.CENTER);
        this.add(jPanel3, BorderLayout.SOUTH);

        this.setVisible(true);
        this.setSize(1000, 600);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        /*this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);*/
    }

    public static int getQuestionFlag() {
        int questionFlag = 0;
        Connection conn = null;
        PreparedStatement preparedStatement = null;
        ResultSet rsQuery = null;
        ResultSet rs = null;
        try {
            conn = JDBCUtils.getConnection();
            String sqlQuery = "select MAX(num) from test";
            System.out.println("查询当前最大题号:数据库连接成功!");
            preparedStatement = conn.prepareStatement(sqlQuery);
            rsQuery = preparedStatement.executeQuery();
            while (rsQuery.next()) {
                questionFlag = rsQuery.getInt(1);
                questionFlag++;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(rsQuery, preparedStatement, conn);
        }
        return questionFlag;
    }

    /*public boolean isAllNumber (String s) {
        char[] str = s.toCharArray();
        for (char c : str) {
            if (c < '0' || c > '9') {
                return false;
            }
        }
        return true;
    }*/

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        // 添加试题

        if (actionEvent.getSource() == btnOk) {
            /*Test[] addTests = new Test[1];*/
            // String num = jtfNum.getText();
            String text = jtfText.getText();
            String answer = stringAnswer[jcbAnswer.getSelectedIndex()];
            int isEmpty = 0;
            int isSelect = 0;
            // int isLegal = 0;
            /*if ("".equals(num)) {
                JOptionPane.showMessageDialog(null, "请输入题号!");
            } else */
            if ("".equals(text)) {
                JOptionPane.showMessageDialog(null, "请输入题目!");
            } else {
                isEmpty = 1;
            }
            if (jcbAnswer.getSelectedIndex() == 0) {
                JOptionPane.showMessageDialog(null, "请选择答案!");
            } else {
                isSelect = 1;
            }

            /*if (isAllNumber(num)) {
                isLegal = 1;
            } else {
                JOptionPane.showMessageDialog(null, "您输入的题号不规范!");
            }*/

            if (isEmpty == 1 &&/* isLegal == 1 && */ isSelect == 1) {
                // 开始连接数据库传入参数
                Connection conn = null;
                PreparedStatement preparedStatement = null;
                // ResultSet rsQuery = null;
                PreparedStatement pstmt = null;
                ResultSet rs = null;

                /*try {
                    conn = JDBCUtils.getConnection();
                    String sqlQuery = "select MAX(num) from test";
                    System.out.println("查询当前最大题号:数据库连接成功!");
                    preparedStatement = conn.prepareStatement(sqlQuery);
                    rsQuery = preparedStatement.executeQuery();
                    while (rsQuery.next()) {
                        questionFlag = rsQuery.getInt(1);
                        questionFlag++;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    JDBCUtils.close(rsQuery, preparedStatement, conn);
                }*/

                /*if (isExist == 0) {*/
                try {
                    conn = JDBCUtils.getConnection();
                    String sql = "insert into test(num, question, answer) " +
                            "values(?, ?, ?) ";
                    System.out.println("添加题目:数据库连接成功!");
                    pstmt = conn.prepareStatement(sql);
                    pstmt.setInt(1, questionFlag);
                    pstmt.setString(2, text);
                    pstmt.setString(3, answer);
                    int count = 0;
                    count = pstmt.executeUpdate();
                    if (count == 1) {
                        System.out.println("题目添加成功!");
                        JOptionPane.showMessageDialog(null, "题目添加成功!");
                        this.dispose();
                    } else {
                        JOptionPane.showMessageDialog(null, "题目添加失败!");
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    JDBCUtils.close(rs, pstmt, conn);
                }
            } else {
                JOptionPane.showMessageDialog(null, "请输入题目或者选择答案!");
            }

            /*}*/
        } else if (actionEvent.getSource() == btnCancel) {
            this.dispose();
        }
    }
}

教师类:teacher/Teacher.java

package com.company.teacher;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:22
 */
public class Teacher {
    private long teacherId;
    private String teacherName;
    private String teacherSex;
    private int teacherAge;

    public long getTeacherId() {
        return teacherId;
    }

    public void setTeacherId(long teacherId) {
        this.teacherId = teacherId;
    }

    public String getTeacherName() {
        return teacherName;
    }

    public void setTeacherName(String teacherName) {
        this.teacherName = teacherName;
    }

    public String getTeacherSex() {
        return teacherSex;
    }

    public void setTeacherSex(String teacherSex) {
        this.teacherSex = teacherSex;
    }

    public int getTeacherAge() {
        return teacherAge;
    }

    public void setTeacherAge(int teacherAge) {
        this.teacherAge = teacherAge;
    }
}

修改成绩:teacher/UpdateScore.java

package com.company.teacher;

import com.company.utils.JDBCUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:49
 */
public class UpdateScore extends JFrame implements ActionListener {
    JLabel updateId = new JLabel("请输入要修改的学生学号:");
    JLabel updateScore = new JLabel("请输入要修改的成绩:");
    JTextField jtfId = new JTextField(20);
    JTextField jtfScore = new JTextField(20);
    JButton btnOk = new JButton("确认");
    JButton btnCancel = new JButton("取消");

    public UpdateScore () {
        JPanel jPanel = new JPanel();
        updateId.setBounds(350, 50, 200, 30);
        jtfId.setBounds(350, 80, 300, 25);
        updateScore.setBounds(350, 120, 200, 30);
        jtfScore.setBounds(350, 150, 300, 25);
        btnOk.setBounds(400, 400, 75, 30);
        btnCancel.setBounds(500, 400, 75, 30);
        add(updateId);
        add(jtfId);
        add(updateScore);
        add(jtfScore);
        add(btnOk);
        add(btnCancel);

        btnOk.addActionListener(this);
        btnCancel.addActionListener(this);

        this.add(jPanel, BorderLayout.CENTER);
        this.setVisible(true);
        this.setSize(1000, 600);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        /*this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);*/
    }

    public boolean isAllNumber (String s) {
        char[] str = s.toCharArray();
        for (char c : str) {
            if (c < '0' || c > '9') {
                return false;
            }
        }
        return true;
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        if (actionEvent.getSource() == btnOk) {
            // 判断ID以及分数是否合理

            int isEmpty = 0;
            int isLegal = 0;

            String temp = "";
            String tempId = "";
            int tempScore = 0;

            temp = jtfScore.getText();
            tempId = jtfId.getText();

            if ("".equals(tempId)) {
                JOptionPane.showMessageDialog(null, "请输入学号!");
            } else if ("".equals(temp)) {
                JOptionPane.showMessageDialog(null, "请输入分数!");
            } else {
                isEmpty = 1;
            }

            if (isEmpty == 1) {
                if (isAllNumber(tempId)) {
                    char[] id = tempId.toCharArray();
                    if (id.length == 11) {
                        if (isAllNumber(temp)) {
                            tempScore = Integer.parseInt(jtfScore.getText());
                            if (0 <= tempScore && tempScore <= 100) {
                                isLegal = 1;
                            } else {
                                JOptionPane.showMessageDialog(null, "分数在0-100!");
                            }
                        } else {
                            JOptionPane.showMessageDialog(null, "分数应为数字!");
                        }
                    } else {
                        JOptionPane.showMessageDialog(null, "学号为11位!");
                    }
                } else {
                    JOptionPane.showMessageDialog(null, "学号应为数字!");
                }
            }

            if (isEmpty == 1 && isLegal == 1) {
                Connection conn = null;
                PreparedStatement pstmt = null;
                ResultSet rs = null;

                try {
                    conn = JDBCUtils.getConnection();
                    System.out.println("修改分数:数据库连接成功!");
                    String sql = "update sc set score = ? where sc.sno = ?";
                    String sqlQuery = "select sno from sc where sc.sno = ?";
                    pstmt = conn.prepareStatement(sqlQuery);
                    int isExist = 0;
                    pstmt.setString(1, tempId);
                    rs = pstmt.executeQuery();
                    while (rs.next()) {
                        isExist ++;
                    }

                    if (isExist == 1) {
                        pstmt = null;
                        pstmt = conn.prepareStatement(sql);
                        pstmt.setInt(1, tempScore);
                        pstmt.setString(2, tempId);
                        int count = pstmt.executeUpdate();
                        if (count == 1) {
                            System.out.println("修改成功!");
                            JOptionPane.showMessageDialog(null, "修改成功!");
                            this.dispose();
                        } else {
                            System.out.println("修改失败!");
                            JOptionPane.showMessageDialog(null, "修改失败!");
                            this.dispose();
                        }
                    } else {
                        JOptionPane.showMessageDialog(null, "您输入的学号不存在!");
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    JDBCUtils.close(rs, pstmt, conn);
                }
            }
        } else if (actionEvent.getSource() == btnCancel) {
            this.dispose();
        }
    }
}

试卷导入:testpaper/AddPaper.java

package com.company.testpaper;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月11日 22:48
 */
public class AddPaper {
    public static Map<String, String> importTestPaper() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("D:\\Java\\IdeaProjects\\StudentOnlineExaminationSystem\\Test.txt"));
        Map<String, String> testMap = new LinkedHashMap<String, String>();
        StringBuilder stringBuilder = new StringBuilder();
        char[] chars = new char[1024];
        int len;
        while ((len = br.read(chars)) != -1) {
            stringBuilder.append(new String(chars, 0, len));
        }
        br.close();
        String allText = stringBuilder.toString();
        System.out.println(allText);
        stringBuilder.delete(0, stringBuilder.length());
        String[] strings = allText.split("/");
        String[] tests = new String[strings.length];
        String[] answers = new String[strings.length];
        int flag = 0;
        for (String string : strings) {
            // 此处的 string 是每一道题的题目与答案
            String[] split = string.split("正确答案:");
            tests[flag] = split[0];
            answers[flag] = split[1];
            flag++;
        }
        String s = stringBuilder.toString();
        System.out.println(s);
        for (int i = 0; i < flag ; i++) {
            testMap.put(tests[i], answers[i]);
        }
        System.out.println("-------");
        System.out.println(testMap);
        return testMap;
    }
}

倒计时:testpaper/Countdown.java

package com.company.testpaper;

import com.company.view.MainView;

import javax.swing.*;
import java.text.NumberFormat;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:54
 */
public class Countdown extends Thread{
    // 设置考试倒计时
    // 剩余时间
    private JLabel leftTime;
    // 考试设置时间,总时间
    private int totalTime;

    public Countdown(JLabel lT, int tT) {
        this.leftTime = lT;
        this.totalTime = tT * 60;
    }

    @Override
    public void run() {
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置数值的整数部分允许的最小位数
        numberFormat.setMinimumIntegerDigits(2);
        // 定义时分秒
        int h, m, s;
        while (totalTime > 0) {
            h = totalTime / 3600;
            m = totalTime % 3600 / 60;
            s = totalTime % 60;
            StringBuilder stringBuilder;
            stringBuilder = new StringBuilder();
            // 增加到leftTime标签
            stringBuilder.append("考试剩余时间为:").append(numberFormat.format(h)).append(":").append(numberFormat.format(m)).append(":").append(numberFormat.format(s));
            leftTime.setText(stringBuilder.toString());
            System.out.println("lefttime :" + leftTime);
            try {
                //延时一秒
                Thread.sleep(1000);
            } catch (Exception e) {
                // ignore error
            }
            // 单位是s,延时1s则总时长-1
            totalTime --;
        }
        if (totalTime == 0) {
            JOptionPane.showMessageDialog(null, "考试结束");
            // 考试结束的时候自动交卷,触发打分方法
            MainView.showScore();
            // 推迟执行,防止过早关闭
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.exit(0);
        }
    }
}

试题类:testpaper/Test.java

package com.company.testpaper;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:50
 */
public class Test {
    // 提供试题类,包括题目的题号、文本、答案
    private int questionNum;        // 题目题号
    private String questionText;    // 试题内容
    private String standardAnswer;  // 标准答案

    // 学生答案和题号
    private String stuAnswer;

    // 检查答案是否正确
    public boolean checkAnswer() {
        if (this.stuAnswer == null) {
            return false;
        } else {
            return this.stuAnswer.equals(this.standardAnswer);
        }
    }

    public Test() {
    }

    public Test(int questionNum, String questionText, String standardAnswer, String stuAnswer) {
        this.questionNum = questionNum;
        this.questionText = questionText;
        this.standardAnswer = standardAnswer;
        this.stuAnswer = stuAnswer;
    }

    public int getQuestionNum() {
        return questionNum;
    }

    public void setQuestionNum(int questionNum) {
        this.questionNum = questionNum;
    }

    public String getQuestionText() {
        return questionText;
    }

    public void setQuestionText(String questionText) {
        this.questionText = questionText;
    }

    public String getStandardAnswer() {
        return standardAnswer;
    }

    public void setStandardAnswer(String standardAnswer) {
        this.standardAnswer = standardAnswer;
    }

    public String getStuAnswer() {
        return stuAnswer;
    }

    public void setStuAnswer(String stuAnswer) {
        this.stuAnswer = stuAnswer;
    }
}

JDBC工具类:utils/JDBCUtils.java

package com.company.utils;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:34
 */
public class JDBCUtils {
    // 定义字符串
    private static String user;
    private static String password;
    private static String url;
    private static String driver;

    /*
     * 文件的读取,只需要用到一次,所以用到静态代码块
     * */
    static {
        // 读取资源文件,获取值
        try {
            // 1. 创建properties集合类
            Properties properties = new Properties();

            // 获取src路径下文件的方法-> ClassLoader 类加载器
            // ClassLoader classLoader = JDBCUtils.class.getClassLoader();
            // URL res = classLoader.getResource("src\\jdbc.properties");
            // String path = res.getPath();
            // System.out.println(path);

            // 2.加载文件
            properties.load(new FileReader("src\\com\\company\\resources\\jdbc.properties"));

            // 3.获取数值,赋值
            url = properties.getProperty("url");
            user = properties.getProperty("user");
            password = properties.getProperty("password");
            driver = properties.getProperty("driver");

            // 4.注册驱动
            Class.forName(driver);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /*
     * 获取连接,连接对象
     * */
    public static Connection getConnection() throws SQLException {
        System.out.println("数据库连接中......");
        return DriverManager.getConnection(url, user, password);
    }

    /*
     * 释放资源
     * */
    public static void close(PreparedStatement pstmt, Connection conn) {
        if (pstmt != null) {
            try {
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


    public static void close (ResultSet rs, PreparedStatement pstmt, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        close(pstmt, conn);
        System.out.println("资源释放成功!");
    }
}

检验身份:view/CheckIdentity.java

package com.company.view;

import com.company.utils.JDBCUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:38
 */
public class CheckIdentity extends JFrame implements ActionListener {
    /*
     *  输入管理员密码之后,才能够创建教师账号/登录教师账号
     * */
    private JButton btnOk;
    private JButton btnCancel;
    private JPasswordField jpfAdmin;

    private JLabel welcome;
    private JButton back;

    public CheckIdentity() {
        super("学生在线考试系统_验证您的身份");

        welcome = new JLabel("确认您的身份");
        back = new JButton("返回");
        back.addActionListener(this);

        JPanel jPanel = new JPanel();
        jPanel.add(welcome);
        jPanel.add(back);
        this.add(jPanel, BorderLayout.NORTH);

        JPanel jPanel1 = new JPanel();
        JLabel jNotification = new JLabel("请输入您的身份验证密码:");
        jNotification.setBounds(400, 200, 230, 25);
        jpfAdmin = new JPasswordField();
        jpfAdmin.setBounds(400, 230, 200, 25);
        add(jNotification);
        add(jpfAdmin);

        JPanel jPanel2 = new JPanel();
        btnOk = new JButton("确认");
        btnCancel = new JButton("取消");
        btnOk.setBounds(430, 290, 60, 30);
        btnCancel.setBounds(500, 290, 60, 30);
        add(btnOk);
        add(btnCancel);

        btnOk.addActionListener(this);
        btnCancel.addActionListener(this);

        Container con = this.getContentPane();
        con.add(jPanel1, BorderLayout.CENTER);
        con.add(jPanel2, BorderLayout.CENTER);

        // 设置属性值
        this.setSize(1000, 600);
        // 设置用户不可调节窗口大小
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    }

    public static void main(String[] args) {
        new CheckIdentity();
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        if (actionEvent.getSource() == btnOk) {
            // 确认验证
            String password = "";

            Connection conn = null;
            PreparedStatement pstmt = null;
            ResultSet rs = null;

            try {
                conn = JDBCUtils.getConnection();
                System.out.println("验证教师:数据库连接成功!");
                String sql = "select * from administrator";
                pstmt = conn.prepareStatement(sql);
                rs = pstmt.executeQuery();
                while (rs.next()) {
                    password = rs.getString(1);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JDBCUtils.close(rs, pstmt, conn);
            }
            if (password.equals(new String(jpfAdmin.getPassword()))) {
                // 密码正确
                JOptionPane.showMessageDialog(null, "密码正确!");
                this.dispose();
                new TeacherSelect();
            }
        } else if (actionEvent.getSource() == btnCancel) {
            // 取消、返回则跳转回上一级页面
            new SelectIdentity();
            this.dispose();
        } else if (actionEvent.getSource() == back) {
            new SelectIdentity();
            this.dispose();
        }
    }
}

答题主页面:view/MainView.java

package com.company.view;

import com.company.testpaper.Countdown;
import com.company.testpaper.Test;
import com.company.utils.JDBCUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:36
 */
public class MainView extends JFrame implements ActionListener {
    // 定义主界面
    // 定义按钮:提交、上一题、下一题、开始
    private JButton start, commit, back, next;
    // 设置单选按钮
    private JRadioButton aButton, bButton, cButton, dButton;
    // 设置按钮组
    private ButtonGroup buttonGroup;
    // 设置文本区
    private static JTextArea jTextArea;

    // 定义所需要的变量值
    private static Test[] tests;              // 设置试题
    private static int questionNum = 0;       // 设置题目数量
    private static int questionPointer = 0;   // 设置题号指针
    private static int yes = 0;
    private static int no = 0;               // 设置对错数量
    private Countdown cd;              // 倒计时

    MainView() {
        super("学生在线考试系统_答题");

        // 设置面板
        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();
        JPanel panel3 = new JPanel();

        // 设定考试时间
        final int EXAM_TIME = 1;
        // 设置标签
        JLabel label = new JLabel("总考试时间:" + 1 + "分钟");
        JLabel clock = new JLabel();
        cd = new Countdown(clock, EXAM_TIME);

        jTextArea = new JTextArea(20, 40);
        // 设置试题区不能编辑(不能修改试题内容)
        jTextArea.setEditable(false);

        aButton = new JRadioButton("A");
        bButton = new JRadioButton("B");
        cButton = new JRadioButton("C");
        dButton = new JRadioButton("D");
        buttonGroup = new ButtonGroup();

        start = new JButton("开始考试");
        back = new JButton("上一题");
        next = new JButton("下一题");
        commit = new JButton("交卷");

        // 添加事件监听
        aButton.addActionListener(this);
        bButton.addActionListener(this);
        cButton.addActionListener(this);
        dButton.addActionListener(this);

        start.addActionListener(this);
        back.addActionListener(this);
        next.addActionListener(this);
        commit.addActionListener(this);

        // 布局设置
        buttonGroup.add(aButton);
        buttonGroup.add(bButton);
        buttonGroup.add(cButton);
        buttonGroup.add(dButton);

        panel1.add(label);
        panel1.add(start);
        panel1.add(clock);


        panel2.add(jTextArea);

        panel3.add(aButton);
        panel3.add(bButton);
        panel3.add(cButton);
        panel3.add(dButton);
        panel3.add(back);
        panel3.add(next);
        panel3.add(commit);

        this.add(panel1, BorderLayout.NORTH);
        this.add(panel2, BorderLayout.CENTER);
        this.add(panel3, BorderLayout.SOUTH);

        // 登录之后界面才可见
        this.setVisible(true);
        this.setTitle("学生在线考试系统");
        // 设置全屏显示
        /*
         * 后来发现全屏显示需要调整UI,舍弃使用
         * */
        /*Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        this.setSize((int) screenSize.getWidth(), (int) screenSize.getHeight());*/
        // 设置尺寸
        this.setSize(1000, 600);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private void createExam() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;

        try {
            // 题目数量
            int num = 0;
            conn = JDBCUtils.getConnection();
            System.out.println("获取题库:数据库连接成功!");
            String sql = "select * from TEST";
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                num ++;
            }
            /*
             * 考虑到教师未添加题目的情况
             *  num == 0
             * */
            if (num == 0) {
                JOptionPane.showMessageDialog(null, "题库为空,请联系教师解决!");
                this.dispose();
                new StudentLogin();
            }
            tests = new Test[num];
            // 题目数量赋值
            questionNum = num;
            /*
             * 出现空指针异常
             * Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
             * 出现异常的原因是因为自定义的类数组,需要对每个类进行实例化
             * Test[] tests = new Test[num] 是没有地方可以存数据的
             * 只有每个成员进行声明后才会给这个成员分配内存
             * tests[0] = new Test();
             * */
            // 获取题量的大小之后,需要对rs重新赋值
            rs = null;
            rs = pstmt.executeQuery();
            int i = 0;
            while (rs.next()) {
                tests[i] = new Test();
                tests[i].setQuestionNum(rs.getInt("NUM"));
                tests[i].setQuestionText(rs.getString("QUESTION"));
                tests[i].setStandardAnswer(rs.getString("ANSWER"));
                i ++;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(rs, pstmt, conn);
        }
    }

    // 设置单选不重复模块
    private void setSelected(String s) {
        if ("A".equals(s)) {
            buttonGroup.setSelected(aButton.getModel(), true);
        }
        if ("B".equals(s)) {
            buttonGroup.setSelected(bButton.getModel(), true);
        }
        if ("C".equals(s)) {
            buttonGroup.setSelected(cButton.getModel(), true);
        }
        if ("D".equals(s)) {
            buttonGroup.setSelected(dButton.getModel(), true);
        }
        if ("".equals(s)) {
            buttonGroup.clearSelection();
        }
    }

    // 设置试题展示模块
    public static void showQuestion() {
        jTextArea.setText("");
        jTextArea.append(tests[questionPointer].getQuestionText());
    }

    // 设置打分模块
    public static void showScore() {
        for (int i = 0; i < questionNum; i++) {
            if (tests[i].checkAnswer()) {
                yes++;
            } else {
                no++;
            }
        }
        int score  = (int) (yes * 100 / questionNum);
        // 把学生成绩传回数据库
        // 用到之前登录时候定义的 stuId
        // 答题则表示登录成功,输入Id正确
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = JDBCUtils.getConnection();
            System.out.println("传入成绩:数据库连接成功!");
            String sql = "update sc set score = ? where sno = ?";
            pstmt = conn.prepareStatement(sql);

            // 设置占位符值
            pstmt.setInt(1, score);
            pstmt.setString(2, StudentLogin.getStuId());

            System.out.println("登录的学号是" + StudentLogin.getStuId());

            int count  = pstmt.executeUpdate();
            System.out.println("改变了" + count + "次成绩");
        } catch (SQLException e) {
            e.printStackTrace();
        } /*finally {
            JDBCUtils.close(null, pstmt, conn);
        }*/
        JOptionPane.showMessageDialog(null,
                "答对" + yes + "题,答错"+ no +"题,分数为" + score);

        // 展示学生信息,打分
        conn = null;
        pstmt = null;
        ResultSet rs = null;
        String sname = "";
        String sid = "";
        int sscore = 0;
        try {
            conn = JDBCUtils.getConnection();
            System.out.println("分数查询:数据库连接成功!");
            String sql = "select student.sno, student.sname, sc.score " +
                    "from sc, student where sc.sno = student.sno and sc.sno = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, StudentLogin.getStuId());
            rs = pstmt.executeQuery();
            while (rs.next()) {
                System.out.println("展示成绩");
                sname = rs.getString("sname");
                sid = rs.getString("sno");
                sscore = rs.getInt("score");
            }
            JOptionPane.showMessageDialog(null,
                    "姓名:" + sname + '\n' + "学号:" + sid + '\n' + "分数:" + sscore);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(rs, pstmt, conn);
        }

    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        // 按键点击
        if (actionEvent.getSource() == start) {
            createExam();         // 创建考试
            questionPointer = 0;  // 题目序号
            showQuestion();       // 展示试题
            start.setEnabled(false);  // 设置按键不可点击
            cd.start();           // 开始计时
        } else if (actionEvent.getSource() == back) {
            questionPointer --;
            if (questionPointer == -1) {
                JOptionPane.showMessageDialog(null, "已经是第一题了!");
                questionPointer ++;
            } else {
                // 当前题目未完成,需要清空选项值
                setSelected(Objects.requireNonNullElse(tests[questionPointer].getStuAnswer(), ""));
            }
            showQuestion();
        } else if (actionEvent.getSource() == next) {
            questionPointer ++;
            if (questionPointer == questionNum) {
                JOptionPane.showMessageDialog(null, "已经是最后一题了!");
                questionPointer --;
            } else {
                // 当前题目未完成,需要清空选项值
                setSelected(Objects.requireNonNullElse(tests[questionPointer].getStuAnswer(), ""));
            }
            showQuestion();
        } else if (actionEvent.getSource() == commit) {
            showScore();
            commit.setEnabled(false);
            System.exit(0);
        }

        // 设置答案选项
        if (actionEvent.getSource() == aButton) {
            tests[questionPointer].setStuAnswer("A");
        }
        if (actionEvent.getSource() == bButton) {
            tests[questionPointer].setStuAnswer("B");
        }
        if (actionEvent.getSource() == cButton) {
            tests[questionPointer].setStuAnswer("C");
        }
        if (actionEvent.getSource() == dButton) {
            tests[questionPointer].setStuAnswer("D");
        }
    }

    public static void main(String[] args) {
        new MainView();
    }

}

选择身份:view/SelectIdentity.java

package com.company.view;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:37
 */
public class SelectIdentity extends JFrame implements ActionListener {
    // 提供用户身份选择
    /*
     * 按照用户分类,分为教师和学生
     * 教师能够添加试题,查询、修改学生成绩
     * 学生能够新建自己的个人信息,设置密码以及修改密码,查询成绩
     * 实现逻辑:
     * 一级界面提供身份选择,二级界面选择登录还是注册,之后根据权限判断,判断身份
     * 1. 如果是教师注册,需要输入管理员密码
     *   - 如果密码不对,不给予注册教师身份
     *   - 如果身份正确,给与注册进入下一步
     * 2. 如果是学生注册,不需要进行判断
     * */
    private JButton jIdentityTeacher;            // 身份选择,教师
    private JButton jIdentityStudent;            // 身份选择,学生
    JFrame jFrame = new JFrame();

    public SelectIdentity () {
        super("学生在线考试系统_确认您的身份");

        JPanel jPanel1 = new JPanel();
        JLabel jNotification = new JLabel("请选择您的身份:");
        jNotification.setBounds(430, 240, 200, 25);
        add(jNotification);

        JPanel jPanel2 = new JPanel();
        jIdentityTeacher = new JButton("教师");
        jIdentityStudent = new JButton("学生");
        jIdentityTeacher.setBounds(430, 270, 60, 30);
        jIdentityStudent.setBounds(500, 270, 60, 30);
        add(jIdentityTeacher);
        add(jIdentityStudent);

        jIdentityTeacher.addActionListener(this);
        jIdentityStudent.addActionListener(this);


        Container con = this.getContentPane();
        con.add(jPanel1, BorderLayout.NORTH);
        con.add(jPanel2, BorderLayout.CENTER);
        con.setLocation(400, 200);

        this.setVisible(true);
        this.setSize(1000, 600);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        /*try {
            JFrame.setDefaultLookAndFeelDecorated(true);
            UIManager.setLookAndFeel("com.jtattoo.plaf.hifi.HiFiLookAndFeel");
            new CheckIdentity();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }*/
        new SelectIdentity();
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        if (actionEvent.getSource() == jIdentityTeacher) {
            /*
             * 假设是教师,需要输入管理员密码确认
             * 密码输入错误跳回选择界面
             * */
            this.dispose();
            new CheckIdentity();
        } else if (actionEvent.getSource() == jIdentityStudent) {
            // 跳转学生界面
            this.dispose();
            new StudentSelect();
        }
    }
}

学生登录:view/StudentLogin.java

package com.company.view;

import com.company.utils.JDBCUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 16:01
 */
public class StudentLogin extends JFrame implements ActionListener {
    // 定义文本域接收用户名
    private JTextField jtfId;
    // 定义密码域接收密码
    private JPasswordField jpfPassword;
    // 定义按钮,确认、取消
    private JButton btnOk;
    private JButton btnCancel;

    private static String stuId = "";              // 学号

    public static String getStuId() {
        return stuId;
    }

    public void setStuId(String stuId) {
        this.stuId = stuId;
    }

    private String stuPassword = "";        // 密码

    private JLabel welcome;
    private JButton back;

    public StudentLogin() {
        super("学生在线考试系统_登录");

        welcome = new JLabel("学生登录界面");
        back = new JButton("返回");
        back.addActionListener(this);

        JPanel jPanel = new JPanel();
        jPanel.add(welcome);
        jPanel.add(back);
        this.add(jPanel, BorderLayout.NORTH);

        // 学号密码输入部分
        // 定义界面
        JPanel jpMain = new JPanel();
        // 定义标签
        JLabel lblId = new JLabel("学号:");
        JLabel lblPassword = new JLabel("密码:");
        jtfId = new JTextField(20);
        jpfPassword = new JPasswordField(20);
        lblId.setBounds(350, 200, 50, 30);
        jtfId.setBounds(400, 205, 200, 25);
        lblPassword.setBounds(350, 240, 50, 30);
        jpfPassword.setBounds(400, 245, 200, 25);
        add(lblId);
        add(jtfId);
        add(lblPassword);
        add(jpfPassword);

        // 登录确认取消部分
        JPanel jpBtn = new JPanel();
        btnOk = new JButton("确认");
        btnCancel = new JButton("取消");
        btnOk.setBounds(430, 290, 60, 30);
        add(btnOk);
        btnCancel.setBounds(500, 290, 60, 30);
        add(btnCancel);

        // 添加事件监听
        btnOk.addActionListener(this);
        btnCancel.addActionListener(this);

        // 添加容器
        Container con = this.getContentPane();
        con.add(jpMain, BorderLayout.CENTER);
        con.add(jpBtn, BorderLayout.CENTER);

        // 设置属性值
        this.setSize(1000, 600);
        // 设置用户不可调节窗口大小
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
        this.setTitle("学生在线考试系统_登录");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        /*
         * 登录功能逻辑:
         *  1. 先获取到学号
         *  2. 利用学号检索数据库,看是否查询得到对应的密码
         *    - 有查询结果,则代表学号正确
         *    - 无查询结果,则代表学号错误/没添加
         *  3. 有对应的密码之后,判断数据库的密码和用户输入的密码是否匹配
         *    - 若匹配,则密码正确
         *    - 若不匹配,则密码错误
         * */
        // 设置用户输入临时储存
        // 设置正确学号密码的匹配值
        String stuPassword = "";

        // 设置用户输入的存储值
        String tempId = "";
        String tempPassword = "";

        int temp = 0;

        if (actionEvent.getSource() == btnOk) {
            if ("".equals(jtfId.getText())) {
                // System.out.println("请输入学号!");
                JOptionPane.showMessageDialog(null, "请输入学号!");
            } else if ("".equals(new String(jpfPassword.getPassword()))) {
                // System.out.println("请输入密码!");
                JOptionPane.showMessageDialog(null, "请输入密码!");
            } else {
                temp = 1;
                tempId = jtfId.getText();
                tempPassword = new String(jpfPassword.getPassword());
            }

            if (temp == 1) {
                // 执行JDBC查询到学生的ID和密码
                Connection conn = null;
                PreparedStatement pstmt = null;
                ResultSet rs = null;
                try {
                    conn = JDBCUtils.getConnection();
                    // JOptionPane.showMessageDialog(null, "数据库连接成功!");
                    System.out.println("登录:数据库连接成功!");
                    String sql = "select password from student where sno = ?";
                    pstmt = conn.prepareStatement(sql);
                    pstmt.setString(1, tempId);
                    rs = pstmt.executeQuery();
                    while (rs.next()) {
                        stuPassword = rs.getString(1);
                    }
                    // 如果学号输入错误/找不到对应的学号,则返回的rs为null,getString也为null
                    if (tempPassword.equals(stuPassword)) {
                        JOptionPane.showMessageDialog(null, "登录成功!");
                        // 学号正确,填入学号,后期更新成绩需要用到
                        /*setStuId(tempId);*/
                        stuId = tempId;
                        // 执行页面跳转
                        this.dispose(); // 关闭登录界面
                        new MainView(); // 弹出主页面
                    } else {
                        JOptionPane.showMessageDialog(null, "学号或密码错误!");
                        jtfId.setText("");
                        jpfPassword.setText("");
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    // 释放资源
                    JDBCUtils.close(rs, pstmt, conn);
                }
            }
        }

        // 取消登录操作
        if (actionEvent.getSource() == btnCancel) {
            /*JOptionPane.showMessageDialog(null, "您已退出!");*/
            this.dispose();
            new StudentSelect();
        } else if (actionEvent.getSource() == back) {
            this.dispose();
            new StudentSelect();
        }
    }

    public static void main(String[] args) {
        new StudentLogin();
    }

}

学生注册:view/StudentRegister.java

package com.company.view;

import com.company.utils.JDBCUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 16:02
 */
public class StudentRegister extends JFrame implements ActionListener {
    // 提供用户注册界面

    private JLabel stuName;
    private JLabel stuId;
    private JLabel stuPassword;
    private JLabel stuSex;
    private JLabel stuAge;
    private JLabel stuDepartment;   // 学院
    private JLabel stuMajor;        // 专业

    private JLabel idTip;
    private JLabel passwordTip;
    private JLabel ageTip;

    private JTextField jtfName;
    private JTextField jtfId;
    private JPasswordField jpfPassword;
    private JComboBox jcbSex;
    private JComboBox jcbDepartment;
    private JComboBox jcbAge;
    private JComboBox jcbMajor;

    private JButton btnOk;
    private JButton btnCancel;

    private JLabel welcome;
    private JButton back;


    // 范围选择
    String[] stringAge = new String[] {"-请选择-", "10", "11", "12", "13", "14", "15", "16",
            "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27",
            "28", "29", "30", "31", "32", "33", "34", "35"};
    String[] stringMajor = new String[] {"-请选择-", "计算机科学与技术", "软件工程", "物联网", "网络工程"};
    String[] stringDepartment = new String[] {"-请选择-", "计算机学院"};
    String[] stringSex = new String[] {"-请选择-", "男", "女"};

    public StudentRegister () {
        super("学生在线考试系统_学生注册");

        welcome = new JLabel("学生注册界面");
        back = new JButton("返回");
        back.addActionListener(this);

        stuName = new JLabel("姓名:");
        jtfName = new JTextField(20);
        stuId = new JLabel("学号:");
        jtfId = new JTextField(20);
        stuPassword = new JLabel("密码:");
        jpfPassword = new JPasswordField(20);
        stuSex = new JLabel("性别:");
        stuAge = new JLabel("年龄:");
        stuDepartment = new JLabel("学院:");
        stuMajor = new JLabel("专业:");

        idTip = new JLabel("(学号为11位的整数)");
        passwordTip = new JLabel("(密码不得少于6位)");
        ageTip = new JLabel("(年龄范围:10-35)");

        btnOk = new JButton("确认");
        btnCancel = new JButton("取消");

        btnOk.addActionListener(this);
        btnCancel.addActionListener(this);

        JPanel jPanel = new JPanel();
        /*welcome.setBounds(430, 20, 200, 30);
        welcome.setFont(new Font("黑体", Font.PLAIN, 16));
        back.setBounds(440, 50, 80, 25);*/
        jPanel.add(welcome);
        jPanel.add(back);
        jcbSex = new JComboBox(stringSex);
        jcbDepartment = new JComboBox(stringDepartment);
        jcbAge = new JComboBox(stringAge);
        jcbMajor = new JComboBox(stringMajor);

        JPanel jPanel1 = new JPanel();
        stuName.setBounds(350, 100, 50, 30);
        jtfName.setBounds(400, 105, 200, 25);
        stuId.setBounds(350, 140, 50, 30);
        jtfId.setBounds(400, 145, 200, 25);
        idTip.setBounds(620, 140, 200, 30);
        stuPassword.setBounds(350, 180, 50, 30);
        jpfPassword.setBounds(400, 185, 200, 25);
        passwordTip.setBounds(620, 180, 200, 30);
        stuSex.setBounds(350, 220, 50, 30);
        jcbSex.setBounds(400, 225, 200, 25);
        stuAge.setBounds(350, 260, 50, 30);
        jcbAge.setBounds(400, 265, 200, 25);
        ageTip.setBounds(620, 260, 200, 30);
        stuDepartment.setBounds(350, 300, 50, 30);
        jcbDepartment.setBounds(400, 305, 200, 25);
        stuMajor.setBounds(350, 340, 50, 30);
        jcbMajor.setBounds(400, 345, 200, 25);
        add(stuName);
        add(jtfName);
        add(stuId);
        add(jtfId);
        add(idTip);
        add(stuPassword);
        add(jpfPassword);
        add(passwordTip);
        add(stuSex);
        add(jcbSex);
        add(stuAge);
        add(jcbAge);
        add(ageTip);
        add(stuDepartment);
        add(jcbDepartment);
        add(stuMajor);
        add(jcbMajor);
        JPanel jPanel2 = new JPanel();
        btnOk.setBounds(430, 470, 60, 30);
        btnCancel.setBounds(500, 470, 60, 30);
        add(btnOk);
        add(btnCancel);

        this.add(jPanel, BorderLayout.NORTH);
        this.add(jPanel1, BorderLayout.CENTER);
        this.add(jPanel2, BorderLayout.SOUTH);

        this.setVisible(true);
        this.setSize(1000, 600);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }


    public boolean isAllNumber (String s) {
        char[] str = s.toCharArray();
        for (char c : str) {
            if (c < '0' || c > '9') {
                return false;
            }
        }
        return true;
    }


    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        if (actionEvent.getSource() == back) {
            this.dispose();
            new StudentSelect();
        } else if (actionEvent.getSource() == btnOk) {
            String tempName = jtfName.getText();
            // 无输入的时候为""
            System.out.println(tempName);
            String tempId = jtfId.getText();
            String tempPassword = new String(jpfPassword.getPassword());
            String tempAge = "";
            String tempSex = "";
            String tempMajor = "";
            String tempDepartment = "";

            int isEmpty = 0;
            int isLegal = 0;
            int isSelect = 0;

            if ("".equals(tempName)) {
                JOptionPane.showMessageDialog(null, "请输入姓名!");
            } else if ("".equals(tempId)) {
                JOptionPane.showMessageDialog(null, "请输入学号!");
            } else if ("".equals(tempPassword)) {
                JOptionPane.showMessageDialog(null, "请输入密码!");
            } else {
                // 表示要填写的元素全部都有填写
                isEmpty = 1;
            }

            if (isEmpty == 1) {
                if (isAllNumber(tempId)){
                    char[] strId = tempId.toCharArray();
                    if (strId.length == 11) {
                        char[] strPassword = tempPassword.toCharArray();
                        if (strPassword.length >= 6) {
                            isLegal = 1;
                        } else {
                            JOptionPane.showMessageDialog(null, "密码不满足条件!");
                        }
                    } else {
                        JOptionPane.showMessageDialog(null, "学号不是11位!");
                        jtfId.setText("");
                    }
                } else {
                    JOptionPane.showMessageDialog(null, "学号不是数字!");
                    jtfId.setText("");
                }
            }

            if (isEmpty == 1 && isLegal == 1) {
                if (jcbSex.getSelectedIndex() != 0) {
                    tempSex = stringSex[jcbSex.getSelectedIndex()];
                    if (jcbAge.getSelectedIndex() != 0) {
                        tempAge = stringAge[jcbAge.getSelectedIndex()];
                        if (jcbDepartment.getSelectedIndex() != 0) {
                            tempDepartment = stringDepartment[jcbDepartment.getSelectedIndex()];
                            if (jcbMajor.getSelectedIndex() != 0) {
                                tempMajor = stringMajor[jcbMajor.getSelectedIndex()];
                                isSelect = 1; // 表示列表项全都做出了选择
                            } else {
                                JOptionPane.showMessageDialog(null, "请选择专业!");
                            }
                        } else {
                            JOptionPane.showMessageDialog(null, "请选择学院!");
                        }
                    } else {
                        JOptionPane.showMessageDialog(null, "请选择年龄!");
                    }
                } else {
                    JOptionPane.showMessageDialog(null, "请选择性别!");
                }
            }

            // 非空才开始传入数据
            if (isEmpty == 1  && isLegal == 1 && isSelect == 1) {
                // 确认注册,需要传入数据
                Connection conn = null;
                PreparedStatement pstmt = null;
                ResultSet rs = null;
                // JDBC数据操作
                try {
                    conn = JDBCUtils.getConnection();
                    System.out.println("学生注册:数据库连接成功!");

                    // 先根据传入的数据是否存在,判断条件:主键Id
                    String selectId = "select sno from student where sno = ?";
                    pstmt = conn.prepareStatement(selectId);
                    pstmt.setString(1, tempId);
                    rs = pstmt.executeQuery();
                    int tempJudge = 0;
                    while (rs.next()) {
                        tempJudge ++;
                    }
                    if (tempJudge == 1) {
                        JOptionPane.showMessageDialog(null, "用户已存在!");
                    } else {
                        pstmt = null;
                        rs = null;
                        String sql = "insert into student(sname, sno, password, ssex," +
                                "sage, major, department) values(?, ?, ?, ?, ?, ?, ?)";
                        /*String sql2 = "insert into sc(sno) values(?)";*/
                        pstmt = conn.prepareStatement(sql);
                        pstmt.setString(1, tempName);
                        pstmt.setString(2, tempId);
                        pstmt.setString(3, tempPassword);
                        pstmt.setString(4, tempSex);
                        pstmt.setString(5, tempAge);
                        pstmt.setString(6, tempMajor);
                        pstmt.setString(7, tempDepartment);

                        // 返回影响的行数
                        int flag = pstmt.executeUpdate();

                        if (flag == 1) {
                            System.out.println("注册成功");
                            rs = null;
                            pstmt = null;
                            String sqlInert = "insert into sc(sno, score) values(?, ?) ";
                            pstmt = conn.prepareStatement(sqlInert);
                            pstmt.setString(1, tempId);
                            pstmt.setInt(2, 0);
                            int count = pstmt.executeUpdate();
                            if (count == 1) {
                                System.out.println("SC表格数据创建成功!");
                                JOptionPane.showMessageDialog(null, "注册成功!");
                            }
                            this.dispose();
                            new StudentLogin();
                        } else {
                            System.out.println("注册失败");
                            JOptionPane.showMessageDialog(null, "注册失败!");
                        }
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    JDBCUtils.close(rs, pstmt, conn);
                }
            }
        } else if (actionEvent.getSource() == btnCancel) {
            // 取消注册,返回上一级
            this.dispose();
            new StudentSelect();
        }
    }


    public static void main(String[] args) {
        new StudentRegister();
    }

}

学生操作选择:view/StudentSelect.java

package com.company.view;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 16:02
 */
public class StudentSelect extends JFrame implements ActionListener {
    /*
     * 提供学生入口选择,注册还是登录
     * 根据相应的选择,跳转不同的界面
     * */
    private JButton jRegister;            // 身份选择,教师
    private JButton jLogin;            // 身份选择,学生

    private JLabel welcome;
    private JButton back;

    StudentSelect() {
        super("学生在线考试系统_学生注册/登录");

        welcome = new JLabel("请选择您的操作");
        back = new JButton("返回");
        back.addActionListener(this);

        JPanel jPanel = new JPanel();
        jPanel.add(welcome);
        jPanel.add(back);
        this.add(jPanel, BorderLayout.NORTH);

        JPanel jPanel1 = new JPanel();
        JLabel jNotification = new JLabel("请选择:");
        jNotification.setBounds(430, 230, 200, 25);
        add(jNotification);
        jRegister = new JButton("注册");
        jLogin = new JButton("登录");
        jRegister.setBounds(430, 260, 60, 30);
        jLogin.setBounds(500, 260, 60, 30);
        add(jRegister);
        add(jLogin);

        jRegister.addActionListener(this);
        jLogin.addActionListener(this);


        Container con = this.getContentPane();
        con.add(jPanel1, BorderLayout.CENTER);
        con.setLocation(400, 200);

        this.setVisible(true);
        this.setSize(1000, 600);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        new StudentSelect();
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        if (actionEvent.getSource() == jRegister) {
            // 选择注册之后
            this.dispose();
            new StudentRegister();
        } else if (actionEvent.getSource() == jLogin) {
            // 选择登录之后进入登录界面
            this.dispose();
            new StudentLogin();
        } else if (actionEvent.getSource() == back) {
            this.dispose();
            new SelectIdentity();
        }
    }
}

教师登录:view/TeacherLogin.java

package com.company.view;

import com.company.utils.JDBCUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:43
 */
public class TeacherLogin extends JFrame implements ActionListener {
    // 定义文本域接收用户名
    private JTextField jtfId;
    // 定义密码域接收密码
    private JPasswordField jpfPassword;
    // 定义按钮,确认、取消
    private JButton btnOk;
    private JButton btnCancel;

    static String teacherId = "";   // 传值给TeacherView使用

    private static String tId = "";              // 工号

    private String tPassword = "";        // 密码

    private JLabel welcome;
    private JButton back;

    public TeacherLogin() {
        super("学生在线考试系统_教师登录");

        welcome = new JLabel("教师注册界面");
        back = new JButton("返回");
        back.addActionListener(this);

        JPanel jPanel = new JPanel();
        jPanel.add(welcome);
        jPanel.add(back);
        this.add(jPanel, BorderLayout.NORTH);

        // 工号密码输入部分
        // 定义界面
        JPanel jpMain = new JPanel();
        // 定义标签
        JLabel lblId = new JLabel("工号:");
        JLabel lblPassword = new JLabel("密码:");
        jtfId = new JTextField(20);
        jpfPassword = new JPasswordField(20);
        lblId.setBounds(350, 200, 50, 30);
        jtfId.setBounds(400, 205, 200, 25);
        lblPassword.setBounds(350, 240, 50, 30);
        jpfPassword.setBounds(400, 245, 200, 25);
        add(lblId);
        add(jtfId);
        add(lblPassword);
        add(jpfPassword);

        // 登录确认取消部分
        JPanel jpBtn = new JPanel();
        btnOk = new JButton("确认");
        btnCancel = new JButton("取消");
        btnOk.setBounds(430, 290, 60, 30);
        add(btnOk);
        btnCancel.setBounds(500, 290, 60, 30);
        add(btnCancel);

        // 添加事件监听
        btnOk.addActionListener(this);
        btnCancel.addActionListener(this);

        // 添加容器
        Container con = this.getContentPane();
        con.add(jpMain, BorderLayout.CENTER);
        con.add(jpBtn, BorderLayout.CENTER);

        // 设置属性值
        this.setSize(1000, 600);
        // 设置用户不可调节窗口大小
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
        this.setTitle("学生在线考试系统_教师登录");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        /*
         * 登录功能逻辑:
         *  1. 先获取到工号
         *  2. 利用工号检索数据库,看是否查询得到对应的密码
         *    - 有查询结果,则代表工号正确
         *    - 无查询结果,则代表工号错误/没添加
         *  3. 有对应的密码之后,判断数据库的密码和用户输入的密码是否匹配
         *    - 若匹配,则密码正确
         *    - 若不匹配,则密码错误
         * */
        // 设置用户输入临时储存
        // 设置正确工号密码的匹配值

        // 设置用户输入的存储值
        String tempId = "";
        String tempPassword = "";

        int temp = 0;

        if (actionEvent.getSource() == btnOk) {
            if ("".equals(jtfId.getText())) {
                // System.out.println("请输入工号!");
                JOptionPane.showMessageDialog(null, "请输入工号!");
            } else if ("".equals(new String(jpfPassword.getPassword()))) {
                // System.out.println("请输入密码!");
                JOptionPane.showMessageDialog(null, "请输入密码!");
            } else {
                temp = 1;
                tempId = jtfId.getText();
                tempPassword = new String(jpfPassword.getPassword());
            }

            if (temp == 1) {
                // 执行JDBC查询到教师的ID和密码
                Connection conn = null;
                PreparedStatement pstmt = null;
                ResultSet rs = null;
                try {
                    conn = JDBCUtils.getConnection();
                    // JOptionPane.showMessageDialog(null, "数据库连接成功!");
                    System.out.println("教师登录:数据库连接成功!");
                    String sql = "select password from teacher where tno = ?";
                    pstmt = conn.prepareStatement(sql);
                    pstmt.setString(1, tempId);
                    rs = pstmt.executeQuery();
                    while (rs.next()) {
                        tPassword = rs.getString(1);
                    }
                    // 如果工号输入错误/找不到对应的工号,则返回的rs为null,getString也为null
                    if (tempPassword.equals(tPassword)) {
                        teacherId = tempId;
                        JOptionPane.showMessageDialog(null, "登录成功!");
                        // 执行页面跳转
                        this.dispose(); // 关闭登录界面
                        new TeacherView(); // 弹出主页面
                    } else {
                        JOptionPane.showMessageDialog(null, "工号或密码错误!");
                        jtfId.setText("");
                        jpfPassword.setText("");
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    // 释放资源
                    JDBCUtils.close(rs, pstmt, conn);
                }
            }
        }

        // 取消登录操作
        if (actionEvent.getSource() == btnCancel) {
            JOptionPane.showMessageDialog(null, "您已退出!");
            new TeacherSelect();
            this.dispose();
        } else if (actionEvent.getSource() == back) {
            new TeacherSelect();
            this.dispose();
        }
    }

    public static void main(String[] args) {
        new TeacherLogin();
    }

}

教师注册:view/TeacherRegister.java

package com.company.view;

import com.company.utils.JDBCUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:52
 */
public class TeacherRegister extends JFrame implements ActionListener {
    // 提供用户注册界面

    private JLabel tName;
    private JLabel tId;
    private JLabel tPassword;
    private JLabel tSex;

    private JLabel idTip;
    private JLabel passwordTip;

    private JTextField jtfName;
    private JTextField jtfId;
    private JPasswordField jpfPassword;
    private JComboBox jcbSex;

    private JButton btnOk;
    private JButton btnCancel;

    private JLabel welcome;
    private JButton back;

    // 范围选择
    String[] stringSex = new String[] {"-请选择-", "男", "女"};

    public TeacherRegister () {
        super("学生在线考试系统_教师注册");

        welcome = new JLabel("教师注册界面");
        back = new JButton("返回");
        back.addActionListener(this);

        tName = new JLabel("姓名:");
        jtfName = new JTextField(20);
        tId = new JLabel("工号:");
        jtfId = new JTextField(20);
        tPassword = new JLabel("密码:");
        jpfPassword = new JPasswordField(20);
        tSex = new JLabel("性别:");
        jcbSex = new JComboBox(stringSex);

        idTip = new JLabel("(工号为11位的整数)");
        passwordTip = new JLabel("(密码不得少于6位)");

        btnOk = new JButton("确认");
        btnCancel = new JButton("取消");

        btnOk.addActionListener(this);
        btnCancel.addActionListener(this);

        JPanel jPanel = new JPanel();
        jPanel.add(welcome);
        jPanel.add(back);
        JPanel jPanel1 = new JPanel();
        tName.setBounds(350, 150, 50, 30);
        jtfName.setBounds(400, 155, 200, 25);
        tId.setBounds(350, 190, 50, 30);
        jtfId.setBounds(400, 195, 200, 25);
        idTip.setBounds(620, 190, 200, 30);
        tPassword.setBounds(350, 230, 50, 30);
        jpfPassword.setBounds(400, 235, 200, 25);
        passwordTip.setBounds(620, 230, 200, 30);
        tSex.setBounds(350, 270, 50, 30);
        jcbSex.setBounds(400, 275, 200, 25);
        add(tName);
        add(jtfName);
        add(tId);
        add(jtfId);
        add(idTip);
        add(tPassword);
        add(jpfPassword);
        add(passwordTip);
        add(tSex);
        add(jcbSex);

        JPanel jPanel2 = new JPanel();
        btnOk.setBounds(430, 330, 60, 30);
        btnCancel.setBounds(500, 330, 60, 30);
        add(btnOk);
        add(btnCancel);

        this.add(jPanel, BorderLayout.NORTH);
        this.add(jPanel1, BorderLayout.CENTER);
        this.add(jPanel2, BorderLayout.SOUTH);

        this.setVisible(true);
        this.setSize(1000, 600);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public boolean isAllNumber (String s) {
        char[] str = s.toCharArray();
        for (char c : str) {
            if (c < '0' || c > '9') {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        new TeacherRegister();
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        if (actionEvent.getSource() == back) {
            this.dispose();
            new TeacherSelect();
        } else if (actionEvent.getSource() == btnOk) {
            // 设置临时变量存储输入值,判断
            String tempName = jtfName.getText();
            // 无输入的时候为""
            System.out.println(tempName);
            String tempId = jtfId.getText();
            String tempPassword = new String(jpfPassword.getPassword());
            String tempSex = "";

            int isEmpty = 0;
            int isLegal = 0;
            int isSelect = 0;

            if ("".equals(tempName)) {
                JOptionPane.showMessageDialog(null, "请输入姓名!");
            } else if ("".equals(tempId)) {
                JOptionPane.showMessageDialog(null, "请输入学号!");
            } else if ("".equals(tempPassword)) {
                JOptionPane.showMessageDialog(null, "请输入密码!");
            } else {
                // 表示要填写的元素全部都有填写
                isEmpty = 1;
            }

            if (isEmpty == 1) {
                if (isAllNumber(tempId)){
                    char[] strId = tempId.toCharArray();
                    if (strId.length == 11) {
                        char[] strPassword = tempPassword.toCharArray();
                        if (strPassword.length >= 6) {
                            isLegal = 1;
                        } else {
                            JOptionPane.showMessageDialog(null, "密码不满足条件!");
                        }
                    } else {
                        JOptionPane.showMessageDialog(null, "工号不是11位!");
                        jtfId.setText("");
                    }
                } else {
                    JOptionPane.showMessageDialog(null, "工号不是数字!");
                    jtfId.setText("");
                }
            }

            if (isEmpty == 1 && isLegal == 1) {
                if (jcbSex.getSelectedIndex() != 0) {
                    tempSex = stringSex[jcbSex.getSelectedIndex()];
                    isSelect = 1;
                } else {
                    JOptionPane.showMessageDialog(null, "请选择性别!");
                }
            }

            if (isEmpty == 1 && isLegal == 1 && isSelect == 1) {
                Connection conn = null;
                PreparedStatement pstmt = null;
                ResultSet rs = null;

                try {
                    conn = JDBCUtils.getConnection();
                    System.out.println("教师注册:数据库连接成功!");

                    // 先根据传入的数据是否存在,判断条件:主键Id
                    String selectId = "select tno from teacher where tno = ?";
                    pstmt = conn.prepareStatement(selectId);
                    pstmt.setString(1, tempId);
                    rs = pstmt.executeQuery();
                    String tempJudge = "";
                    while (rs.next()) {
                        tempJudge = rs.getString(1);
                    }

                    if (tempJudge.equals(tempId)) {
                        JOptionPane.showMessageDialog(null, "用户已存在!");
                    } else {
                        pstmt = null;
                        rs = null;
                        String sql = "insert into teacher(tno, password, tname, tsex) " +
                                "values(?, ?, ?, ?)";
                        pstmt = conn.prepareStatement(sql);
                        pstmt.setString(1, tempId);
                        pstmt.setString(2, tempPassword);
                        pstmt.setString(3, tempName);
                        pstmt.setString(4, tempSex);

                        // 返回影响的行数
                        int flag = pstmt.executeUpdate();

                        if (flag == 1) {
                            System.out.println("注册成功");
                            JOptionPane.showMessageDialog(null, "注册成功!");
                            this.dispose();
                            new TeacherLogin();
                        } else {
                            System.out.println("注册失败");
                            JOptionPane.showMessageDialog(null, "注册失败!");
                        }
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    JDBCUtils.close(rs, pstmt, conn);
                }
            }

        } else if (actionEvent.getSource() == btnCancel) {
            this.dispose();
            new SelectIdentity();
        }
    }
}

教师操作选择:view/TeacherSelect.java

package com.company.view;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:39
 */
public class TeacherSelect extends JFrame implements ActionListener {
    /*
     * 用户验证身份为教师之后,需要选择登录/注册
     * 根据教师的选择进行跳转相应的界面
     * */
    private JButton jRegister;
    private JButton jLogin;

    private JLabel welcome;
    private JButton back;

    public TeacherSelect() {
        super("学生在线考试系统_教师注册/登录");

        welcome = new JLabel("教师操作选择");
        back = new JButton("返回");
        back.addActionListener(this);

        JPanel jPanel = new JPanel();
        jPanel.add(welcome);
        jPanel.add(back);

        JPanel jPanel1 = new JPanel();
        JLabel jNotification = new JLabel("请选择:");
        jNotification.setBounds(430, 230, 200, 25);
        add(jNotification);

        JPanel jPanel2 = new JPanel();
        jRegister = new JButton("注册");
        jLogin = new JButton("登录");
        jRegister.setBounds(430, 260, 60, 30);
        jLogin.setBounds(500, 260, 60, 30);
        add(jRegister);
        add(jLogin);

        jRegister.addActionListener(this);
        jLogin.addActionListener(this);


        Container con = this.getContentPane();
        con.add(jPanel1, BorderLayout.NORTH);
        con.add(jPanel2, BorderLayout.CENTER);
        con.add(jPanel, BorderLayout.NORTH);
        con.setLocation(400, 200);

        this.setVisible(true);
        this.setSize(1000, 600);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        new TeacherSelect();
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        if (actionEvent.getSource() == back) {
            this.dispose();
            new SelectIdentity();
        } else if (actionEvent.getSource() == jRegister) {
            // 选择注册之后
            this.dispose();
            new TeacherRegister();
        } else if (actionEvent.getSource() == jLogin) {
            // 选择登录之后进入登录界面
            this.dispose();
            new TeacherLogin();
        }
    }
}

教师主页面:view/TeacherView.java

package com.company.view;

import com.company.student.Student;
import com.company.teacher.AddQuestion;
import com.company.teacher.UpdateScore;
import com.company.testpaper.AddPaper;
import com.company.utils.JDBCUtils;

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.Set;

/**
 * @ author: 雨下一整晚Real
 * @ date: 2021年05月10日 15:42
 */
public class TeacherView extends JFrame implements ActionListener {

    private JLabel welcome;

    private JLabel name;
    private JLabel id;
    private JLabel sex;
    private JLabel tName;
    private JLabel tId;
    private JLabel tSex;

    private JButton back;

    String teacherName = "";
    String teacherId = "";
    String teacherSex = "";

    private JLabel functionTip;
    private JButton btnAddQuestion;
    private JButton btnAddPaper;
    private JButton btnQueryScore;
    private JButton btnUpdateScore;

    // 学生信息表格查询
    private DefaultTableModel model;
    private JScrollPane jScrollPane;
    private JPanel jPanel3;
    private JTable jTable;
    Student[] students;

    public TeacherView () {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JDBCUtils.getConnection();
            System.out.println("教师界面:数据库连接成功");
            String sql = "select tname,tsex from teacher where tno = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, TeacherLogin.teacherId);
            rs = pstmt.executeQuery();
            teacherId = TeacherLogin.teacherId;
            while (rs.next()) {
                teacherName = rs.getString("tname");
                teacherSex = rs.getString("tsex");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(rs, pstmt, conn);
        }

        welcome = new JLabel("教师主页面");
        back = new JButton("返回");
        back.addActionListener(this);
        JPanel jPanel1 = new JPanel();
        jPanel1.add(welcome);
        jPanel1.add(back);

        name = new JLabel("姓名:");
        id = new JLabel("工号:");
        sex = new JLabel("性别:");
        tName = new JLabel(teacherName);
        tId = new JLabel(teacherId);
        tSex = new JLabel(teacherSex);
        JPanel jPanel2 = new JPanel();
        name.setBounds(350, 70, 50, 30);
        tName.setBounds(400, 70, 200, 30);
        id.setBounds(350, 110, 50, 30);
        tId.setBounds(400, 110, 200, 30);
        sex.setBounds(350, 150, 50, 30);
        tSex.setBounds(400, 150, 200, 30);
        add(name);
        add(tName);
        add(id);
        add(tId);
        add(sex);
        add(tSex);
        functionTip = new JLabel("请选择您的操作:");
        btnQueryScore = new JButton("查询成绩");
        btnUpdateScore = new JButton("修改成绩");
        btnAddQuestion = new JButton("添加试题");
        btnAddPaper = new JButton("添加试卷");
        functionTip.setBounds(250, 200, 200, 30);
        btnQueryScore.setBounds(250, 240, 100, 30);
        btnUpdateScore.setBounds(380, 240, 100, 30);
        btnAddQuestion.setBounds(510, 240, 100, 30);
        btnAddPaper.setBounds(640, 240, 100, 30);
        add(functionTip);
        add(btnQueryScore);
        add(btnUpdateScore);
        add(btnAddQuestion);
        add(btnAddPaper);
        btnQueryScore.addActionListener(this);
        btnUpdateScore.addActionListener(this);
        btnAddQuestion.addActionListener(this);
        btnAddPaper.addActionListener(this);

        jPanel3 = new JPanel();
        String[] columnName = {"姓名", "学号", "性别", "年龄", "成绩", "学院", "专业"};
        String[] columnWidth = {"80", "120", "40", "40", "40", "90", "90"};
        model = new DefaultTableModel();
        model.setColumnIdentifiers(columnName);

        jTable = new JTable(model);
        jTable.setBounds(280, 300, 500, 300);
        TableColumnModel tableColumnModel = jTable.getColumnModel();
        for (int i = 0; i < 7; i++) {
            TableColumn tableColumn = tableColumnModel.getColumn(i);
            tableColumn.setPreferredWidth(Integer.parseInt(columnWidth[i]));
        }
        DefaultTableCellRenderer cr = new DefaultTableCellRenderer();
        cr.setHorizontalAlignment(JLabel.CENTER);
        jTable.setDefaultRenderer(Object.class, cr);
        jScrollPane = new JScrollPane(jTable);
        add(jTable);
        jTable.setVisible(false);

        this.add(jPanel3, BorderLayout.SOUTH);
        this.add(jPanel1, BorderLayout.NORTH);
        this.add(jPanel2, BorderLayout.CENTER);

        this.setVisible(true);
        this.setTitle("学生在线考试系统_教师界面");
        this.setSize(1000, 700);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    /*public static void main(String[] args) {
        new TeacherView();
    }*/


    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        if (actionEvent.getSource() == back) {
            this.dispose();
            new TeacherLogin();
        } else if (actionEvent.getSource() == btnQueryScore) {
            // btnQueryScore.setEnabled(false);
            /*Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            this.setSize((int) screenSize.getWidth(), (int) screenSize.getHeight());*/
            Connection conn = null;
            PreparedStatement pstmt = null;
            ResultSet rs = null;
            try {
                int row = 0;
                conn = JDBCUtils.getConnection();
                String sqlQuery = "select sname, student.sno, ssex, sage, department, major, sc.score " +
                        "from student, sc " +
                        "where student.sno=sc.sno";
                String sqlRow = "select count(*) from student";
                pstmt = conn.prepareStatement(sqlRow);
                rs = pstmt.executeQuery();
                while (rs.next()) {
                    row = rs.getInt(1);
                }
                if (row == 0) {
                    JOptionPane.showMessageDialog(null, "没有学生记录!");
                } else {
                    model.setRowCount(0);
                    int countRow = 0;
                    String[] columnName = {"姓名", "学号", "性别", "年龄", "成绩", "学院", "专业"};
                    model.addRow(columnName);
                    jTable.setVisible(true);
                    pstmt = null;
                    rs = null;
                    students = new Student[row];
                    pstmt = conn.prepareStatement(sqlQuery);
                    rs = pstmt.executeQuery();
                    int i = 0;
                    while (rs.next()) {
                        students[i] = new Student();
                        students[i].setStudentName(rs.getString("sname"));
                        students[i].setStudentId(rs.getLong("sno"));
                        students[i].setStudentSex(rs.getString("ssex"));
                        students[i].setStudentAge(rs.getInt("sage"));
                        students[i].setStudentScore(rs.getInt("score"));
                        students[i].setStudentDepartment(rs.getString("department"));
                        students[i].setStudentMajor(rs.getString("major"));
                        i ++;
                    }
                    for (int j = 0; j < i; j ++) {
                        model.addRow(new Object[]{students[j].getStudentName(), students[j].getStudentId(),
                                students[j].getStudentSex(), students[j].getStudentAge(), students[j].getStudentScore(),
                                students[j].getStudentDepartment(), students[j].getStudentMajor()});
                    }
                    countRow = jTable.getRowCount();
                    jTable.setEnabled(false);
                    System.out.println(countRow);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JDBCUtils.close(rs, pstmt, conn);
            }
        } else if (actionEvent.getSource() == btnUpdateScore) {
            new UpdateScore();
        } else if (actionEvent.getSource() == btnAddQuestion) {
            // 添加试题
            new AddQuestion();
        } else if (actionEvent.getSource() == btnAddPaper) {
            // 添加试卷
            AddPaper addPaper = new AddPaper();
            // 开始连接数据库传入参数
            Connection conn = null;
            PreparedStatement preparedStatement = null;
            ResultSet rsQuery;

            Map<String, String> testPaper = null;
            try {
                testPaper = AddPaper.importTestPaper();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                int flag = 0;
                conn = JDBCUtils.getConnection();
                String sqlQuery = "select MAX(num) from test";
                System.out.println("查询最大题号:数据库连接成功!");
                preparedStatement = conn.prepareStatement(sqlQuery);
                rsQuery = preparedStatement.executeQuery();
                while (rsQuery.next()) {
                    flag = rsQuery.getInt(1);
                    // 最大的已存在,还需要 +1
                    flag++;
                }
                String sqlInsert = null;
                Set<String> keySet = testPaper.keySet();
                for (String question : keySet) {
                    sqlInsert = "insert into test values(?, ?, ?)";
                    preparedStatement = conn.prepareStatement(sqlInsert);
                    preparedStatement.setInt(1, flag);
                    preparedStatement.setString(2, question);
                    preparedStatement.setString(3, testPaper.get(question));
                    int count = preparedStatement.executeUpdate();
                    if (count == 1) {
                        System.out.println("题目添加成功!");
                    } else {
                        System.out.println("题目添加失败!");
                    }
                    flag ++;
                }
                System.out.println("题库添加完毕!");
                JOptionPane.showMessageDialog(null, "题库添加完成!");
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JDBCUtils.close(preparedStatement, conn);
            }
        }
    }
}

四、问题汇总

1. 使用类结构数组的时候发生空指针异常

/*
* 出现空指针异常
* Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
* 出现异常的原因是因为自定义的类数组,需要对每个类进行实例化
* Test[] tests = new Test[num] 是没有地方可以存数据的
* 只有每个成员进行声明后才会给这个成员分配内存
* tests[0] = new Test();
* */

2.表格多次点击查询,数据重复添加

表格多次点击查询,数据重复添加。之前设置的思路是在当前界面直接显示成绩表格,但是出现了这个问题。

之后每次点击添加的时候设置jTablerowCount = 0,每次点击就开始查询,查询一次就开始添加数据,最后显示正常。

public void actionPerformed(ActionEvent actionEvent) {
        if (actionEvent.getSource() == back) {
            this.dispose();
            new StudentSelect();
        } else if (actionEvent.getSource() == btnOk) {
            String tempName = jtfName.getText();
            // 无输入的时候为""
            System.out.println(tempName);
            String tempId = jtfId.getText();
            String tempPassword = new String(jpfPassword.getPassword());
            String tempAge = "";
            String tempSex = "";
            String tempMajor = "";
            String tempDepartment = "";

            int isEmpty = 0;
            int isLegal = 0;
            int isSelect = 0;

            if ("".equals(tempName)) {
                JOptionPane.showMessageDialog(null, "请输入姓名!");
            } else if ("".equals(tempId)) {
                JOptionPane.showMessageDialog(null, "请输入学号!");
            } else if ("".equals(tempPassword)) {
                JOptionPane.showMessageDialog(null, "请输入密码!");
            } else {
                // 表示要填写的元素全部都有填写
                isEmpty = 1;
            }

            if (isEmpty == 1) {
                if (isAllNumber(tempId)){
                    char[] strId = tempId.toCharArray();
                    if (strId.length == 11) {
                        char[] strPassword = tempPassword.toCharArray();
                        if (strPassword.length >= 6) {
                            isLegal = 1;
                        } else {
                            JOptionPane.showMessageDialog(null, "密码不满足条件!");
                        }
                    } else {
                        JOptionPane.showMessageDialog(null, "学号不是11位!");
                        jtfId.setText("");
                    }
                } else {
                    JOptionPane.showMessageDialog(null, "学号不是数字!");
                    jtfId.setText("");
                }
            }

            if (isEmpty == 1 && isLegal == 1) {
                if (jcbSex.getSelectedIndex() != 0) {
                    tempSex = stringSex[jcbSex.getSelectedIndex()];
                    if (jcbAge.getSelectedIndex() != 0) {
                        tempAge = stringAge[jcbAge.getSelectedIndex()];
                        if (jcbDepartment.getSelectedIndex() != 0) {
                            tempDepartment = stringDepartment[jcbDepartment.getSelectedIndex()];
                            if (jcbMajor.getSelectedIndex() != 0) {
                                tempMajor = stringMajor[jcbMajor.getSelectedIndex()];
                                isSelect = 1; // 表示列表项全都做出了选择
                            } else {
                                JOptionPane.showMessageDialog(null, "请选择专业!");
                            }
                        } else {
                            JOptionPane.showMessageDialog(null, "请选择学院!");
                        }
                    } else {
                        JOptionPane.showMessageDialog(null, "请选择年龄!");
                    }
                } else {
                    JOptionPane.showMessageDialog(null, "请选择性别!");
                }
            }

            // 非空才开始传入数据
            if (isEmpty == 1  && isLegal == 1 && isSelect == 1) {
                // 确认注册,需要传入数据
                Connection conn = null;
                PreparedStatement pstmt = null;
                ResultSet rs = null;
                // JDBC数据操作
                try {
                    conn = JDBCUtils.getConnection();
                    System.out.println("学生注册:数据库连接成功!");

                    // 先根据传入的数据是否存在,判断条件:主键Id
                    String selectId = "select sno from student where sno = ?";
                    pstmt = conn.prepareStatement(selectId);
                    pstmt.setString(1, tempId);
                    rs = pstmt.executeQuery();
                    int tempJudge = 0;
                    while (rs.next()) {
                        tempJudge ++;
                    }
                    if (tempJudge == 1) {
                        JOptionPane.showMessageDialog(null, "用户已存在!");
                    } else {
                        pstmt = null;
                        rs = null;
                        String sql = "insert into student(sname, sno, password, ssex," +
                                "sage, major, department) values(?, ?, ?, ?, ?, ?, ?)";
                        /*String sql2 = "insert into sc(sno) values(?)";*/
                        pstmt = conn.prepareStatement(sql);
                        pstmt.setString(1, tempName);
                        pstmt.setString(2, tempId);
                        pstmt.setString(3, tempPassword);
                        pstmt.setString(4, tempSex);
                        pstmt.setString(5, tempAge);
                        pstmt.setString(6, tempMajor);
                        pstmt.setString(7, tempDepartment);

                        // 返回影响的行数
                        int flag = pstmt.executeUpdate();

                        if (flag == 1) {
                            System.out.println("注册成功");
                            rs = null;
                            pstmt = null;
                            String sqlInert = "insert into sc(sno, score) values(?, ?) ";
                            pstmt = conn.prepareStatement(sqlInert);
                            pstmt.setString(1, tempId);
                            pstmt.setInt(2, 0);
                            int count = pstmt.executeUpdate();
                            if (count == 1) {
                                System.out.println("SC表格数据创建成功!");
                                JOptionPane.showMessageDialog(null, "注册成功!");
                            }
                            this.dispose();
                            new StudentLogin();
                        } else {
                            System.out.println("注册失败");
                            JOptionPane.showMessageDialog(null, "注册失败!");
                        }
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    JDBCUtils.close(rs, pstmt, conn);
                }
            }
        } else if (actionEvent.getSource() == btnCancel) {
            // 取消注册,返回上一级
            this.dispose();
            new StudentSelect();
        }
    }

About

用 Java 编写的在线考试系统

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages