Compare commits
21 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
28b584c7e7 | 4 months ago |
|
|
f61c588820 | 4 months ago |
|
|
951d6d1e15 | 4 months ago |
|
|
57dc81e7b0 | 4 months ago |
|
|
fcce80de1f | 4 months ago |
|
|
2ddabaca53 | 4 months ago |
|
|
670feecce6 | 4 months ago |
|
|
fc131d7b29 | 4 months ago |
|
|
0c37bda31f | 4 months ago |
|
|
b4ac017ae5 | 4 months ago |
|
|
824a8e3a3d | 4 months ago |
|
|
17b0628e14 | 4 months ago |
|
|
cadb4b2c60 | 4 months ago |
|
|
69b6a3083a | 4 months ago |
|
|
5e7c448b39 | 4 months ago |
|
|
68bcd630ce | 4 months ago |
|
|
f4f7c0489c | 4 months ago |
|
|
7af6a3e1fb | 4 months ago |
|
|
9b6d063530 | 4 months ago |
|
|
fe84f95967 | 4 months ago |
|
|
d6d726ad6f | 4 months ago |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,10 @@
|
||||
import controller.MainController;
|
||||
import javax.swing.*;
|
||||
|
||||
public class MathLearningApp {
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
new MainController().showLogin();
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
|
||||
import service.QuestionService;
|
||||
import model.Question;
|
||||
import service.OptionsResult;
|
||||
import java.util.List;
|
||||
|
||||
class Test {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== 测试题目生成 ===\n");
|
||||
|
||||
QuestionService questionService = new QuestionService();
|
||||
List<Question> questions = questionService.generateQuestions("高中", 30);
|
||||
|
||||
for (int i = 0; i < questions.size(); i++) {
|
||||
Question question = questions.get(i);
|
||||
System.out.println((i + 1) + ". " + question.getContent());
|
||||
|
||||
// 通过 OptionsResult 获取选项列表
|
||||
OptionsResult optionsResult = question.getOptions();
|
||||
List<String> options = optionsResult.getOptions();
|
||||
|
||||
System.out.print(" 选项: ");
|
||||
for (int j = 0; j < options.size(); j++) {
|
||||
char optionChar = (char) ('A' + j);
|
||||
System.out.print(optionChar + "." + options.get(j) + " ");
|
||||
}
|
||||
|
||||
char correctChar = (char) ('A' + optionsResult.getCorrectIndex());
|
||||
System.out.println(" [答案:" + correctChar + "]");
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
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;
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Exam {
|
||||
private List<Question> questions;
|
||||
private String difficulty;
|
||||
|
||||
public Exam(List<Question> questions, String difficulty) {
|
||||
this.questions = questions;
|
||||
this.difficulty = difficulty;
|
||||
}
|
||||
|
||||
public List<Question> getQuestions() {
|
||||
return questions;
|
||||
}
|
||||
|
||||
public String getDifficulty() {
|
||||
return difficulty;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package model;
|
||||
|
||||
import java.util.List;
|
||||
import service.OptionsResult;
|
||||
|
||||
public class Question {
|
||||
private String content;
|
||||
private OptionsResult options;
|
||||
private int correctPos;
|
||||
private String difficulty;
|
||||
|
||||
public Question(String content, OptionsResult options, int correctPos, String difficulty) {
|
||||
this.content = content;
|
||||
this.options = options;
|
||||
this.correctPos = correctPos;
|
||||
this.difficulty = difficulty;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public OptionsResult getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public int getCorrectAnswer() {
|
||||
return correctPos;
|
||||
}
|
||||
|
||||
public String getDifficulty() {
|
||||
return difficulty;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class User implements Serializable {
|
||||
private String email;
|
||||
private String password;
|
||||
private String registrationCode;
|
||||
private boolean isRegistered;
|
||||
|
||||
public User(String email, String registrationCode) {
|
||||
this.email = email;
|
||||
this.registrationCode = registrationCode;
|
||||
this.isRegistered = false;
|
||||
this.password = null;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getRegistrationCode() {
|
||||
return registrationCode;
|
||||
}
|
||||
|
||||
public boolean isRegistered() {
|
||||
return isRegistered;
|
||||
}
|
||||
|
||||
public void setRegistered(boolean registered) {
|
||||
isRegistered = registered;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package service;
|
||||
|
||||
import model.Question;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
public abstract class AbstractQuestionGenerator implements QuestionGenerator {
|
||||
protected String difficulty;
|
||||
protected Random random = new Random();
|
||||
|
||||
public AbstractQuestionGenerator(String difficulty) {
|
||||
this.difficulty = difficulty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionsResult generateOptions(int correct) {
|
||||
List<String> options = new ArrayList<>();
|
||||
Set<Integer> used = new HashSet<>();
|
||||
used.add(correct);
|
||||
|
||||
// 先生成3个错误选项
|
||||
while (options.size() < 3) {
|
||||
int wrong = correct + (int)(Math.random() * 10) - 5;
|
||||
if (!used.contains(wrong) && wrong != correct) {
|
||||
options.add(String.valueOf(wrong));
|
||||
used.add(wrong);
|
||||
}
|
||||
}
|
||||
// 在随机位置插入正确答案
|
||||
int correctPosition = (int)(Math.random() * 4); // 0-3的随机位置
|
||||
options.add(correctPosition, String.valueOf(correct));
|
||||
|
||||
return new OptionsResult(options, correctPosition);
|
||||
}
|
||||
|
||||
public String getDifficulty() {
|
||||
return difficulty;
|
||||
}
|
||||
|
||||
protected int getRandomOperand() {
|
||||
return random.nextInt(20)+1;
|
||||
}
|
||||
|
||||
protected String getRandomOperator(String[] operators) {
|
||||
return operators[random.nextInt(operators.length)];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class OptionsResult {
|
||||
private List<String> options;
|
||||
private int correctIndex;
|
||||
|
||||
public OptionsResult(List<String> options, int correctIndex) {
|
||||
this.options = options;
|
||||
this.correctIndex = correctIndex;
|
||||
}
|
||||
|
||||
public List<String> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public int getCorrectIndex() {
|
||||
return correctIndex;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package service;
|
||||
|
||||
import model.Question;
|
||||
import java.util.List;
|
||||
|
||||
public interface QuestionGenerator {
|
||||
Question generateQuestion();
|
||||
OptionsResult generateOptions(int correctAnswer);
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class QuestionGeneratorFactory {
|
||||
private static final Map<String, QuestionGenerator> generators = new HashMap<>();
|
||||
|
||||
static {
|
||||
generators.put("小学", new PrimaryQuestionGenerator());
|
||||
generators.put("初中", new MiddleSchoolQuestionGenerator());
|
||||
generators.put("高中", new HighSchoolQuestionGenerator());
|
||||
}
|
||||
|
||||
public static QuestionGenerator getGenerator(String difficulty) {
|
||||
return generators.getOrDefault(difficulty, generators.get("小学"));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package service;
|
||||
|
||||
import model.Question;
|
||||
import java.util.*;
|
||||
|
||||
public class QuestionService {
|
||||
/*生成试卷的题目部分*/
|
||||
public List<Question> generateQuestions(String difficulty, int count) {
|
||||
if(count < 10 || count > 30) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Question> questions = new ArrayList<>();
|
||||
Set<String> usedQuestions = new HashSet<>();
|
||||
QuestionGenerator generator = QuestionGeneratorFactory.getGenerator(difficulty);
|
||||
|
||||
while (questions.size() < count) {
|
||||
Question q = generator.generateQuestion();
|
||||
if (usedQuestions.add(q.getContent())) {
|
||||
questions.add(q);
|
||||
}
|
||||
}
|
||||
return questions;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package service;
|
||||
|
||||
import model.User;
|
||||
import utils.FileStorage;
|
||||
import utils.PasswordValidator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class UserService {
|
||||
private Map<String, User> users = new HashMap<>();
|
||||
private FileStorage fileStorage = new FileStorage();
|
||||
|
||||
public UserService() {
|
||||
users = fileStorage.loadUsers(); //加载所有已有的用户
|
||||
}
|
||||
|
||||
/*注册用户第一阶段-生成验证码*/
|
||||
public String registerUser(String email) {
|
||||
if (users.containsKey(email) && users.get(email).isRegistered()){
|
||||
return "registered"; //注册过的用户不能再注册
|
||||
//return null;
|
||||
}
|
||||
if (users.containsKey(email)) {
|
||||
return "recheck your email"; //已发过验证码也不再发了
|
||||
//return null;
|
||||
}
|
||||
String code = String.valueOf(100000 + (int)(Math.random() * 900000)); //生成6位注册码
|
||||
users.put(email, new User(email, code));
|
||||
fileStorage.saveUsers(users);
|
||||
return code;
|
||||
}
|
||||
|
||||
/*注册用户第二阶段-完成注册*/
|
||||
public boolean completeRegistration(String email, String code, String password) {
|
||||
User user = users.get(email);
|
||||
if (user != null && user.getRegistrationCode().equals(code) && PasswordValidator.isValid(password)) {
|
||||
user.setPassword(password);
|
||||
user.setRegistered(true);
|
||||
fileStorage.saveUsers(users);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*用户登录*/
|
||||
public boolean login(String email, String password) {
|
||||
User user = users.get(email);
|
||||
return user != null && user.isRegistered() && user.getPassword().equals(password);
|
||||
}
|
||||
|
||||
/*修改密码*/
|
||||
public boolean changePassword(String email, String oldPassword, String newPassword) {
|
||||
User user = users.get(email);
|
||||
if (user != null && user.getPassword().equals(oldPassword) && PasswordValidator.isValid(newPassword)) {
|
||||
user.setPassword(newPassword);
|
||||
fileStorage.saveUsers(users);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package utils;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class EmailValidator {
|
||||
private static final Pattern EMAIL_PATTERN = Pattern.compile("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$");
|
||||
|
||||
/*只检查邮箱的格式是否正确,但不保证这个邮箱存在*/
|
||||
public static boolean isValid(String email) {
|
||||
return email != null && EMAIL_PATTERN.matcher(email).matches();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package utils;
|
||||
|
||||
import model.User;
|
||||
import java.io.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class FileStorage {
|
||||
/*完全擦除原来的文件并重新写入*/
|
||||
public void saveUsers(Map<String, User> users) {
|
||||
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("users.dat"))) {
|
||||
oos.writeObject(users);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*从文件中载入*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, User> loadUsers() {
|
||||
File file = new File("users.dat");
|
||||
if (!file.exists()) return new HashMap<>();
|
||||
|
||||
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("users.dat"))) {
|
||||
return (Map<String, User>) ois.readObject();
|
||||
} catch (Exception e) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package utils;
|
||||
|
||||
public class PasswordValidator {
|
||||
public static boolean isValid(String password) {
|
||||
if (password == null || password.length() < 6 || password.length() > 10) {
|
||||
return false;
|
||||
}
|
||||
boolean hasUpper = false;
|
||||
boolean hasLower = false;
|
||||
boolean hasDigit = false;
|
||||
for (char c : password.toCharArray()) {
|
||||
if (Character.isUpperCase(c)) hasUpper = true;
|
||||
if (Character.isLowerCase(c)) hasLower = true;
|
||||
if (Character.isDigit(c)) hasDigit = true;
|
||||
}
|
||||
return hasUpper && hasLower && hasDigit;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,140 @@
|
||||
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("考试 - 共" + questions.size() + "题");
|
||||
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("下一题");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
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(300, 200);
|
||||
setLocationRelativeTo(null);
|
||||
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
|
||||
// 创建结果信息面板
|
||||
JPanel resultPanel = new JPanel(new GridLayout(3, 1));
|
||||
JLabel scoreLabel = new JLabel("得分: " + score + "/" + total, JLabel.CENTER);
|
||||
JLabel totalLabel = new JLabel("总题数: " + total + "题", JLabel.CENTER);
|
||||
double percentage = (double) score / total * 100;
|
||||
JLabel percentageLabel = new JLabel(String.format("正确率: %.1f%%", percentage), JLabel.CENTER);
|
||||
|
||||
// 设置字体
|
||||
Font boldFont = new Font("微软雅黑", Font.BOLD, 16);
|
||||
scoreLabel.setFont(boldFont);
|
||||
totalLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
||||
percentageLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
||||
|
||||
resultPanel.add(scoreLabel);
|
||||
resultPanel.add(totalLabel);
|
||||
resultPanel.add(percentageLabel);
|
||||
|
||||
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(resultPanel, BorderLayout.CENTER);
|
||||
panel.add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
add(panel);
|
||||
setVisible(true);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue