Compare commits

..

No commits in common. 'new' and 'main' have entirely different histories.
new ... main

30
.gitignore vendored

@ -0,0 +1,30 @@
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
.kotlin
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

8
.idea/.gitignore vendored

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1 @@
README.md

@ -0,0 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" build-on-make="true" name="mathQuetion:jar">
<output-path>$PROJECT_DIR$/out/artifacts/mathQuetion_jar</output-path>
<root id="archive" name="untitled.jar">
<element id="module-output" name="untitled" />
</root>
</artifact>
</component>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/untitled.iml" filepath="$PROJECT_DIR$/untitled.iml" />
</modules>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

@ -1,10 +0,0 @@
import controller.MainController;
import javax.swing.*;
public class MathLearningApp {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new MainController().showLogin();
});
}
}

@ -1,46 +0,0 @@
package controller;
import service.*;
import view.*;
public class AuthController {
private UserService userService = new UserService();
private EmailService emailService = new EmailService();
private MainController mainController;
private String currentUser;
public AuthController(MainController mainController) {
this.mainController = mainController;
}
public boolean login(String email, String password) {
if (userService.login(email, password)) {
currentUser = email;
mainController.showMainFrame();
return true;
}
return false;
}
public String register(String email) {
String code = userService.registerUser(email);
if (code != null) {
int sendResult = emailService.sendRegistrationCode(email, code);
if (sendResult == 1) {
return code;
}
}
return null;
}
public boolean completeRegistration(String email, String code, String password, String confirmPassword) {
return password.equals(confirmPassword) && userService.completeRegistration(email, code, password);
}
public void showLogin() {
new LoginFrame(this);
}
public void showRegister() {
new RegisterFrame(this);
}
}

@ -1,9 +0,0 @@
package controller;
public class Config {
public static final String USER_DATA_FILE = "users.dat";
public static final int MIN_PASSWORD_LENGTH = 6;
public static final int MAX_PASSWORD_LENGTH = 10;
public static final int MIN_QUESTIONS = 1;
public static final int MAX_QUESTIONS = 100;
}

@ -1,59 +0,0 @@
package controller;
import service.QuestionService;
import view.ExamFrame;
import java.util.List;
import javax.swing.JOptionPane;
public class ExamController {
private MainController mainController;
private QuestionService questionService = new QuestionService();
public ExamController(MainController mainController) {
this.mainController = mainController;
}
public void startExam(String difficulty) {
try {
String input = JOptionPane.showInputDialog("请输入题目数量:");
if (input != null) {
int count = Integer.parseInt(input);
if (count > 0) {
List<model.Question> questions = questionService.generateQuestions(difficulty, count);
new ExamFrame(this, questions);
} else {
JOptionPane.showMessageDialog(null, "题目数量必须大于0");
}
}
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, "请输入有效数字");
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "生成题目时出现错误: " + e.getMessage());
}
}
public void showResult(int score, int total) {
// 计算百分比
int percentage = (int) ((double) score / total * 100);
// 显示成绩
JOptionPane.showMessageDialog(null,
"考试结束!\n" +
"得分: " + score + "/" + total + "\n" +
"正确率: " + percentage + "%",
"考试结果",
JOptionPane.INFORMATION_MESSAGE);
// 重新显示主界面
mainController.showMainFrame();
}
public void returnToMain() {
// 返回到主界面
mainController.showMainFrame();
}
// 获取主控制器(如果需要)
public MainController getMainController() {
return mainController;
}
}

@ -1,93 +0,0 @@
package controller;
import view.*;
public class MainController {
private AuthController authController = new AuthController(this);
private ExamController examController = new ExamController(this);
private MainFrame mainFrame;
public MainController() {
// 控制器初始化
}
/**
*
*/
public void showLogin() {
// 如果主界面存在,先关闭它
if (mainFrame != null) {
mainFrame.dispose();
mainFrame = null;
}
// 创建并显示登录界面
new LoginFrame(authController);
}
/**
*
*/
public void showMainFrame() {
if (mainFrame == null) {
// 第一次显示,创建主界面
mainFrame = new MainFrame(this);
}
// 显示主界面
mainFrame.showFrame();
// 确保主界面位于前台
mainFrame.toFront();
mainFrame.requestFocus();
}
/**
*
* @param difficulty
*/
public void startExam(String difficulty) {
examController.startExam(difficulty);
}
/**
* 退
*/
public void logout() {
// 清理主界面
if (mainFrame != null) {
mainFrame.dispose();
mainFrame = null;
}
// 显示登录界面
showLogin();
}
/**
*
*/
public AuthController getAuthController() {
return authController;
}
/**
*
*/
public ExamController getExamController() {
return examController;
}
/**
*
*/
public MainFrame getMainFrame() {
return mainFrame;
}
/**
* 退
*/
public void exitApplication() {
// 清理资源
if (mainFrame != null) {
mainFrame.dispose();
}
System.exit(0);
}
}

@ -0,0 +1,112 @@
# math_question
中小学数学卷子自动生成程序 - 发布说明
# 1.程序简介
中小学数学卷子自动生成程序是一个为中小学数学教师设计的命令行工具,能够根据小学、初中、高中不同难度要求自动生成数学试卷题目。
# 2.系统配置:
Windows 平台
操作系统: Windows 7 / 8 / 10 / 11
Java环境: Java 8 或更高版本
Linux平台
操作系统: Ubuntu 16.04+ / CentOS 7+ / 其他主流Linux发行版
Java环境: OpenJDK 8 或 Oracle JDK 8+
# 3.环境需求:
在运行程序前请先检查系统是否已安装Java
Windows:
cmd
java -version
Linux/macOS:
bash
java -version
如果显示Java版本信息如 java version "1.8.0_291"说明环境正常。如果未安装Java请从 Oracle官网 或 OpenJDK官网 下载安装。
# 4.运行指南
该项目存放于目录math_question_release_v1.0下包含可执行文件包mathQuetion.jar
Windows
方法一:使用批处理文件(推荐)
安装jdk后双击mathQuestion.jar文件可直接运行或右键选择"以管理员身份运行"
方法二:命令行运行
cmd
cd math_question_release_v1.0 #进入程序目录
java -jar mathQuestion.jar #运行程序
方法三PowerShell运行
PowerShell
cd "C:\path\to\your\project" #进入目录
java -jar math_question.jar #运行
若出现中文乱码问题,需要设置 .NET 控制台输入/输出编码为 UTF-8输入以下代码
[Console]::InputEncoding = [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
Linux
方法一使用Shell脚本推荐
bash
chmod +x run_linux.sh #给脚本执行权限
./run_linux.sh #运行
方法二:命令行运行
bash
cd math_question_release_v1.0 #进入程序目录
java -jar mathQuestion.jar #运行
# 5.参数设置
程序支持以下命令行参数:
bash
#指定配置文件
java -jar math_question.jar --config config/custom.properties
#指定日志级别
java -jar math_question.jar --log-level INFO
#指定输出目录
java -jar math_question.jar --output /path/to/output
#静默模式(无交互)
java -jar math_question.jar --silent
内存参数
bash
#设置堆内存大小
java -Xms128m -Xmx512m -jar math_question.jar
#设置年轻代大小
java -XX:NewSize=64m -XX:MaxNewSize=128m -jar math_question.jar
# 6.使用流程
启动程序 → 选择适合平台的启动方式
用户登录 → 输入用户名和密码
生成题目 → 输入题目数量10-30
切换难度 → 输入"切换为小学/初中/高中"
退出登录 → 输入"-1"
# 7.版本信息
当前版本: v1.0
发布日期: 2025年9月29日
开发者: 湖南大学金郅博

@ -0,0 +1,19 @@
1. 34 / 30 =
2. ((44) - 97 - 68) * 15 =
3. 63 / 81 =
4. 96 =
5. ((36) - 18 + 35) =
6. 76 - 52 =
7. (34 * 99 / 50) - 77 =
8. (57) - 51 + 90 =
9. (((4) * 9) + 15) / 6 =
10. ((20 - 11) + 95 * 39) =

@ -0,0 +1,29 @@
1. 21 =
2. 61 / 51 =
3. ((98) / 56 - 89) + 50 =
4. (58) - 1 + 74 =
5. 62 =
6. 44 - 62 - 47 =
7. (63 / 26 + 92) =
8. 21 =
9. ((54) * 43 - 14) =
10. (44 / 75) / 9 / 71 / 43 =
11. 76 / 45 =
12. ((((61) + 17 - 94) - 19) / 33) =
13. 38 =
14. (94 / 22 / 27 + 70 - 40) =
15. 81 - 48 =

@ -0,0 +1,29 @@
1. 58 =
2. 19 / 81 =
3. 77 - 20 =
4. (66 + 65 + 35 / 57) =
5. 29 / 37 =
6. (64 / 31) - 27 * 64 - 69 =
7. ((97) * 83 * 39 + 23) =
8. 72 - 85 =
9. 30 - 79 + 63 + 82 =
10. 95 - 26 =
11. 13 - 98 =
12. 36 - 55 =
13. (((94 + 72) * 1) * 13) / 90 =
14. 36 * 69 =
15. (68 + 60) * 65 / 33 =

@ -0,0 +1,31 @@
1. 69 =
2. (4 + 49 - 36 + 79) =
3. 17 =
4. ((83 + 61 - 26) + 24 * 93) =
5. 65 =
6. 16 / 66 =
7. 5 / 93 =
8. 33 / 11 =
9. 91 =
10. (22 - 13) + 70 + 40 / 59 =
11. 88 =
12. ((87) + 89) - 55 * 76 =
13. 63 + 18 + 6 - 25 =
14. 44 / 37 - 45 - 87 =
15. ((74) + 53) / 31 / 54 =
16. 91 / 9 + 55 * 38 =

@ -0,0 +1,31 @@
1. 69 - 65 - 7 =
2. 72 / 96 =
3. 35 / 75 =
4. 23 - 11 - 99 + 17 * 34 =
5. 8 - 21 =
6. 24 / 61 =
7. (55 + 43 /) 47 / 5 =
8. (26 - 22 *) 30 * 54 * 62 =
9. 90 / 20 + 44 + 32 =
10. 14 / 80 =
11. 55 + 72 + 51 + 16 / 84 =
12. 16 / 61 =
13. (18 + 36 /) 20 / 36 * 31 =
14. (3 + 90 /) 99 =
15. 29 * 65 =
16. 91 - 28 =

@ -0,0 +1,45 @@
1. (92 + 89 *) 83 =
2. 68 - 62 =
3. (57 - 88 /) 8 - 80 * 88 =
4. (65 + 64 +) 51 / 65 * 57 =
5. 41 - 42 =
6. 75 * 97 - 68 =
7. 87 * 78 * 55 * 46 - 1 =
8. (37 / 98 +) 3 =
9. 66 - 4 * 44 * 65 =
10. 93 - 86 + 67 / 20 =
11. 100 / 23 / 86 + 11 =
12. 53 / 52 / 85 + 84 =
13. (51 / 42 +) 9 - 62 - 8 =
14. 92 * 41 - 86 * 57 =
15. 39 - 42 * 26 - 14 =
16. 22 * 91 - 9 * 53 =
17. (55 * 8 -) 76 * 47 =
18. 54 - 98 - 79 * 66 =
19. 9 - 90 - 63 =
20. (18 * 64 /) 97 - 99 =
21. (90 * 88 *) 9 =
22. 70 + 87 * 67 =
23. 83 / 9 - 45 + 15 =

@ -0,0 +1,31 @@
1. √26 =
2. (2)² =
3. √56 =
4. (1)² =
5. (41 / 60 /) 71 =
6. (5)² =
7. √57 =
8. √91 =
9. √71 =
10. (3)² + 17 - 41 * 61 - 99 * 52 =
11. (9 + 52 * 9 +) 51 * 27 =
12. √62 + 1 * 16 - 31 =
13. (6)² =
14. √38 + (7 - 5 -) 57 - 12 =
15. √29 =
16. √73 =

@ -0,0 +1,31 @@
1. sin(26°) =
2. sin(53°) + 34 * 16 / 59 =
3. 48 * 85 - 80 =
4. cos(52°) + (2)² + 54 - 34 / 99 + 69 =
5. tan(44°) + (1)² =
6. cos(6°) + 27 - 34 * 83 =
7. (44 - 79 /) 10 - 62 =
8. 35 / 42 / 21 / 24 + 75 =
9. sin(84°) + √76 =
10. cos(1°) =
11. sin(5°) + √55 =
12. sin(31°) =
13. cos(79°) + (78 * 51 -) 67 - 67 / 32 =
14. cos(7°) + (37 - 6 *) 8 / 89 - 1 =
15. sin(20°) + (19 * 74 +) 83 =
16. tan(53°) + 51 / 76 - 71 + 68 =

@ -0,0 +1,31 @@
1. 32 + 97 / 81 * 72 / 2 =
2. 15 / 83 =
3. 35 + 72 * 65 + 4 * 16 =
4. (51 / 62) - 12 =
5. 58 * 52 =
6. 76 / 2 - 93 =
7. 80 - 12 + 75 / 41 =
8. 46 - 68 =
9. 58 - 48 - 27 - 10 =
10. 65 * 24 =
11. 15 - 78 * 28 - 66 + 72 =
12. 52 * 34 + 35 =
13. (91 / 27) + 49 - 32 =
14. 68 * 51 + 15 * 32 =
15. 39 + 14 * 63 * 3 - 73 =
16. 36 + 30 / 20 * 85 =

@ -0,0 +1,31 @@
1. 13 - 63 - 23 + 34 - 6 =
2. 13 - 17 =
3. √74 + 36 / 23 + 75 =
4. (6)² + 83 * 97 / 75 - 77 / 52 =
5. (4)² =
6. (8)² + 19 - 91 / 67 * 97 =
7. √35 + 47 / 40 =
8. (7)² =
9. √8 =
10. √90 =
11. 44 * 21 - 58 / 80 / 94 =
12. √18 =
13. √70 =
14. (10)² + 78 * 95 - 22 * 72 - 33 =
15. √34 =
16. (8)² + 12 - 50 - 74 =

@ -0,0 +1,31 @@
1. cos(4°) + √40 + 23 / 26 =
2. tan(26°) + √9 =
3. sin(24°) + √90 + 72 + 52 =
4. sin(86°) =
5. cos(62°) + (10)² =
6. 97 / 100 + 38 - 69 =
7. cos(20°) =
8. 19 / 79 + 3 - 85 / 34 =
9. sin(46°) + 52 + 6 =
10. 44 * 69 - 98 + 94 * 75 =
11. sin(48°) + 4 + 58 * 75 =
12. sin(80°) + 32 - 97 + 85 - 86 =
13. sin(72°) + (13 * 68) + 63 =
14. tan(84°) + 66 / 90 * 4 =
15. 38 / 19 =
16. cos(6°) + 41 + 28 * 73 - 44 =

@ -0,0 +1,59 @@
1. 50 + 97 + 6 + 70 =
2. cos(31°) + 21 + (13 / 72) / 76 * 74 =
3. tan(33°) + 41 + 30 - 19 / 29 * 66 =
4. tan(88°) + √68 + 34 - 15 - 5 =
5. tan(59°) =
6. sin(59°) + 20 * 60 / 46 / 71 =
7. sin(36°) + (7)² + 47 * 48 / 23 + 5 - 20 =
8. 87 - 43 =
9. cos(19°) =
10. 42 * (56 - 58) - 6 =
11. sin(41°) + (10 + 75) / 47 / 96 =
12. sin(38°) =
13. cos(35°) + (1)² =
14. 80 / 97 + (18 - 92) / 80 =
15. cos(83°) =
16. cos(85°) + 33 + 69 - 8 - 48 * 6 =
17. sin(61°) + 25 / 33 + 42 =
18. 35 + 75 =
19. sin(51°) + (23 + 18) + 12 * 79 =
20. sin(63°) + 68 - 40 =
21. tan(84°) + 82 - 72 * 31 =
22. sin(50°) =
23. cos(22°) =
24. tan(81°) + √31 =
25. cos(6°) + 3 * 24 =
26. tan(49°) + √28 =
27. tan(27°) + 48 - 16 =
28. cos(40°) =
29. sin(43°) + 5 - 9 + 55 - 90 + 71 =
30. sin(67°) + (1)² =

@ -0,0 +1,39 @@
1. (9)² =
2. √99 =
3. (5)² =
4. √86 + (39) + 56 / 86 =
5. √44 + ((21) * 49) / 19 / 15 / 6 =
6. (4)² =
7. (7)² =
8. (5)² + (36 - 53 + 24) =
9. √27 =
10. (2)² =
11. (6)² + ((30) / 29 / 87) * 6 + 49 =
12. √54 =
13. √73 =
14. (5)² + 14 * 89 / 65 / 6 - 16 =
15. √55 =
16. √74 + (((16) - 29) * 26 - 34) =
17. √11 =
18. √41 + ((71) / 57 - 16 * 8) + 90 =
19. (6)² =
20. √63 =

@ -0,0 +1,51 @@
1. (4)² + 42 =
2. √4 + 1 =
3. √30 + 51 - 84 =
4. √99 + 60 =
5. √22 + 97 =
6. (6)² + ((12) + 10 * 78 + 17 + 9) =
7. (3)² + 5 =
8. √28 + 91 =
9. (2)² + 11 / 57 - 87 =
10. (10)² + 55 * 97 =
11. (8)² + (74) / 18 - 46 + 12 =
12. (9)² + 96 =
13. √46 + 48 =
14. (2)² + 71 * 83 =
15. √42 + (44 / 91 + 51) =
16. √51 + 36 - 57 =
17. (3)² + 88 =
18. (3)² + 80 =
19. √87 + 96 * 45 =
20. (9)² + 40 =
21. (6)² + ((67 * 20) + 91) + 85 =
22. (8)² + ((24 * 46) / 40) / 5 * 100 =
23. √19 + 19 =
24. √95 + 17 + 91 / 27 =
25. (7)² + 31 =
26. √100 + (39) * 72 - 50 =

@ -0,0 +1,29 @@
1. 27 =
2. (61) + 90 / 15 - 25 =
3. (42 / 28 - 92 - 53) - 13 =
4. 79 * 71 / 94 =
5. 66 - 24 + 85 - 52 =
6. 95 =
7. 70 * 18 =
8. (88 * 26 - 7 * 88 - 95) =
9. (60 - 1 - 34) =
10. 86 =
11. 2 - 90 - 21 =
12. 6 =
13. 87 =
14. (40 - 14 + 6 + 78 - 76) =
15. 91 - 4 * 78 + 19 =

@ -0,0 +1,39 @@
1. sin(67°) + ((91) - 77) + 2 =
2. cos(40°) + (88) / 44 + 69 + 17 + 93 =
3. sin(20°) + 84 + 3 =
4. tan(16°) + 31 * 7 + 87 + 64 =
5. tan(18°) + (((24 - 34) - 27 * 58) * 67) =
6. cos(26°) + ((77 - 15 * 79) / 14 - 19) =
7. sin(24°) + 71 =
8. tan(14°) + 28 + 83 =
9. sin(7°) + (84) / 54 / 48 / 64 + 39 =
10. cos(21°) + 66 =
11. sin(33°) + 53 =
12. cos(37°) + 93 + 83 / 50 / 6 =
13. sin(38°) + (86 / 53 / 19 * 31) =
14. sin(48°) + 8 / 18 =
15. cos(83°) + 53 + 99 =
16. cos(73°) + 28 / 36 =
17. cos(10°) + 13 - 13 =
18. cos(83°) + 2 =
19. tan(35°) + (83) * 31 / 11 - 93 =
20. tan(26°) + (((53 + 63) + 74) + 22 / 58) =

@ -0,0 +1,124 @@
import interfaces.LoginSystemInterface;
import interfaces.FileManagerInterface;
import models.User;
import models.DifficultyLevel;
import factories.ServiceFactory;
import services.QuestionGenerator;
import java.util.Scanner;
public class Application {
private Scanner scanner;
private LoginSystemInterface loginSystem;
private QuestionGenerator generator;
private FileManagerInterface fileManager;
public Application() {
this.scanner = new Scanner(System.in);
this.loginSystem = ServiceFactory.createLoginSystem();
this.generator = new QuestionGenerator();
this.fileManager = ServiceFactory.createFileManager();
}
public void start() {
while (true) {
User currentUser = handleLogin();
if (currentUser != null) {
handleUserSession(currentUser);
}
}
}
private User handleLogin() {
while (true) {
System.out.print("请输入用户名和密码(用空格隔开):");
String input = scanner.nextLine().trim();
String[] parts = input.split("\\s+");
if (parts.length != 2) {
System.out.println("请输入正确的用户名、密码");
continue;
}
User user = loginSystem.login(parts[0], parts[1]);
if (user != null) {
System.out.println("当前选择为" + user.getLevel().getDisplayName() + "出题");
return user;
} else {
System.out.println("请输入正确的用户名、密码");
}
}
}
private void handleUserSession(User user) {
while (true) {
showPrompt(user);
String command = scanner.nextLine().trim();
if (processCommand(command, user)) {
break;
}
}
}
private void showPrompt(User user) {
System.out.println("准备生成" + user.getLevel().getDisplayName() +
"数学题目,请输入生成题目数量(输入-1将退出当前用户重新登录");
}
private boolean processCommand(String command, User user) {
// 检查退出命令
if (command.equals("-1")) {
System.out.println("退出当前用户,重新登录...");
return true;
}
// 检查切换命令
if (command.startsWith("切换为")) {
return handleSwitchLevel(command, user);
}
// 处理生成题目命令
handleGenerateQuestions(command, user);
return false;
}
private boolean handleSwitchLevel(String command, User user) {
String levelName = command.substring(3).trim();
DifficultyLevel newLevel = loginSystem.switchLevel(levelName);
if (newLevel != null) {
user.setLevel(newLevel);
// 这里不再显示提示信息,让主循环重新显示
}
return false; // 继续当前会话
}
private void handleGenerateQuestions(String command, User user) {
try {
int count = Integer.parseInt(command);
if (count < 10 || count > 30) {
System.out.println("题目数量应在10-30之间");
return;
}
generateAndSaveQuestions(user, count);
} catch (NumberFormatException e) {
System.out.println("请输入有效的数字");
}
}
private void generateAndSaveQuestions(User user, int count) {
String[] questions = generator.generateQuestions(user.getLevel(), count, user.getUsername());
if (questions == null) {
System.out.println("生成题目失败,可能存在重复题目");
return;
}
boolean success = fileManager.saveQuestions(user, questions);
if (success) {
System.out.println("题目生成成功!");
} else {
System.out.println("文件保存失败");
}
}
}

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

@ -0,0 +1,6 @@
public class Main {
public static void main(String[] args) {
Application app = new Application();
app.start();
}
}

@ -0,0 +1,16 @@
package factories;
import interfaces.LoginSystemInterface;
import interfaces.FileManagerInterface;
import services.LoginSystem;
import services.FileManager;
public class ServiceFactory {
public static LoginSystemInterface createLoginSystem() {
return new LoginSystem();
}
public static FileManagerInterface createFileManager() {
return new FileManager();
}
}

@ -0,0 +1,9 @@
package interfaces;
import models.User;
import java.util.Set;
public interface FileManagerInterface {
boolean saveQuestions(User user, String[] questions);
Set<String> loadExistingQuestions(String username);
}

@ -0,0 +1,9 @@
package interfaces;
import models.User;
import models.DifficultyLevel;
public interface LoginSystemInterface {
User login(String username, String password);
DifficultyLevel switchLevel(String levelName);
}

@ -0,0 +1,10 @@
package interfaces;
import models.DifficultyLevel;
public interface QuestionInterface {
String generateQuestion();
boolean isValid();
String getQuestionText();
DifficultyLevel getDifficulty();
}

@ -0,0 +1,26 @@
package models;
public enum DifficultyLevel {
PRIMARY("小学"),
JUNIOR("初中"),
SENIOR("高中");
private final String displayName;
DifficultyLevel(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return displayName;
}
public static DifficultyLevel fromString(String text) {
for (DifficultyLevel level : DifficultyLevel.values()) {
if (level.displayName.equals(text)) {
return level;
}
}
return null;
}
}

@ -0,0 +1,18 @@
package models;
public class User {
private String username;
private String password;
private DifficultyLevel level;
public User(String username, String password, DifficultyLevel level) {
this.username = username;
this.password = password;
this.level = level;
}
public String getUsername() { return username; }
public String getPassword() { return password; }
public DifficultyLevel getLevel() { return level; }
public void setLevel(DifficultyLevel level) { this.level = level; }
}

@ -0,0 +1,68 @@
package services;
import interfaces.FileManagerInterface;
import models.User;
import java.io.*;
import java.nio.file.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class FileManager implements FileManagerInterface {
private static final String BASE_DIR = "exams";
@Override
public boolean saveQuestions(User user, String[] questions) {
try {
Path userDir = Paths.get(BASE_DIR, user.getUsername());
Files.createDirectories(userDir);
String timestamp = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
Path filePath = userDir.resolve(timestamp + ".txt");
try (PrintWriter writer = new PrintWriter(Files.newBufferedWriter(filePath))) {
for (int i = 0; i < questions.length; i++) {
writer.println(questions[i]);
if (i < questions.length - 1) {
writer.println();
}
}
}
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
@Override
public Set<String> loadExistingQuestions(String username) {
Set<String> questions = new HashSet<>();
Path userDir = Paths.get(BASE_DIR, username);
if (!Files.exists(userDir)) {
return questions;
}
try (DirectoryStream<Path> stream = Files.newDirectoryStream(userDir, "*.txt")) {
for (Path filePath : stream) {
try (BufferedReader reader = Files.newBufferedReader(filePath)) {
String line;
while ((line = reader.readLine()) != null) {
if (line.trim().isEmpty() || !line.contains(".")) {
continue;
}
String question = line.substring(line.indexOf(".") + 1).trim();
questions.add(question);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return questions;
}
}

@ -0,0 +1,48 @@
package services;
import interfaces.LoginSystemInterface;
import models.User;
import models.DifficultyLevel;
import java.util.HashMap;
import java.util.Map;
public class LoginSystem implements LoginSystemInterface {
private Map<String, User> users;
public LoginSystem() {
initializeUsers();
}
private void initializeUsers() {
users = new HashMap<>();
users.put("张三1", new User("张三1", "123", DifficultyLevel.PRIMARY));
users.put("张三2", new User("张三2", "123", DifficultyLevel.PRIMARY));
users.put("张三3", new User("张三3", "123", DifficultyLevel.PRIMARY));
users.put("李四1", new User("李四1", "123", DifficultyLevel.JUNIOR));
users.put("李四2", new User("李四2", "123", DifficultyLevel.JUNIOR));
users.put("李四3", new User("李四3", "123", DifficultyLevel.JUNIOR));
users.put("王五1", new User("王五1", "123", DifficultyLevel.SENIOR));
users.put("王五2", new User("王五2", "123", DifficultyLevel.SENIOR));
users.put("王五3", new User("王五3", "123", DifficultyLevel.SENIOR));
}
@Override
public User login(String username, String password) {
User user = users.get(username);
if (user != null && user.getPassword().equals(password)) {
return user;
}
return null;
}
@Override
public DifficultyLevel switchLevel(String levelName) {
DifficultyLevel newLevel = DifficultyLevel.fromString(levelName);
if (newLevel == null) {
System.out.println("请输入小学、初中和高中三个选项中的一个");
return null;
}
return newLevel;
}
}

@ -0,0 +1,238 @@
package services;
import interfaces.QuestionInterface;
import models.DifficultyLevel;
import java.util.Random;
public class MathQuestion implements QuestionInterface {
private String questionText;
private DifficultyLevel difficulty;
private Random random;
private boolean isValid;
public MathQuestion(DifficultyLevel difficulty) {
this.difficulty = difficulty;
this.random = new Random();
this.questionText = generateQuestion();
this.isValid = validateQuestion();
}
@Override
public String generateQuestion() {
StringBuilder question = new StringBuilder();
switch (difficulty) {
case PRIMARY:
question.append(generatePrimaryQuestion());
break;
case JUNIOR:
question.append(generateJuniorQuestion());
break;
case SENIOR:
question.append(generateSeniorQuestion());
break;
}
question.append(" = ");
return question.toString();
}
@Override
public boolean isValid() {
return isValid;
}
private boolean validateQuestion() {
if (questionText == null || questionText.trim().isEmpty()) {
return false;
}
// 检查括号是否匹配
if (!isParenthesesBalanced(questionText)) {
return false;
}
// 检查是否有不合理的括号位置(如运算符后面直接跟右括号)
if (hasInvalidParentheses(questionText)) {
return false;
}
// 小学题目必须至少有2个操作数
if (difficulty == DifficultyLevel.PRIMARY) {
String expr = questionText.replace(" = ", "");
// 更严格的验证:必须包含至少一个运算符
boolean hasOperator = expr.contains("+") || expr.contains("-") ||
expr.contains("*") || expr.contains("/");
// 并且不能是单个数字的情况
boolean isSingleNumber = expr.matches("^\\d+$") ||
expr.matches("^\\(\\d+\\)$") ||
expr.matches("^√\\d+$") ||
expr.matches("^\\(\\d+\\)²$");
return hasOperator && !isSingleNumber;
}
return true;
}
private boolean isParenthesesBalanced(String expression) {
int balance = 0;
for (char c : expression.toCharArray()) {
if (c == '(') balance++;
if (c == ')') balance--;
if (balance < 0) return false; // 右括号出现在左括号之前
}
return balance == 0;
}
private boolean hasInvalidParentheses(String expression) {
// 检查是否有不合理的括号模式
String[] invalidPatterns = {
"\\(\\s*[+\\-*/]", // 左括号后直接跟运算符
"[+\\-*/]\\s*\\)", // 运算符后直接跟右括号
"\\(\\s*\\)", // 空括号
"\\d\\s*\\(", // 数字后直接跟左括号(应该是运算符后跟左括号)
"\\)\\s*\\d" // 右括号后直接跟数字(应该是运算符后跟数字)
};
for (String pattern : invalidPatterns) {
if (expression.matches(".*" + pattern + ".*")) {
return true;
}
}
return false;
}
@Override
public String getQuestionText() {
return questionText;
}
@Override
public DifficultyLevel getDifficulty() {
return difficulty;
}
private String generatePrimaryQuestion() {
// 小学题目确保至少有2个操作数2-5个
int operandCount = random.nextInt(4) + 2; // 2-5个操作数
String[] operators = {"+", "-", "*", "/"};
StringBuilder question = new StringBuilder();
// 生成所有操作数
int[] operands = new int[operandCount];
for (int i = 0; i < operandCount; i++) {
operands[i] = random.nextInt(100) + 1;
}
// 构建基础表达式(不带括号)
question.append(operands[0]);
for (int i = 1; i < operandCount; i++) {
question.append(" ").append(operators[random.nextInt(operators.length)]).append(" ");
question.append(operands[i]);
}
// 只在有3个及以上操作数时考虑添加括号且概率降低
if (operandCount >= 3 && random.nextDouble() < 0.3) {
return addProperParentheses(question.toString());
}
return question.toString();
}
private String addProperParentheses(String expression) {
String[] parts = expression.split(" ");
// 只在合适的运算符位置添加括号
for (int attempt = 0; attempt < 10; attempt++) {
int opIndex = random.nextInt(parts.length / 2) * 2 + 1; // 随机选择一个运算符位置
if (opIndex >= 1 && opIndex < parts.length - 2) {
// 构建带括号的表达式
StringBuilder newExpr = new StringBuilder();
// 添加括号前的部分
for (int i = 0; i < opIndex - 1; i++) {
newExpr.append(parts[i]).append(" ");
}
// 添加左括号和第一个操作数
newExpr.append("(").append(parts[opIndex - 1]).append(" ");
// 添加运算符和第二个操作数
newExpr.append(parts[opIndex]).append(" ").append(parts[opIndex + 1]);
// 添加右括号
newExpr.append(")");
// 添加剩余部分
for (int i = opIndex + 2; i < parts.length; i++) {
newExpr.append(" ").append(parts[i]);
}
String result = newExpr.toString();
// 验证生成的表达式是否合理
if (!hasInvalidParentheses(result) && isParenthesesBalanced(result)) {
return result;
}
}
}
// 如果多次尝试都失败,返回原表达式(不带括号)
return expression;
}
private String generateJuniorQuestion() {
// 初中题目可以有1个操作数涉及平方、开根号
int choice = random.nextInt(4);
switch (choice) {
case 0:
// 单个操作数:开根号
return "√" + (random.nextInt(100) + 1);
case 1:
// 单个操作数:平方
return "(" + (random.nextInt(10) + 1) + ")²";
case 2:
// 多个操作数:基础运算 + 平方/开根号
String baseQuestion = generatePrimaryQuestion();
if (random.nextBoolean()) {
return "√" + (random.nextInt(100) + 1) + " + " + baseQuestion;
} else {
return "(" + (random.nextInt(10) + 1) + ")² + " + baseQuestion;
}
case 3:
// 纯基础运算(多个操作数)
return generatePrimaryQuestion();
default:
return generatePrimaryQuestion();
}
}
private String generateSeniorQuestion() {
// 高中题目可以有1个操作数涉及三角函数
int choice = random.nextInt(4);
String[] trigFunctions = {"sin", "cos", "tan"};
switch (choice) {
case 0:
// 单个操作数:三角函数
return trigFunctions[random.nextInt(trigFunctions.length)] +
"(" + (random.nextInt(90) + 1) + "°)";
case 1:
// 三角函数 + 基础运算
String baseQuestion = generatePrimaryQuestion();
return trigFunctions[random.nextInt(trigFunctions.length)] +
"(" + (random.nextInt(90) + 1) + "°) + " + baseQuestion;
case 2:
// 复杂组合:三角函数 + 平方/开根号 + 基础运算
String complexBase = generateJuniorQuestion();
return trigFunctions[random.nextInt(trigFunctions.length)] +
"(" + (random.nextInt(90) + 1) + "°) + " + complexBase;
case 3:
// 纯基础运算(多个操作数)
return generatePrimaryQuestion();
default:
return generatePrimaryQuestion();
}
}
}

@ -0,0 +1,43 @@
package services;
import interfaces.QuestionInterface;
import models.DifficultyLevel;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class QuestionGenerator {
private Random random;
private FileManager fileManager;
public QuestionGenerator() {
random = new Random();
fileManager = new FileManager();
}
public String[] generateQuestions(DifficultyLevel level, int count, String username) {
Set<String> existingQuestions = fileManager.loadExistingQuestions(username);
Set<String> newQuestions = new HashSet<>();
String[] questions = new String[count];
for (int i = 0; i < count; i++) {
QuestionInterface question;
int attempts = 0;
do {
question = new MathQuestion(level);
attempts++;
if (attempts > 100) {
return null;
}
} while (existingQuestions.contains(question.getQuestionText()) ||
newQuestions.contains(question.getQuestionText()) ||
!question.isValid());
newQuestions.add(question.getQuestionText());
questions[i] = (i + 1) + ". " + question.getQuestionText();
}
return questions;
}
}

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -1,140 +0,0 @@
package view;
import controller.ExamController;
import model.Question;
import javax.swing.*;
import java.awt.*;
import java.util.List;
public class ExamFrame extends JFrame {
private List<Question> questions;
private int current = 0;
private int[] answers;
private ButtonGroup group;
private JButton nextBtn;
private JButton prevBtn;
public ExamFrame(ExamController controller, List<Question> questions) {
this.questions = questions;
this.answers = new int[questions.size()];
for (int i = 0; i < answers.length; i++) answers[i] = -1;
setTitle("考试");
setSize(500, 300);
setLocationRelativeTo(null);
JPanel panel = new JPanel(new BorderLayout());
JLabel questionLabel = new JLabel();
group = new ButtonGroup();
JRadioButton[] options = new JRadioButton[4];
JPanel optionsPanel = new JPanel(new GridLayout(4, 1));
for (int i = 0; i < 4; i++) {
options[i] = new JRadioButton();
group.add(options[i]);
optionsPanel.add(options[i]);
int index = i;
options[i].addActionListener(e -> answers[current] = index);
}
prevBtn = new JButton("上一题");
nextBtn = new JButton("下一题");
JButton submit = new JButton("提交");
JPanel buttonPanel = new JPanel();
prevBtn.addActionListener(e -> showQuestion(current - 1, questionLabel, options));
nextBtn.addActionListener(e -> {
if (current == questions.size() - 1) {
// 已经是最后一题,提示用户
JOptionPane.showMessageDialog(this,
"已经是最后一题!\n请点击提交按钮完成考试。",
"提示",
JOptionPane.INFORMATION_MESSAGE);
} else {
showQuestion(current + 1, questionLabel, options);
}
});
submit.addActionListener(e -> {
// 检查是否有未答题目
int unanswered = 0;
for (int answer : answers) {
if (answer == -1) unanswered++;
}
String message;
if (unanswered > 0) {
message = "还有 " + unanswered + " 道题目未作答,确定要提交吗?";
} else {
message = "确定要提交试卷吗?";
}
// 确认提交对话框
int result = JOptionPane.showConfirmDialog(
this,
message,
"确认提交",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE
);
if (result == JOptionPane.YES_OPTION) {
int score = 0;
for (int i = 0; i < questions.size(); i++) {
if (answers[i] == questions.get(i).getCorrectAnswer()) score++;
}
controller.showResult(score, questions.size());
dispose();
}
});
buttonPanel.add(prevBtn);
buttonPanel.add(nextBtn);
buttonPanel.add(submit);
panel.add(questionLabel, BorderLayout.NORTH);
panel.add(optionsPanel, BorderLayout.CENTER);
panel.add(buttonPanel, BorderLayout.SOUTH);
add(panel);
showQuestion(0, questionLabel, options);
setVisible(true);
}
private void showQuestion(int index, JLabel label, JRadioButton[] options) {
if (index < 0 || index >= questions.size()) return;
current = index;
Question q = questions.get(index);
label.setText("第" + (index + 1) + "题: " + q.getContent() + " (" + (index + 1) + "/" + questions.size() + ")");
List<String> optionTexts = q.getOptions().getOptions();
// 先清空所有选项的选择状态
group.clearSelection();
// 设置选项文本,并根据当前题目的答案状态设置选择
for (int i = 0; i < 4; i++) {
options[i].setText(optionTexts.get(i));
if (answers[current] == i) {
options[i].setSelected(true);
}
}
// 更新按钮状态
updateButtonStates();
}
private void updateButtonStates() {
// 上一题按钮状态
prevBtn.setEnabled(current > 0);
// 下一题按钮状态
nextBtn.setEnabled(current < questions.size() - 1);
// 如果是最后一题,修改下一题按钮文本为提示
if (current == questions.size() - 1) {
nextBtn.setText("最后一题");
} else {
nextBtn.setText("下一题");
}
}
}

@ -1,46 +0,0 @@
package view;
import controller.AuthController;
import javax.swing.*;
import java.awt.*;
public class LoginFrame extends JFrame {
public LoginFrame(AuthController controller) {
setTitle("登录");
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridLayout(3, 2, 10, 10));
panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
JTextField emailField = new JTextField();
JPasswordField passwordField = new JPasswordField();
JButton loginBtn = new JButton("登录");
JButton registerBtn = new JButton("注册");
panel.add(new JLabel("邮箱:"));
panel.add(emailField);
panel.add(new JLabel("密码:"));
panel.add(passwordField);
panel.add(loginBtn);
panel.add(registerBtn);
loginBtn.addActionListener(e -> {
String email = emailField.getText();
String password = new String(passwordField.getPassword());
if (controller.login(email, password)) {
dispose();
} else {
JOptionPane.showMessageDialog(this, "登录失败");
}
});
registerBtn.addActionListener(e -> {
dispose();
controller.showRegister();
});
add(panel);
setVisible(true);
}
}

@ -1,105 +0,0 @@
package view;
import controller.MainController;
import javax.swing.*;
import java.awt.*;
public class MainFrame extends JFrame {
private MainController controller;
public MainFrame(MainController controller) {
this.controller = controller;
initializeWindow();
createComponents();
setVisible(true);
}
private void initializeWindow() {
setTitle("数学学习系统 - 主界面");
setSize(300, 250);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
}
private void createComponents() {
JPanel panel = new JPanel(new GridLayout(5, 1, 10, 10));
panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
JLabel titleLabel = new JLabel("选择考试难度", JLabel.CENTER);
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
JButton primaryBtn = new JButton("小学");
JButton middleBtn = new JButton("初中");
JButton highBtn = new JButton("高中");
JButton logoutBtn = new JButton("退出登录");
// 设置按钮字体
Font buttonFont = new Font("微软雅黑", Font.PLAIN, 14);
primaryBtn.setFont(buttonFont);
middleBtn.setFont(buttonFont);
highBtn.setFont(buttonFont);
logoutBtn.setFont(buttonFont);
// 设置按钮颜色
primaryBtn.setBackground(new Color(173, 216, 230)); // 浅蓝色
middleBtn.setBackground(new Color(144, 238, 144)); // 浅绿色
highBtn.setBackground(new Color(255, 182, 193)); // 浅粉色
logoutBtn.setBackground(new Color(240, 240, 240)); // 浅灰色
// 按钮事件监听
primaryBtn.addActionListener(e -> {
setVisible(false); // 隐藏主界面
controller.startExam("小学");
});
middleBtn.addActionListener(e -> {
setVisible(false); // 隐藏主界面
controller.startExam("初中");
});
highBtn.addActionListener(e -> {
setVisible(false); // 隐藏主界面
controller.startExam("高中");
});
logoutBtn.addActionListener(e -> {
int result = JOptionPane.showConfirmDialog(
this,
"确定要退出登录吗?",
"确认退出",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE
);
if (result == JOptionPane.YES_OPTION) {
controller.logout();
}
});
// 添加组件到面板
panel.add(titleLabel);
panel.add(primaryBtn);
panel.add(middleBtn);
panel.add(highBtn);
panel.add(logoutBtn);
add(panel);
}
/**
*
*/
public void showFrame() {
setVisible(true);
toFront(); // 确保窗口在前台
requestFocus(); // 请求焦点
}
/**
* dispose 退
*/
@Override
public void dispose() {
super.dispose();
}
}

@ -1,126 +0,0 @@
package view;
import controller.AuthController;
import javax.swing.*;
import java.awt.*;
public class RegisterFrame extends JFrame {
public RegisterFrame(AuthController controller) {
setTitle("注册");
setSize(400, 350);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
// 使用 GridBagLayout 更灵活布局
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5, 5, 5, 5);
JTextField emailField = new JTextField();
JTextField codeField = new JTextField();
JPasswordField passwordField = new JPasswordField();
JPasswordField confirmField = new JPasswordField();
JButton sendCodeBtn = new JButton("发送验证码");
JButton registerBtn = new JButton("注册");
JButton backBtn = new JButton("返回");
// 邮箱行
gbc.gridx = 0; gbc.gridy = 0;
panel.add(new JLabel("邮箱:"), gbc);
gbc.gridx = 1; gbc.gridy = 0; gbc.gridwidth = 2;
gbc.weightx = 1.0;
panel.add(emailField, gbc);
// 验证码行 - 修复布局
gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 1; gbc.weightx = 0;
panel.add(new JLabel("验证码:"), gbc);
gbc.gridx = 1; gbc.gridy = 1; gbc.weightx = 1.0;
panel.add(codeField, gbc);
gbc.gridx = 2; gbc.gridy = 1; gbc.weightx = 0;
gbc.fill = GridBagConstraints.NONE;
panel.add(sendCodeBtn, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL; // 恢复填充
// 密码行
gbc.gridx = 0; gbc.gridy = 2; gbc.gridwidth = 1; gbc.weightx = 0;
panel.add(new JLabel("密码:"), gbc);
gbc.gridx = 1; gbc.gridy = 2; gbc.gridwidth = 2; gbc.weightx = 1.0;
panel.add(passwordField, gbc);
// 确认密码行
gbc.gridx = 0; gbc.gridy = 3; gbc.gridwidth = 1; gbc.weightx = 0;
panel.add(new JLabel("确认密码:"), gbc);
gbc.gridx = 1; gbc.gridy = 3; gbc.gridwidth = 2; gbc.weightx = 1.0;
panel.add(confirmField, gbc);
// 按钮行 - 添加返回按钮
JPanel buttonPanel = new JPanel(new FlowLayout());
buttonPanel.add(registerBtn);
buttonPanel.add(backBtn);
gbc.gridx = 0; gbc.gridy = 4; gbc.gridwidth = 3;
gbc.weightx = 1.0;
panel.add(buttonPanel, gbc);
// 事件监听器
sendCodeBtn.addActionListener(e -> {
String email = emailField.getText().trim();
if (email.isEmpty()) {
JOptionPane.showMessageDialog(this, "请输入邮箱地址", "提示", JOptionPane.WARNING_MESSAGE);
return;
}
String code = controller.register(email);
if (code != null) {
codeField.setText(code);
JOptionPane.showMessageDialog(this, "验证码已发送: " + code, "验证码", JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(this, "邮箱已被注册或无效", "错误", JOptionPane.ERROR_MESSAGE);
}
});
registerBtn.addActionListener(e -> {
String email = emailField.getText().trim();
String code = codeField.getText().trim();
String password = new String(passwordField.getPassword());
String confirmPassword = new String(confirmField.getPassword());
// 输入验证
if (email.isEmpty() || code.isEmpty() || password.isEmpty()) {
JOptionPane.showMessageDialog(this, "请填写所有字段", "提示", JOptionPane.WARNING_MESSAGE);
return;
}
if (!password.equals(confirmPassword)) {
JOptionPane.showMessageDialog(this, "两次输入的密码不一致", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
boolean success = controller.completeRegistration(email, code, password, confirmPassword);
if (success) {
JOptionPane.showMessageDialog(this,
"注册成功!\n请使用注册的邮箱和密码登录",
"注册成功",
JOptionPane.INFORMATION_MESSAGE);
dispose();
controller.showLogin();
} else {
JOptionPane.showMessageDialog(this,
"注册失败!\n可能的原因\n- 验证码错误\n- 密码不符合要求6-10位包含大小写字母和数字\n- 邮箱已被注册",
"注册失败",
JOptionPane.ERROR_MESSAGE);
}
});
backBtn.addActionListener(e -> {
dispose();
controller.showLogin();
});
// 添加回车键提交支持
getRootPane().setDefaultButton(registerBtn);
add(panel);
setVisible(true);
}
}

@ -1,37 +0,0 @@
package view;
import controller.ExamController;
import javax.swing.*;
import java.awt.*;
public class ResultFrame extends JFrame {
public ResultFrame(ExamController controller, int score, int total) {
setTitle("考试结果");
setSize(250, 150);
setLocationRelativeTo(null);
JPanel panel = new JPanel(new BorderLayout());
JLabel label = new JLabel("得分: " + score + "/" + total, JLabel.CENTER);
JButton continueBtn = new JButton("继续做题");
JButton exitBtn = new JButton("退出");
continueBtn.addActionListener(e -> {
dispose();
controller.returnToMain();
});
exitBtn.addActionListener(e -> {
dispose();
controller.returnToMain();
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(continueBtn);
buttonPanel.add(exitBtn);
panel.add(label, BorderLayout.CENTER);
panel.add(buttonPanel, BorderLayout.SOUTH);
add(panel);
setVisible(true);
}
}

Binary file not shown.
Loading…
Cancel
Save