generatedQuestions = new HashSet<>();
+
+ for (int i = 0; i < count; i++) {
+ Question question;
+ int attempts = 0;
+ do {
+ question = generator.generateQuestion();
+ attempts++;
+ } while (generatedQuestions.contains(question.getContent()) && attempts < 10);
+
+ if (attempts < 10) {
+ currentExam.add(question);
+ generatedQuestions.add(question.getContent());
+ }
+ }
+
+ currentQuestionIndex = 0;
+ score = 0;
+
+ // 开始考试时重置选项状态
+ resetOptionButtons();
+ displayCurrentQuestion();
+ }
+
+ private void displayCurrentQuestion() {
+ if (currentQuestionIndex < currentExam.size()) {
+ Question question = currentExam.get(currentQuestionIndex);
+ questionLabel.setText("题目 " + (currentQuestionIndex + 1) + "/" +
+ currentExam.size() + "
" + question.getContent() + "
");
+
+ String[] options = question.getOptions();
+ for (int i = 0; i < 4; i++) {
+ optionButtons[i].setText((char)('A' + i) + ". " + options[i]);
+ }
+
+ // 重置选项状态
+ resetOptionButtons();
+ }
+ }
+
+ private void resetOptionButtons() {
+ if (optionGroup != null) {
+ optionGroup.clearSelection();
+ }
+ if (optionButtons != null) {
+ for (JRadioButton button : optionButtons) {
+ if (button != null) {
+ button.setSelected(false);
+ }
+ }
+ }
+ }
+
+ private void handleAnswerSubmission() {
+ int selectedIndex = -1;
+ for (int i = 0; i < 4; i++) {
+ if (optionButtons[i].isSelected()) {
+ selectedIndex = i;
+ break;
+ }
+ }
+
+ if (selectedIndex == -1) {
+ JOptionPane.showMessageDialog(mainPanel, "请选择一个答案");
+ return;
+ }
+
+ Question currentQuestion = currentExam.get(currentQuestionIndex);
+ if (selectedIndex == currentQuestion.getCorrectAnswer()) {
+ score++;
+ }
+
+ currentQuestionIndex++;
+
+ if (currentQuestionIndex < currentExam.size()) {
+ displayCurrentQuestion();
+ } else {
+ showScore();
+ }
+ }
+
+ private void showScore() {
+ int totalQuestions = currentExam.size();
+ int percentScore = (int) Math.round((double) score / totalQuestions * 100);
+
+ String comment;
+ Color color;
+ if (percentScore >= 90) {
+ comment = "优秀!";
+ color = new Color(0, 128, 0);
+ } else if (percentScore >= 80) {
+ comment = "良好!";
+ color = new Color(0, 100, 0);
+ } else if (percentScore >= 60) {
+ comment = "及格!";
+ color = new Color(218, 165, 32);
+ } else {
+ comment = "加油!";
+ color = new Color(220, 20, 60);
+ }
+
+ scoreLabel.setText("" +
+ "得分: " + percentScore + "分
" +
+ "(" + score + "/" + totalQuestions + ")
" +
+ "" + comment + "
");
+ cardLayout.show(mainPanel, "Score");
+ }
+
+ // 工具方法
+ private JButton createStyledButton(String text, Color color) {
+ JButton button = new JButton(text);
+ button.setFont(new Font("微软雅黑", Font.BOLD, 14));
+ button.setBackground(color);
+ button.setForeground(Color.WHITE);
+ button.setFocusPainted(false);
+ button.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
+ button.setCursor(new Cursor(Cursor.HAND_CURSOR));
+
+ button.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseEntered(java.awt.event.MouseEvent evt) {
+ button.setBackground(color.darker());
+ }
+ public void mouseExited(java.awt.event.MouseEvent evt) {
+ button.setBackground(color);
+ }
+ });
+
+ return button;
+ }
+
+ private JButton createLevelButton(String text, Color color) {
+ JButton button = new JButton(text);
+ button.setFont(new Font("微软雅黑", Font.BOLD, 18));
+ button.setBackground(color);
+ button.setForeground(Color.WHITE);
+ button.setFocusPainted(false);
+ button.setBorder(BorderFactory.createEmptyBorder(15, 0, 15, 0));
+ button.setCursor(new Cursor(Cursor.HAND_CURSOR));
+
+ button.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseEntered(java.awt.event.MouseEvent evt) {
+ button.setBackground(color.darker());
+ }
+ public void mouseExited(java.awt.event.MouseEvent evt) {
+ button.setBackground(color);
+ }
+ });
+
+ return button;
+ }
+
+ private String getHexColor(Color color) {
+ return String.format("#%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue());
+ }
+
+ private boolean isValidEmail(String email) {
+ String emailRegex = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
+ Pattern pattern = Pattern.compile(emailRegex);
+ return pattern.matcher(email).matches();
+ }
+
+ private boolean validatePassword(String password, String confirmPassword) {
+ if (!password.equals(confirmPassword)) {
+ JOptionPane.showMessageDialog(mainPanel, "两次输入的密码不一致");
+ return false;
+ }
+
+ return validatePasswordFormat(password);
+ }
+
+ private boolean validatePasswordFormat(String password) {
+ if (password.length() < 6 || password.length() > 10) {
+ JOptionPane.showMessageDialog(mainPanel, "密码长度应为6-10位");
+ return false;
+ }
+
+ boolean hasUpper = false, hasLower = false, 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;
+ }
+
+ if (!hasUpper || !hasLower || !hasDigit) {
+ JOptionPane.showMessageDialog(mainPanel, "密码必须包含大小写字母和数字");
+ return false;
+ }
+
+ return true;
+ }
+
+ private String generateVerificationCode() {
+ Random random = new Random();
+ return String.format("%06d", random.nextInt(1000000));
+ }
+
+ public static void main(String[] args) {
+ try {
+ UIManager.setLookAndFeel(UIManager.getLookAndFeel());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ SwingUtilities.invokeLater(() -> new MathLearningApp());
+ }
+}
\ No newline at end of file
diff --git a/src/user_data/users.dat b/src/user_data/users.dat
new file mode 100644
index 0000000..209d73f
Binary files /dev/null and b/src/user_data/users.dat differ
diff --git a/src/users.txt b/src/users.txt
new file mode 100644
index 0000000..3cdf169
--- /dev/null
+++ b/src/users.txt
@@ -0,0 +1,3 @@
+luguo:2830398107@qq.com:Qi1234
+测试用户:test@test.com:Test123
+示例用户:user@example.com:User123