package View; import Service.User_service; import Service.Exam_service; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class MainFrame extends JFrame { private User_service userService; private Exam_service examService; private CardLayout cardLayout; private JPanel mainPanel; // 登录面板组件 private JTextField loginEmailField; private JPasswordField loginPasswordField; // 注册面板组件 private JTextField regEmailField; private JTextField regCodeField; private JPasswordField regPasswordField; private JPasswordField regConfirmPasswordField; // 考试面板组件 private JLabel questionLabel; private JRadioButton[] optionButtons; private ButtonGroup optionGroup; private JLabel questionNumberLabel; private JLabel examInfoLabel; // 结果面板组件 private JLabel resultLabel; public MainFrame() { userService = new User_service(); examService = new Exam_service(); initializeUI(); } private void initializeUI() { setTitle("数学学习软件"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); setLocationRelativeTo(null); cardLayout = new CardLayout(); mainPanel = new JPanel(cardLayout); createLoginPanel(); createRegisterPanel(); createGradeSelectionPanel(); createExamPanel(); createResultPanel(); createPasswordChangePanel(); add(mainPanel); showLoginPanel(); } private void createLoginPanel() { JPanel panel = new JPanel(new BorderLayout(10, 10)); panel.setBorder(BorderFactory.createEmptyBorder(50, 100, 50, 100)); // 标题 JLabel titleLabel = new JLabel("数学学习软件", JLabel.CENTER); titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24)); panel.add(titleLabel, BorderLayout.NORTH); // 表单区域 JPanel formPanel = new JPanel(new GridLayout(3, 2, 15, 15)); formPanel.setBorder(BorderFactory.createEmptyBorder(30, 50, 30, 50)); formPanel.add(new JLabel("邮箱:", JLabel.RIGHT)); loginEmailField = new JTextField(); formPanel.add(loginEmailField); formPanel.add(new JLabel("密码:", JLabel.RIGHT)); loginPasswordField = new JPasswordField(); formPanel.add(loginPasswordField); panel.add(formPanel, BorderLayout.CENTER); // 按钮区域 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10)); JButton loginButton = createStyledButton("登录", new Color(70, 130, 180)); loginButton.addActionListener(e -> login()); buttonPanel.add(loginButton); JButton registerButton = createStyledButton("注册账号", new Color(60, 179, 113)); registerButton.addActionListener(e -> showRegisterPanel()); buttonPanel.add(registerButton); panel.add(buttonPanel, BorderLayout.SOUTH); mainPanel.add(panel, "Login"); } private void createRegisterPanel() { JPanel panel = new JPanel(new BorderLayout(10, 10)); panel.setBorder(BorderFactory.createEmptyBorder(30, 80, 30, 80)); JLabel titleLabel = new JLabel("用户注册", JLabel.CENTER); titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 20)); panel.add(titleLabel, BorderLayout.NORTH); JPanel formPanel = new JPanel(new GridLayout(5, 2, 15, 15)); formPanel.setBorder(BorderFactory.createEmptyBorder(20, 50, 20, 50)); formPanel.add(new JLabel("邮箱:", JLabel.RIGHT)); regEmailField = new JTextField(); formPanel.add(regEmailField); formPanel.add(new JLabel("验证码:", JLabel.RIGHT)); JPanel codePanel = new JPanel(new BorderLayout(5, 0)); regCodeField = new JTextField(); codePanel.add(regCodeField, BorderLayout.CENTER); JButton sendCodeButton = new JButton("发送验证码"); sendCodeButton.setFont(new Font("微软雅黑", Font.PLAIN, 10)); sendCodeButton.addActionListener(e -> sendVerificationCode()); codePanel.add(sendCodeButton, BorderLayout.EAST); formPanel.add(codePanel); formPanel.add(new JLabel("密码:", JLabel.RIGHT)); regPasswordField = new JPasswordField(); formPanel.add(regPasswordField); formPanel.add(new JLabel("确认密码:", JLabel.RIGHT)); regConfirmPasswordField = new JPasswordField(); formPanel.add(regConfirmPasswordField); panel.add(formPanel, BorderLayout.CENTER); JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10)); JButton registerButton = createStyledButton("注册", new Color(60, 179, 113)); registerButton.addActionListener(e -> register()); buttonPanel.add(registerButton); JButton backButton = createStyledButton("返回登录", new Color(192, 192, 192)); backButton.addActionListener(e -> showLoginPanel()); buttonPanel.add(backButton); panel.add(buttonPanel, BorderLayout.SOUTH); mainPanel.add(panel, "Register"); } private void createGradeSelectionPanel() { JPanel panel = new JPanel(new BorderLayout(10, 10)); panel.setBorder(BorderFactory.createEmptyBorder(50, 100, 50, 100)); JLabel titleLabel = new JLabel("选择学习阶段", JLabel.CENTER); titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24)); panel.add(titleLabel, BorderLayout.NORTH); JPanel gradePanel = new JPanel(new GridLayout(4, 1, 20, 20)); gradePanel.setBorder(BorderFactory.createEmptyBorder(50, 100, 50, 100)); JButton primaryButton = createGradeButton("小学", new Color(255, 182, 193)); primaryButton.addActionListener(e -> startExam(0, "小学")); gradePanel.add(primaryButton); JButton juniorButton = createGradeButton("初中", new Color(135, 206, 250)); juniorButton.addActionListener(e -> startExam(1, "初中")); gradePanel.add(juniorButton); JButton seniorButton = createGradeButton("高中", new Color(152, 251, 152)); seniorButton.addActionListener(e -> startExam(2, "高中")); gradePanel.add(seniorButton); panel.add(gradePanel, BorderLayout.CENTER); JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10)); JButton changePasswordButton = createStyledButton("修改密码", new Color(255, 165, 0)); changePasswordButton.addActionListener(e -> showPasswordChangePanel()); bottomPanel.add(changePasswordButton); JButton logoutButton = createStyledButton("退出登录", new Color(220, 20, 60)); logoutButton.addActionListener(e -> logout()); bottomPanel.add(logoutButton); panel.add(bottomPanel, BorderLayout.SOUTH); mainPanel.add(panel, "GradeSelection"); } private void createExamPanel() { JPanel panel = new JPanel(new BorderLayout(10, 10)); panel.setBorder(BorderFactory.createEmptyBorder(20, 40, 20, 40)); // 顶部信息栏 JPanel topPanel = new JPanel(new BorderLayout()); questionNumberLabel = new JLabel("", JLabel.LEFT); questionNumberLabel.setFont(new Font("微软雅黑", Font.BOLD, 16)); examInfoLabel = new JLabel("", JLabel.RIGHT); examInfoLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14)); topPanel.add(questionNumberLabel, BorderLayout.WEST); topPanel.add(examInfoLabel, BorderLayout.EAST); panel.add(topPanel, BorderLayout.NORTH); // 题目区域 JPanel questionPanel = new JPanel(new BorderLayout(10, 20)); questionPanel.setBorder(BorderFactory.createEmptyBorder(30, 50, 30, 50)); questionLabel = new JLabel("", JLabel.CENTER); questionLabel.setFont(new Font("微软雅黑", Font.PLAIN, 18)); questionPanel.add(questionLabel, BorderLayout.NORTH); // 选项区域 JPanel optionsPanel = new JPanel(new GridLayout(4, 1, 10, 10)); optionsPanel.setBorder(BorderFactory.createEmptyBorder(20, 100, 20, 100)); optionButtons = new JRadioButton[4]; optionGroup = new ButtonGroup(); String[] optionLabels = {"A. ", "B. ", "C. ", "D. "}; for (int i = 0; i < 4; i++) { JPanel optionPanel = new JPanel(new BorderLayout()); optionButtons[i] = new JRadioButton(); optionButtons[i].setFont(new Font("微软雅黑", Font.PLAIN, 16)); optionGroup.add(optionButtons[i]); JLabel optionLabel = new JLabel(optionLabels[i]); optionLabel.setFont(new Font("微软雅黑", Font.BOLD, 16)); optionLabel.setPreferredSize(new Dimension(30, 25)); optionPanel.add(optionLabel, BorderLayout.WEST); optionPanel.add(optionButtons[i], BorderLayout.CENTER); optionsPanel.add(optionPanel); } questionPanel.add(optionsPanel, BorderLayout.CENTER); panel.add(questionPanel, BorderLayout.CENTER); // 提交按钮 JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); JButton submitButton = createStyledButton("提交答案", new Color(70, 130, 180)); submitButton.addActionListener(e -> submitAnswer()); bottomPanel.add(submitButton); panel.add(bottomPanel, BorderLayout.SOUTH); mainPanel.add(panel, "Exam"); } private void createResultPanel() { JPanel panel = new JPanel(new BorderLayout(10, 10)); panel.setBorder(BorderFactory.createEmptyBorder(50, 100, 50, 100)); resultLabel = new JLabel("", JLabel.CENTER); resultLabel.setFont(new Font("微软雅黑", Font.BOLD, 24)); panel.add(resultLabel, BorderLayout.CENTER); JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 30, 20)); JButton continueButton = createStyledButton("继续做题", new Color(60, 179, 113)); continueButton.addActionListener(e -> showGradeSelectionPanel()); JButton exitButton = createStyledButton("退出程序", new Color(220, 20, 60)); exitButton.addActionListener(e -> System.exit(0)); buttonPanel.add(continueButton); buttonPanel.add(exitButton); panel.add(buttonPanel, BorderLayout.SOUTH); mainPanel.add(panel, "Result"); } private void createPasswordChangePanel() { JPanel panel = new JPanel(new BorderLayout(10, 10)); panel.setBorder(BorderFactory.createEmptyBorder(50, 100, 50, 100)); JLabel titleLabel = new JLabel("修改密码", JLabel.CENTER); titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 20)); panel.add(titleLabel, BorderLayout.NORTH); JPanel formPanel = new JPanel(new GridLayout(4, 2, 15, 15)); formPanel.setBorder(BorderFactory.createEmptyBorder(30, 80, 30, 80)); formPanel.add(new JLabel("原密码:", JLabel.RIGHT)); JPasswordField oldPasswordField = new JPasswordField(); formPanel.add(oldPasswordField); formPanel.add(new JLabel("新密码:", JLabel.RIGHT)); JPasswordField newPasswordField = new JPasswordField(); formPanel.add(newPasswordField); formPanel.add(new JLabel("确认新密码:", JLabel.RIGHT)); JPasswordField confirmPasswordField = new JPasswordField(); formPanel.add(confirmPasswordField); panel.add(formPanel, BorderLayout.CENTER); JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10)); JButton changeButton = createStyledButton("确认修改", new Color(60, 179, 113)); changeButton.addActionListener(e -> { String oldPassword = new String(oldPasswordField.getPassword()); String newPassword = new String(newPasswordField.getPassword()); String confirmPassword = new String(confirmPasswordField.getPassword()); changePassword(oldPassword, newPassword, confirmPassword); }); buttonPanel.add(changeButton); JButton backButton = createStyledButton("返回", new Color(192, 192, 192)); backButton.addActionListener(e -> showGradeSelectionPanel()); buttonPanel.add(backButton); panel.add(buttonPanel, BorderLayout.SOUTH); mainPanel.add(panel, "PasswordChange"); } // 工具方法:创建样式化按钮 private JButton createStyledButton(String text, Color bgColor) { JButton button = new JButton(text); button.setFont(new Font("微软雅黑", Font.BOLD, 14)); button.setBackground(bgColor); button.setForeground(Color.WHITE); button.setFocusPainted(false); button.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20)); return button; } // 工具方法:创建年级选择按钮 private JButton createGradeButton(String text, Color bgColor) { JButton button = new JButton(text); button.setFont(new Font("微软雅黑", Font.BOLD, 18)); button.setBackground(bgColor); button.setForeground(Color.BLACK); button.setFocusPainted(false); button.setBorder(BorderFactory.createEmptyBorder(20, 0, 20, 0)); return button; } // 界面显示方法 private void showLoginPanel() { loginEmailField.setText(""); loginPasswordField.setText(""); cardLayout.show(mainPanel, "Login"); } private void showRegisterPanel() { regEmailField.setText(""); regCodeField.setText(""); regPasswordField.setText(""); regConfirmPasswordField.setText(""); cardLayout.show(mainPanel, "Register"); } private void showGradeSelectionPanel() { cardLayout.show(mainPanel, "GradeSelection"); } private void showPasswordChangePanel() { cardLayout.show(mainPanel, "PasswordChange"); } // 业务逻辑方法 private void login() { String email = loginEmailField.getText().trim(); String password = new String(loginPasswordField.getPassword()); if (email.isEmpty() || password.isEmpty()) { JOptionPane.showMessageDialog(this, "请输入邮箱和密码"); return; } if (userService.login(email, password)) { showGradeSelectionPanel(); } else { JOptionPane.showMessageDialog(this, "登录失败,请检查邮箱和密码"); } } private void sendVerificationCode() { String email = regEmailField.getText().trim(); if (email.isEmpty()) { JOptionPane.showMessageDialog(this, "请输入邮箱地址"); return; } if (userService.sendVerificationCode(email)) { JOptionPane.showMessageDialog(this, "验证码已发送到您的邮箱,请查收"); } else { JOptionPane.showMessageDialog(this, "验证码发送失败,请检查邮箱地址或稍后重试"); } } private void register() { String email = regEmailField.getText().trim(); String code = regCodeField.getText().trim(); String password = new String(regPasswordField.getPassword()); String confirmPassword = new String(regConfirmPasswordField.getPassword()); if (email.isEmpty() || code.isEmpty() || password.isEmpty()) { JOptionPane.showMessageDialog(this, "请填写所有字段"); return; } if (!password.equals(confirmPassword)) { JOptionPane.showMessageDialog(this, "两次输入的密码不一致"); return; } if (userService.completeRegistration(email, code, password)) { JOptionPane.showMessageDialog(this, "注册成功,请登录"); showLoginPanel(); } else { JOptionPane.showMessageDialog(this, "注册失败,请检查验证码和密码格式\n密码要求:6-10位,包含大小写字母和数字"); } } private void startExam(int gradeLevel, String gradeName) { String input = JOptionPane.showInputDialog(this, "请输入" + gradeName + "题目数量:", "题目数量", JOptionPane.QUESTION_MESSAGE); if (input == null) return; // 用户取消 try { int count = Integer.parseInt(input.trim()); if (count <= 0) { JOptionPane.showMessageDialog(this, "题目数量必须大于0"); return; } if (count > 100) { JOptionPane.showMessageDialog(this, "题目数量不能超过100"); return; } examService.startExam(gradeLevel, count); showNextQuestion(); cardLayout.show(mainPanel, "Exam"); } catch (NumberFormatException e) { JOptionPane.showMessageDialog(this, "请输入有效的数字"); } } private void showNextQuestion() { Question question = examService.getCurrentQuestion(); if (question != null) { questionNumberLabel.setText(String.format("第 %d 题 / 共 %d 题", examService.getCurrentQuestionNumber(), examService.getTotalQuestions())); examInfoLabel.setText(getGradeName(question.getGradeLevel()) + "数学题"); questionLabel.setText("
正确题数: %d / %d
" + "得分: %.1f
" + "