Fourth commit

main^2
Arno 2 months ago committed by Gitea
parent c65d5cc83e
commit 4c8aa575a0

@ -0,0 +1,58 @@
# 带UI的数学学习软件
## 项目结构
Math_learning
|——lib  依赖jar包
  |——javax.mail-1.6.2.jar  发送邮件相关
  |——activation-1.1.1.jar  javax.mail所需依赖
|——src  源代码目录
  |——Base  基础类包
    |——Email_settings.java  邮件发送服务配置
    |——Exam_result.java  考试结果类
    |——Question.java  题目类
    |——User.java  用户类
  |——Generator  题目生成器包
    |——G_ques.java  生成器接口
    |——Pri_g_ques.java  小学题目生成器
    |——Jun_g_ques.java  初中题目生成器
    |——Sen_g_ques.java  高中题目生成器
    |——Generate_paper.java  生成试卷
  |——Send_Email  邮件发送包
    |——Deal_i_code.java  管理验证码以及验证码校验
    |——Generate_i_code.java  产生验证码
    |——Send_email.java  发送邮件类
  |——Service  服务类包,供前端调用
    |——User_service.java  用户服务类,包括注册、登录、修改密码等
    |——Exam_service.java  考试服务类
    |——Deal_file.java  可选功能:保存试卷为文件
  |——View  前端类包
|——doc  说明文档
  |——README.md
## 邮件发送说明
  发件人信息通过配置文件存储首次运行时会创建config/email.properties配置文件并使用默认配置乔毅凡的qq邮箱
  修改配置文件可更改发件人配置,如果要使用自己的邮箱,需要去设置中开启特定配置。
以QQ邮箱为例子
1. 需要去自己的邮箱设置中找到POP3/IMAP/SMTP/Exchange/CardDAV 服务,选择开启,生成授权码。
2. 查看QQ邮箱配置方法中的说明看到“发送邮件服务器 smtp.qq.com使用SSL端口号465或587”这就是发件服务器和使用的端口以及使用SSL。
3. 将上述信息修改到配置文件中。发件服务器、端口、SSL在默认配置中已经为QQ邮箱的配置修改邮箱和授权码即可
4. 其他邮箱配置方法具体见官方说明。
## 用户信息
用户信息保存在本地,用户/用户信息.txt(运行时会产生)
## 运行环境
可执行文件Math_Learning.jar依赖已经打包
Windows  UTF-8编码  
---
软件2302
刘星宇 202326010226
毛承上 202326010227
乔毅凡 202326010228

@ -1,13 +1,86 @@
package Base;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class Email_settings {
public static final String SMTP_HOST = "smtp.qq.com";
// 邮箱服务器端口
public static final String SMTP_PORT = "587";
// 发件人邮箱
public static final String FROM_EMAIL = "835981889@qq.com";
// 发件人邮箱授权码
public static final String EMAIL_PASSWORD = "fpqfprqznbvdbcdf";
// 是否启用SSL
public static final boolean SSL_ENABLE = true;
private static final String CONFIG_FILE = "config/email.properties";
private static Properties properties;
private static long lastModified = 0;
static {
loadConfig();
}
private static void loadConfig() {
properties = new Properties();
setDefaultProperties();
File configFile = new File(CONFIG_FILE);
if (configFile.exists()) {
try (FileInputStream input = new FileInputStream(configFile)) {
properties.load(input);
lastModified = configFile.lastModified();
} catch (IOException e) {
System.err.println("加载邮箱配置文件失败,使用默认配置: " + e.getMessage());
}
} else {
createDefaultConfigFile();
}
}
private static void setDefaultProperties() {
properties.setProperty("smtp.host", "smtp.qq.com");
properties.setProperty("smtp.port", "587");
properties.setProperty("from.email", "835981889@qq.com");
properties.setProperty("email.password", "fpqfprqznbvdbcdf");
properties.setProperty("ssl.enable", "true");
}
private static void createDefaultConfigFile() {
File configDir = new File("config");
if (!configDir.exists()) {
configDir.mkdirs();
}
try (FileOutputStream output = new FileOutputStream(CONFIG_FILE)) {
properties.store(output, "Settings");
} catch (IOException e) {
System.err.println("创建默认配置文件失败: " + e.getMessage());
}
}
private static void checkForUpdates() {
File configFile = new File(CONFIG_FILE);
if (configFile.exists() && configFile.lastModified() > lastModified) {
loadConfig();
}
}
public static String getSmtpHost() {
checkForUpdates();
return properties.getProperty("smtp.host");
}
public static String getSmtpPort() {
checkForUpdates();
return properties.getProperty("smtp.port");
}
public static String getFromEmail() {
checkForUpdates();
return properties.getProperty("from.email");
}
public static String getEmailPassword() {
checkForUpdates();
return properties.getProperty("email.password");
}
public static boolean isSslEnable() {
checkForUpdates();
return Boolean.parseBoolean(properties.getProperty("ssl.enable"));
}
}

@ -0,0 +1,53 @@
package Generator;
import Base.Question;
import Service.Deal_file;
import java.util.ArrayList;
public class Generate_paper {
public static ArrayList<Question> g_paper(int num,String type,String id) {
ArrayList<Question> result = new ArrayList<>();
G_ques generator;
switch (type){
case "小学":{
generator=new Pri_g_ques();
break;
}
case "初中":{
generator=new Jun_g_ques();
break;
}
case "高中":{
generator=new Sen_g_ques();
break;
}
default:{
generator=new Pri_g_ques();
}
}
for (int i=0;i<num;i++){
String temp;
int try_times = 0;
do {
temp = generator.g_question();
try_times++;
} while (check_repetition(result,temp) && try_times <= 50);
Question t=new Question(i+1,temp,generator.g_type());
t.set_options();
result.add(t);
}
/*Deal_file d=new Deal_file();
d.savePaper(result,id);*/
return result;
}
private static boolean check_repetition(ArrayList<Question> all,String ques){
for (Question q:all){
if (q.getContent().equals(ques)){
return true;
}
}
return false;
}
}

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: Math_learning_app

@ -0,0 +1,22 @@
import Service.User_service;
import View.Login_frame;
import javax.swing.*;
public class Math_learning_app {
private static User_service userService;
public static void main(String[] args) {
initializeServices();
SwingUtilities.invokeLater(Math_learning_app::showLoginFrame);
}
private static void initializeServices() {
userService = new User_service();
}
public static void showLoginFrame() {
Login_frame loginFrame = new Login_frame(userService);
loginFrame.setVisible(true);
}
}

@ -59,23 +59,23 @@ public class Send_email {
public static boolean send_email(String toEmail, String Code) {
try {
Properties props = new Properties();
props.put("mail.smtp.host", Email_settings.SMTP_HOST);
props.put("mail.smtp.port", Email_settings.SMTP_PORT);
props.put("mail.smtp.host", Email_settings.getSmtpHost());
props.put("mail.smtp.port", Email_settings.getSmtpPort());
props.put("mail.smtp.auth", "true");
if (Email_settings.SSL_ENABLE) {
if (Email_settings.isSslEnable()) {
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.ssl.trust", Email_settings.SMTP_HOST);
props.put("mail.smtp.ssl.trust", Email_settings.getSmtpHost());
}
// 创建会话
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(Email_settings.FROM_EMAIL, Email_settings.EMAIL_PASSWORD);
return new PasswordAuthentication(Email_settings.getFromEmail(), Email_settings.getEmailPassword());
}
});
// 创建邮件消息
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(Email_settings.FROM_EMAIL));
message.setFrom(new InternetAddress(Email_settings.getFromEmail()));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail));
message.setSubject("注册验证码");
// 邮件内容

@ -2,6 +2,7 @@ package Service;
import Base.Exam_result;
import Base.Question;
import Generator.Generate_paper;
import java.util.*;
@ -17,7 +18,7 @@ public class Exam_service {
public Exam_service(int num,String type,String id){
this.id=id;
this.type=type;
paper=Generate_paper.g_paper(num,type,id);
paper= Generate_paper.g_paper(num,type,id);
now_index=0;
this.start_time = new Date();
this.user_answers = new HashMap<>();

@ -0,0 +1,173 @@
package View;
import Base.Exam_result;
import Base.Question;
import Service.Deal_file;
import Service.Exam_service;
import Service.User_service;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Exam_frame extends JFrame {
private Exam_service examService;
private User_service userService;
private String email;
private JLabel questionLabel;
private JRadioButton[] optionButtons;
private ButtonGroup buttonGroup;
private JLabel progressLabel;
private JButton previousButton;
private JButton nextButton;
public Exam_frame(Exam_service examService, User_service userService, String email) {
this.examService = examService;
this.userService = userService;
this.email = email;
initializeUI();
showQuestion();
}
private void initializeUI() {
setTitle("考试");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 400);
setLocationRelativeTo(null);
setResizable(false);
// 主面板
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// 进度标签
progressLabel = new JLabel();
updateProgress();
mainPanel.add(progressLabel, BorderLayout.NORTH);
// 题目面板
JPanel questionPanel = new JPanel(new BorderLayout());
questionLabel = new JLabel();
questionLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
questionPanel.add(questionLabel, BorderLayout.NORTH);
// 选项面板
JPanel optionsPanel = new JPanel(new GridLayout(4, 1, 10, 10));
optionButtons = new JRadioButton[4];
buttonGroup = new ButtonGroup();
for (int i = 0; i < 4; i++) {
optionButtons[i] = new JRadioButton();
optionButtons[i].setFont(new Font("微软雅黑", Font.PLAIN, 14));
buttonGroup.add(optionButtons[i]);
optionsPanel.add(optionButtons[i]);
}
questionPanel.add(optionsPanel, BorderLayout.CENTER);
mainPanel.add(questionPanel, BorderLayout.CENTER);
// 按钮面板
JPanel buttonPanel = new JPanel(new FlowLayout());
previousButton = new JButton("上一题");
nextButton = new JButton("下一题");
buttonPanel.add(previousButton);
buttonPanel.add(nextButton);
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
// 添加事件监听器
previousButton.addActionListener(new PreviousListener());
nextButton.addActionListener(new NextListener());
add(mainPanel);
}
private void showQuestion() {
Question currentQuestion = examService.get_now_question();
if (currentQuestion == null) {
return;
}
questionLabel.setText(currentQuestion.getContent());
for (int i = 0; i < 4; i++) {
String options = currentQuestion.getOptions(i);
optionButtons[i].setText(options);
}
// 检查是否已经回答过该题
Integer userAnswer = examService.get_user_answer(examService.get_now_index());
if (userAnswer != null && userAnswer!=-1) {
optionButtons[userAnswer].setSelected(true);
} else {
buttonGroup.clearSelection();
}
updateProgress();
updateButtons();
}
private void updateProgress() {
int current = examService.get_now_index() + 1;
int total = examService.get_paper().size();
progressLabel.setText("进度: " + current + "/" + total);
}
private void updateButtons() {
int currentIndex = examService.get_now_index();
int total = examService.get_paper().size();
previousButton.setEnabled(currentIndex > 0);
nextButton.setText(currentIndex < total - 1 ? "下一题" : "提交");
}
private class PreviousListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// 保存当前答案
saveAnswer();
if (examService.pre_one()) {
showQuestion();
}
}
}
private class NextListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
boolean hasNext = examService.next_one(getSelectedOption());
if (hasNext) {
showQuestion();
} else {
if (!examService.check_finished()){
JOptionPane.showMessageDialog(Exam_frame.this,
"有题目未完成", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
Exam_result result = examService.calculate_result();
openResultFrame(result);
}
}
}
private void saveAnswer() {
int selected = getSelectedOption();
if (selected != -1) {
examService.change_answer(examService.get_now_index(), selected);
}
}
private int getSelectedOption() {
for (int i = 0; i < 4; i++) {
if (optionButtons[i].isSelected()) {
return i;
}
}
return -1;
}
private void openResultFrame(Exam_result result) {
Result_frame resultFrame = new Result_frame(examService, result , userService, email);
resultFrame.setVisible(true);
this.dispose();
}
}

@ -0,0 +1,104 @@
package View;
import Service.User_service;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Login_frame extends JFrame {
private User_service userService;
private JTextField idField;
private JPasswordField passwordField;
public Login_frame(User_service userService) {
this.userService = userService;
initializeUI();
}
private void initializeUI() {
setTitle("登录");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 350);
setLocationRelativeTo(null);
setResizable(false);
// 主面板
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// 标题
JLabel titleLabel = new JLabel("数学学习软件", JLabel.CENTER);
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24));
mainPanel.add(titleLabel, BorderLayout.NORTH);
// 表单面板
JPanel formPanel = new JPanel(new GridLayout(3, 2, 10, 10));
formPanel.add(new JLabel("用户名:"));
idField = new JTextField();
formPanel.add(idField);
formPanel.add(new JLabel("密码:"));
passwordField = new JPasswordField();
formPanel.add(passwordField);
// 按钮面板
JPanel buttonPanel = new JPanel(new FlowLayout());
JButton loginButton = new JButton("登录");
JButton registerButton = new JButton("注册账号");
JButton exitButton = new JButton("退出");
buttonPanel.add(loginButton);
buttonPanel.add(registerButton);
buttonPanel.add(exitButton);
formPanel.add(buttonPanel);
mainPanel.add(formPanel, BorderLayout.CENTER);
// 添加事件监听器
loginButton.addActionListener(new LoginListener());
registerButton.addActionListener(e -> openRegisterFrame());
exitButton.addActionListener(e -> System.exit(0));
add(mainPanel);
}
private class LoginListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String id = idField.getText().trim();
String password = new String(passwordField.getPassword());
if (id.isEmpty() || password.isEmpty()) {
JOptionPane.showMessageDialog(Login_frame.this,
"请输入用户名和密码", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
String result = userService.login(id, password);
if (result.equals("登陆成功")) {
JOptionPane.showMessageDialog(Login_frame.this,
"登录成功!", "成功", JOptionPane.INFORMATION_MESSAGE);
openMainFrame(userService.find_user_i(id).get_email());
} else {
JOptionPane.showMessageDialog(Login_frame.this,
result, "登录失败", JOptionPane.ERROR_MESSAGE);
}
}
}
private void openRegisterFrame() {
Register_frame registerFrame = new Register_frame(userService);
registerFrame.setVisible(true);
this.dispose();
}
private void openMainFrame(String email) {
Main_frame mainFrame = new Main_frame(userService, email);
mainFrame.setVisible(true);
this.dispose();
}
}

@ -0,0 +1,156 @@
package View;
import Service.Exam_service;
import Service.User_service;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main_frame extends JFrame {
private User_service userService;
private String email;
private JComboBox<String> typeComboBox;
private JTextField countField;
public Main_frame(User_service userService, String email) {
this.userService = userService;
this.email = email;
initializeUI();
}
private void initializeUI() {
setTitle("主界面");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 400);
setLocationRelativeTo(null);
setResizable(false);
// 主面板
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// 标题
JLabel titleLabel = new JLabel("数学学习软件", JLabel.CENTER);
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24));
mainPanel.add(titleLabel, BorderLayout.NORTH);
// 设置面板
JPanel settingPanel = new JPanel(new GridLayout(2, 2, 10, 10));
settingPanel.add(new JLabel("选择难度:"));
typeComboBox = new JComboBox<>(new String[]{"小学", "初中", "高中"});
settingPanel.add(typeComboBox);
settingPanel.add(new JLabel("题目数量:"));
countField = new JTextField("10");
settingPanel.add(countField);
mainPanel.add(settingPanel, BorderLayout.CENTER);
// 按钮面板
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10));
buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
JButton startButton = new JButton("开始做题");
JButton changePasswordButton = new JButton("修改密码");
JButton logoutButton = new JButton("退出登录");
JButton UnregisterButton = new JButton("删除账号");
buttonPanel.add(startButton);
buttonPanel.add(changePasswordButton);
buttonPanel.add(logoutButton);
buttonPanel.add(UnregisterButton);
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
// 添加事件监听器
startButton.addActionListener(new StartListener());
changePasswordButton.addActionListener(e -> openChangePasswordFrame());
logoutButton.addActionListener(e -> openLoginFrame());
UnregisterButton.addActionListener(e-> UnregisterOperation());
add(mainPanel);
}
private class StartListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String type = (String) typeComboBox.getSelectedItem();
String countText = countField.getText().trim();
if (countText.isEmpty()) {
JOptionPane.showMessageDialog(Main_frame.this,
"请输入题目数量", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
int count;
try {
count = Integer.parseInt(countText);
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(Main_frame.this,
"题目数量必须是数字", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
if (count < 10 || count > 30) {
JOptionPane.showMessageDialog(Main_frame.this,
"题目数量必须在10-30之间", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
// 创建考试服务
Exam_service examService = new Exam_service(count, type, userService.find_user(email).get_id());
openExamFrame(examService);
}
}
private void openExamFrame(Exam_service examService) {
Exam_frame examFrame = new Exam_frame(examService, userService, email);
examFrame.setVisible(true);
this.dispose();
}
private void openChangePasswordFrame() {
JPasswordField oldPasswordField = new JPasswordField();
JPasswordField newPasswordField = new JPasswordField();
JPasswordField confirmPasswordField = new JPasswordField();
JPanel panel = new JPanel(new GridLayout(3, 2));
panel.add(new JLabel("原密码:"));
panel.add(oldPasswordField);
panel.add(new JLabel("新密码:"));
panel.add(newPasswordField);
panel.add(new JLabel("确认新密码:"));
panel.add(confirmPasswordField);
int result = JOptionPane.showConfirmDialog(this, panel, "修改密码", JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
String oldPassword = new String(oldPasswordField.getPassword());
String newPassword = new String(newPasswordField.getPassword());
String confirmPassword = new String(confirmPasswordField.getPassword());
if (!newPassword.equals(confirmPassword)) {
JOptionPane.showMessageDialog(this,
"两次输入的新密码不一致", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
String changeResult = userService.change_pwd(email, oldPassword, newPassword);
JOptionPane.showMessageDialog(this, changeResult, "修改密码", JOptionPane.INFORMATION_MESSAGE);
}
}
private void openLoginFrame() {
Login_frame loginFrame = new Login_frame(userService);
loginFrame.setVisible(true);
this.dispose();
}
private void UnregisterOperation(){
String result=userService.Unregister(email);
JOptionPane.showMessageDialog(this, result, "删除账号", JOptionPane.INFORMATION_MESSAGE);
openLoginFrame();
}
}

@ -0,0 +1,167 @@
package View;
import Service.User_service;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Register_frame extends JFrame {
private User_service userService;
private JTextField emailField;
private JTextField codeField;
private JTextField idField;
private JPasswordField passwordField;
private JPasswordField confirmPasswordField;
private JButton sendCodeButton;
private JButton registerButton;
private JButton backButton;
public Register_frame(User_service userService) {
this.userService = userService;
initializeUI();
}
private void initializeUI() {
setTitle("注册");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 400);
setLocationRelativeTo(null);
setResizable(false);
// 主面板
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// 标题
JLabel titleLabel = new JLabel("用户注册", JLabel.CENTER);
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 20));
mainPanel.add(titleLabel, BorderLayout.NORTH);
// 表单面板
JPanel formPanel = new JPanel(new GridLayout(5, 2, 10, 10));
// 输入邮箱
formPanel.add(new JLabel("邮箱地址:"));
JPanel emailPanel = new JPanel(new BorderLayout());
emailField = new JTextField();
sendCodeButton = new JButton("发送验证码");
emailPanel.add(emailField, BorderLayout.CENTER);
emailPanel.add(sendCodeButton, BorderLayout.EAST);
formPanel.add(emailPanel);
// 验证码和密码
formPanel.add(new JLabel("验证码:"));
codeField = new JTextField();
formPanel.add(codeField);
formPanel.add(new JLabel("用户名:"));
idField = new JTextField();
formPanel.add(idField);
formPanel.add(new JLabel("密码:"));
passwordField = new JPasswordField();
formPanel.add(passwordField);
formPanel.add(new JLabel("确认密码:"));
confirmPasswordField = new JPasswordField();
formPanel.add(confirmPasswordField);
// 密码要求说明
JLabel passwordHint = new JLabel("密码要求: 6-20位至少包含大小写字母和数字");
passwordHint.setFont(new Font("微软雅黑", Font.PLAIN, 12));
passwordHint.setForeground(Color.GRAY);
mainPanel.add(formPanel, BorderLayout.CENTER);
mainPanel.add(passwordHint, BorderLayout.SOUTH);
JPanel buttonPanel = new JPanel(new FlowLayout());
registerButton = new JButton("完成注册");
backButton = new JButton("返回登录");
buttonPanel.add(registerButton);
buttonPanel.add(backButton);
add(buttonPanel, BorderLayout.SOUTH);
setStep1State();
sendCodeButton.addActionListener(new SendCodeListener());
registerButton.addActionListener(new RegisterListener());
backButton.addActionListener(e -> openLoginFrame());
add(mainPanel);
}
private void setStep1State() {
codeField.setEnabled(false);
passwordField.setEnabled(false);
confirmPasswordField.setEnabled(false);
registerButton.setEnabled(false);
}
private void setStep2State() {
codeField.setEnabled(true);
passwordField.setEnabled(true);
confirmPasswordField.setEnabled(true);
registerButton.setEnabled(true);
sendCodeButton.setEnabled(false);
}
private class SendCodeListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String email = emailField.getText().trim();
String result = userService.register(email);
if (result.equals("验证码已发送")) {
JOptionPane.showMessageDialog(Register_frame.this,
"验证码已发送到您的邮箱,请查收", "成功", JOptionPane.INFORMATION_MESSAGE);
setStep2State();
} else {
JOptionPane.showMessageDialog(Register_frame.this,
result, "错误", JOptionPane.ERROR_MESSAGE);
}
}
}
private class RegisterListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String email = emailField.getText().trim();
String id = idField.getText().trim();
String code = codeField.getText().trim();
String password = new String(passwordField.getPassword());
//确认密码(输两次)
String confirmPassword = new String(confirmPasswordField.getPassword());
if (code.isEmpty() || password.isEmpty() || confirmPassword.isEmpty()) {
JOptionPane.showMessageDialog(Register_frame.this,
"请填写所有字段", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
if (!password.equals(confirmPassword)) {
JOptionPane.showMessageDialog(Register_frame.this,
"两次输入的密码不一致", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
String result = userService.check_register(email, code, password,id);
if (result.equals("注册成功")) {
JOptionPane.showMessageDialog(Register_frame.this,
"注册成功!", "成功", JOptionPane.INFORMATION_MESSAGE);
openLoginFrame();
} else {
JOptionPane.showMessageDialog(Register_frame.this,
result, "注册失败", JOptionPane.ERROR_MESSAGE);
}
}
}
private void openLoginFrame() {
Login_frame loginFrame = new Login_frame(userService);
loginFrame.setVisible(true);
this.dispose();
}
}

@ -0,0 +1,82 @@
package View;
import Base.Exam_result;
import Service.Exam_service;
import Service.User_service;
import javax.swing.*;
import java.awt.*;
public class Result_frame extends JFrame {
private Exam_service examService;
private Exam_result result;
private User_service userService;
private String email;
public Result_frame(Exam_service ex,Exam_result result, User_service userService, String email) {
this.examService=ex;
this.result = result;
this.userService = userService;
this.email = email;
initializeUI();
}
private void initializeUI() {
setTitle("考试结果");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 400);
setLocationRelativeTo(null);
setResizable(false);
// 主面板
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// 标题
JLabel titleLabel = new JLabel("考试结果", JLabel.CENTER);
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24));
mainPanel.add(titleLabel, BorderLayout.NORTH);
// 结果信息
JPanel resultPanel = new JPanel(new GridLayout(5, 1, 10, 10));
resultPanel.add(new JLabel("考试类型: " + result.getExamType()));
resultPanel.add(new JLabel("题目数量: " + result.getTotalQuestions()));
resultPanel.add(new JLabel("正确题目: " + result.getCorrectAnswers()));
resultPanel.add(new JLabel("得分: " + String.format("%.2f", result.getScore())));
resultPanel.add(new JLabel("用时: " + result.getDuration()));
mainPanel.add(resultPanel, BorderLayout.CENTER);
// 按钮面板
JPanel buttonPanel = new JPanel(new FlowLayout());
JButton reviewButton =new JButton("查看错题");
JButton mainMenuButton = new JButton("返回主菜单");
JButton exitButton = new JButton("退出");
buttonPanel.add(reviewButton);
buttonPanel.add(mainMenuButton);
buttonPanel.add(exitButton);
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
// 添加事件监听器
reviewButton.addActionListener(e->openReviewFrame());
mainMenuButton.addActionListener(e -> openMainFrame());
exitButton.addActionListener(e -> System.exit(0));
add(mainPanel);
}
private void openMainFrame() {
Main_frame mainFrame = new Main_frame(userService, email);
mainFrame.setVisible(true);
this.dispose();
}
private void openReviewFrame(){
examService.set_now_index(0);
Review_frame reviewFrame= new Review_frame(examService,userService, email,result);
reviewFrame.setVisible(true);
this.dispose();
}
}

@ -0,0 +1,148 @@
package View;
import Base.Exam_result;
import Base.Question;
import Service.Exam_service;
import Service.User_service;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Review_frame extends JFrame{
private Exam_service examService;
private User_service userService;
private String email;
private Exam_result examResult;
private JLabel questionLabel;
private JLabel[] optionLabel;
private JLabel progressLabel;
private JButton previousButton;
private JButton nextButton;
private JButton exitButton;
public Review_frame(Exam_service examService, User_service userService, String email,Exam_result ex) {
this.examService = examService;
this.userService = userService;
this.email = email;
this.examResult = ex;
initializeUI();
showQuestion();
}
private void initializeUI() {
setTitle("查看错题");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 400);
setLocationRelativeTo(null);
setResizable(false);
// 主面板
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// 进度标签
progressLabel = new JLabel();
updateProgress();
mainPanel.add(progressLabel, BorderLayout.NORTH);
// 题目面板
JPanel questionPanel = new JPanel(new BorderLayout());
questionLabel = new JLabel();
questionLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
questionPanel.add(questionLabel, BorderLayout.NORTH);
// 选项面板
JPanel optionsPanel = new JPanel(new GridLayout(4, 1, 10, 10));
optionLabel = new JLabel[4];
for (int i = 0; i < 4; i++) {
optionLabel[i] = new JLabel();
optionLabel[i].setFont(new Font("微软雅黑", Font.PLAIN, 14));
optionsPanel.add(optionLabel[i]);
}
questionPanel.add(optionsPanel, BorderLayout.CENTER);
mainPanel.add(questionPanel, BorderLayout.CENTER);
// 按钮面板
JPanel buttonPanel = new JPanel(new FlowLayout());
previousButton = new JButton("上一题");
nextButton = new JButton("下一题");
exitButton = new JButton("返回");
buttonPanel.add(previousButton);
buttonPanel.add(nextButton);
buttonPanel.add(exitButton);
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
// 添加事件监听器
previousButton.addActionListener(new Review_frame.PreviousListener());
nextButton.addActionListener(new Review_frame.NextListener());
exitButton.addActionListener(e->openResultFrame());
add(mainPanel);
}
private void showQuestion() {
Question currentQuestion = examService.get_now_question();
if (currentQuestion == null) {
return;
}
questionLabel.setText(currentQuestion.getContent());
if (examResult.getWrongQuestions().contains(examService.get_now_index())) {
for (int i = 0; i < 4; i++) {
String options = currentQuestion.getOptions(i);
if (options.equals(currentQuestion.getAnswer())){
options=options+"√";
}
else if (i==examService.get_user_answers().get(examService.get_now_index())){
options=options+"×";
}
optionLabel[i].setText(options);
}
}
else {
for (int i = 0; i < 4; i++) {
String options = currentQuestion.getOptions(i);
if (options.equals(currentQuestion.getAnswer())){
options=options+"√";
}
optionLabel[i].setText(options);
}
}
updateProgress();
}
private void updateProgress() {
int current = examService.get_now_index() + 1;
int total = examService.get_paper().size();
progressLabel.setText("进度: " + current + "/" + total);
}
private class PreviousListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
examService.set_now_index(-1);
showQuestion();
}
}
private class NextListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
examService.set_now_index(1);
showQuestion();
}
}
private void openResultFrame() {
Result_frame resultFrame = new Result_frame(examService, examResult, userService, email);
resultFrame.setVisible(true);
this.dispose();
}
}
Loading…
Cancel
Save