|
|
|
|
@ -2,50 +2,47 @@ package View;
|
|
|
|
|
|
|
|
|
|
import Service.User_service;
|
|
|
|
|
import Service.Exam_service;
|
|
|
|
|
import Base.Exam_result;
|
|
|
|
|
import Base.Question;
|
|
|
|
|
|
|
|
|
|
import javax.swing.*;
|
|
|
|
|
import java.awt.*;
|
|
|
|
|
import java.awt.event.ActionEvent;
|
|
|
|
|
import java.awt.event.ActionListener;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
public class MainFrame extends JFrame {
|
|
|
|
|
private User_service userService;
|
|
|
|
|
private final User_service userService;
|
|
|
|
|
private Exam_service examService;
|
|
|
|
|
private CardLayout cardLayout;
|
|
|
|
|
private JPanel mainPanel;
|
|
|
|
|
private String currentUserId;
|
|
|
|
|
|
|
|
|
|
// 登录面板组件
|
|
|
|
|
private JTextField loginEmailField;
|
|
|
|
|
// UI组件字段
|
|
|
|
|
private JTextField loginIdField;
|
|
|
|
|
private JPasswordField loginPasswordField;
|
|
|
|
|
|
|
|
|
|
// 注册面板组件
|
|
|
|
|
private JTextField regEmailField;
|
|
|
|
|
private JTextField regCodeField;
|
|
|
|
|
private JPasswordField regPasswordField;
|
|
|
|
|
private JPasswordField regConfirmPasswordField;
|
|
|
|
|
|
|
|
|
|
// 考试面板组件
|
|
|
|
|
private JTextField regUserIdField;
|
|
|
|
|
private JLabel questionLabel;
|
|
|
|
|
private JRadioButton[] optionButtons;
|
|
|
|
|
private ButtonGroup optionGroup;
|
|
|
|
|
private JLabel questionNumberLabel;
|
|
|
|
|
private JLabel examInfoLabel;
|
|
|
|
|
|
|
|
|
|
// 结果面板组件
|
|
|
|
|
private JButton prevButton;
|
|
|
|
|
private JButton nextButton;
|
|
|
|
|
private JButton submitButton;
|
|
|
|
|
private JLabel resultLabel;
|
|
|
|
|
|
|
|
|
|
public MainFrame() {
|
|
|
|
|
userService = new User_service();
|
|
|
|
|
examService = new Exam_service();
|
|
|
|
|
initializeUI();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initializeUI() {
|
|
|
|
|
setTitle("数学学习软件");
|
|
|
|
|
setTitle("数学学习系统");
|
|
|
|
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
|
|
|
setSize(800, 600);
|
|
|
|
|
setLocationRelativeTo(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initializeUI() {
|
|
|
|
|
cardLayout = new CardLayout();
|
|
|
|
|
mainPanel = new JPanel(cardLayout);
|
|
|
|
|
|
|
|
|
|
@ -54,6 +51,7 @@ public class MainFrame extends JFrame {
|
|
|
|
|
createGradeSelectionPanel();
|
|
|
|
|
createExamPanel();
|
|
|
|
|
createResultPanel();
|
|
|
|
|
createWrongQuestionsPanel(); // 新增错题面板
|
|
|
|
|
createPasswordChangePanel();
|
|
|
|
|
|
|
|
|
|
add(mainPanel);
|
|
|
|
|
@ -64,36 +62,37 @@ public class MainFrame extends JFrame {
|
|
|
|
|
JPanel panel = new JPanel(new BorderLayout(10, 10));
|
|
|
|
|
panel.setBorder(BorderFactory.createEmptyBorder(50, 100, 50, 100));
|
|
|
|
|
|
|
|
|
|
// 标题
|
|
|
|
|
JLabel titleLabel = new JLabel("数学学习软件", JLabel.CENTER);
|
|
|
|
|
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.CENTER));
|
|
|
|
|
loginIdField = new JTextField();
|
|
|
|
|
formPanel.add(loginIdField);
|
|
|
|
|
|
|
|
|
|
formPanel.add(new JLabel("密码:", JLabel.RIGHT));
|
|
|
|
|
formPanel.add(new JLabel("密码:", JLabel.CENTER));
|
|
|
|
|
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));
|
|
|
|
|
JButton loginButton = createStyledButton("登录");
|
|
|
|
|
loginButton.addActionListener(e -> login());
|
|
|
|
|
buttonPanel.add(loginButton);
|
|
|
|
|
|
|
|
|
|
JButton registerButton = createStyledButton("注册账号", new Color(60, 179, 113));
|
|
|
|
|
JButton registerButton = createStyledButton("注册账号");
|
|
|
|
|
registerButton.addActionListener(e -> showRegisterPanel());
|
|
|
|
|
buttonPanel.add(registerButton);
|
|
|
|
|
|
|
|
|
|
JButton exitButton = createStyledButton("退出");
|
|
|
|
|
exitButton.addActionListener(e -> exitchoice());
|
|
|
|
|
buttonPanel.add(exitButton);
|
|
|
|
|
|
|
|
|
|
panel.add(buttonPanel, BorderLayout.SOUTH);
|
|
|
|
|
|
|
|
|
|
mainPanel.add(panel, "Login");
|
|
|
|
|
@ -110,11 +109,11 @@ public class MainFrame extends JFrame {
|
|
|
|
|
JPanel formPanel = new JPanel(new GridLayout(5, 2, 15, 15));
|
|
|
|
|
formPanel.setBorder(BorderFactory.createEmptyBorder(20, 50, 20, 50));
|
|
|
|
|
|
|
|
|
|
formPanel.add(new JLabel("邮箱:", JLabel.RIGHT));
|
|
|
|
|
formPanel.add(new JLabel("邮箱:", JLabel.CENTER));
|
|
|
|
|
regEmailField = new JTextField();
|
|
|
|
|
formPanel.add(regEmailField);
|
|
|
|
|
|
|
|
|
|
formPanel.add(new JLabel("验证码:", JLabel.RIGHT));
|
|
|
|
|
formPanel.add(new JLabel("验证码:", JLabel.CENTER));
|
|
|
|
|
JPanel codePanel = new JPanel(new BorderLayout(5, 0));
|
|
|
|
|
regCodeField = new JTextField();
|
|
|
|
|
codePanel.add(regCodeField, BorderLayout.CENTER);
|
|
|
|
|
@ -125,23 +124,27 @@ public class MainFrame extends JFrame {
|
|
|
|
|
codePanel.add(sendCodeButton, BorderLayout.EAST);
|
|
|
|
|
formPanel.add(codePanel);
|
|
|
|
|
|
|
|
|
|
formPanel.add(new JLabel("密码:", JLabel.RIGHT));
|
|
|
|
|
formPanel.add(new JLabel("密码:", JLabel.CENTER));
|
|
|
|
|
regPasswordField = new JPasswordField();
|
|
|
|
|
formPanel.add(regPasswordField);
|
|
|
|
|
|
|
|
|
|
formPanel.add(new JLabel("确认密码:", JLabel.RIGHT));
|
|
|
|
|
formPanel.add(new JLabel("确认密码:", JLabel.CENTER));
|
|
|
|
|
regConfirmPasswordField = new JPasswordField();
|
|
|
|
|
formPanel.add(regConfirmPasswordField);
|
|
|
|
|
|
|
|
|
|
formPanel.add(new JLabel("用户名:", JLabel.CENTER));
|
|
|
|
|
regUserIdField = new JTextField();
|
|
|
|
|
formPanel.add(regUserIdField);
|
|
|
|
|
|
|
|
|
|
panel.add(formPanel, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
|
|
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10));
|
|
|
|
|
|
|
|
|
|
JButton registerButton = createStyledButton("注册", new Color(60, 179, 113));
|
|
|
|
|
JButton registerButton = createStyledButton("注册");
|
|
|
|
|
registerButton.addActionListener(e -> register());
|
|
|
|
|
buttonPanel.add(registerButton);
|
|
|
|
|
|
|
|
|
|
JButton backButton = createStyledButton("返回登录", new Color(192, 192, 192));
|
|
|
|
|
JButton backButton = createStyledButton("返回登录");
|
|
|
|
|
backButton.addActionListener(e -> showLoginPanel());
|
|
|
|
|
buttonPanel.add(backButton);
|
|
|
|
|
|
|
|
|
|
@ -161,27 +164,33 @@ public class MainFrame extends JFrame {
|
|
|
|
|
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, "小学"));
|
|
|
|
|
JButton primaryButton = createGradeButton("小学");
|
|
|
|
|
primaryButton.addActionListener(e -> startExam("小学"));
|
|
|
|
|
gradePanel.add(primaryButton);
|
|
|
|
|
|
|
|
|
|
JButton juniorButton = createGradeButton("初中", new Color(135, 206, 250));
|
|
|
|
|
juniorButton.addActionListener(e -> startExam(1, "初中"));
|
|
|
|
|
JButton juniorButton = createGradeButton("初中");
|
|
|
|
|
juniorButton.addActionListener(e -> startExam("初中"));
|
|
|
|
|
gradePanel.add(juniorButton);
|
|
|
|
|
|
|
|
|
|
JButton seniorButton = createGradeButton("高中", new Color(152, 251, 152));
|
|
|
|
|
seniorButton.addActionListener(e -> startExam(2, "高中"));
|
|
|
|
|
JButton seniorButton = createGradeButton("高中");
|
|
|
|
|
seniorButton.addActionListener(e -> startExam("高中"));
|
|
|
|
|
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));
|
|
|
|
|
JButton changePasswordButton = createStyledButton("修改密码");
|
|
|
|
|
changePasswordButton.addActionListener(e -> showPasswordChangePanel());
|
|
|
|
|
bottomPanel.add(changePasswordButton);
|
|
|
|
|
|
|
|
|
|
JButton logoutButton = createStyledButton("退出登录", new Color(220, 20, 60));
|
|
|
|
|
// 新增:删除账号按钮
|
|
|
|
|
JButton deleteAccountButton = createStyledButton("删除账号");
|
|
|
|
|
deleteAccountButton.setBackground(new Color(220, 20, 60)); // 红色背景提示危险操作
|
|
|
|
|
deleteAccountButton.addActionListener(e -> deleteAccount());
|
|
|
|
|
bottomPanel.add(deleteAccountButton);
|
|
|
|
|
|
|
|
|
|
JButton logoutButton = createStyledButton("退出登录");
|
|
|
|
|
logoutButton.addActionListener(e -> logout());
|
|
|
|
|
bottomPanel.add(logoutButton);
|
|
|
|
|
|
|
|
|
|
@ -189,6 +198,43 @@ public class MainFrame extends JFrame {
|
|
|
|
|
|
|
|
|
|
mainPanel.add(panel, "GradeSelection");
|
|
|
|
|
}
|
|
|
|
|
// 新增:删除当前账号功能
|
|
|
|
|
private void deleteAccount() {
|
|
|
|
|
// 简单确认对话框
|
|
|
|
|
int result = JOptionPane.showConfirmDialog(
|
|
|
|
|
this,
|
|
|
|
|
"确定要删除当前账号吗?\n用户名:" + currentUserId + "\n此操作不可恢复!",
|
|
|
|
|
"确认删除账号",
|
|
|
|
|
JOptionPane.YES_NO_OPTION,
|
|
|
|
|
JOptionPane.WARNING_MESSAGE
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (result == JOptionPane.YES_OPTION) {
|
|
|
|
|
// 直接使用当前用户名作为邮箱(根据您的系统设计,用户名可能就是邮箱)
|
|
|
|
|
// 或者让用户输入邮箱确认
|
|
|
|
|
String userEmail = JOptionPane.showInputDialog(
|
|
|
|
|
this,
|
|
|
|
|
"请输入您的邮箱进行确认:",
|
|
|
|
|
"确认删除",
|
|
|
|
|
JOptionPane.QUESTION_MESSAGE
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (userEmail != null && !userEmail.trim().isEmpty()) {
|
|
|
|
|
// 调用User_service的Unregister函数删除账号
|
|
|
|
|
String deleteResult = userService.Unregister(userEmail.trim());
|
|
|
|
|
|
|
|
|
|
if (deleteResult.equals("删除成功")) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "账号删除成功!");
|
|
|
|
|
// 清除当前用户信息并返回登录界面
|
|
|
|
|
currentUserId = null;
|
|
|
|
|
examService = null;
|
|
|
|
|
showLoginPanel();
|
|
|
|
|
} else {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "删除失败:" + deleteResult);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void createExamPanel() {
|
|
|
|
|
JPanel panel = new JPanel(new BorderLayout(10, 10));
|
|
|
|
|
@ -199,11 +245,7 @@ public class MainFrame extends JFrame {
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
// 题目区域
|
|
|
|
|
@ -220,33 +262,33 @@ public class MainFrame extends JFrame {
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
optionsPanel.add(optionButtons[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
// 导航按钮区域
|
|
|
|
|
JPanel navPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10));
|
|
|
|
|
|
|
|
|
|
panel.add(bottomPanel, BorderLayout.SOUTH);
|
|
|
|
|
prevButton = createStyledButton("上一题");
|
|
|
|
|
prevButton.addActionListener(e -> goToPreviousQuestion());
|
|
|
|
|
navPanel.add(prevButton);
|
|
|
|
|
|
|
|
|
|
nextButton = createStyledButton("下一题");
|
|
|
|
|
nextButton.addActionListener(e -> goToNextQuestion());
|
|
|
|
|
navPanel.add(nextButton);
|
|
|
|
|
|
|
|
|
|
submitButton = createStyledButton("提交试卷");
|
|
|
|
|
submitButton.addActionListener(e -> submitExam());
|
|
|
|
|
navPanel.add(submitButton);
|
|
|
|
|
|
|
|
|
|
panel.add(navPanel, BorderLayout.SOUTH);
|
|
|
|
|
|
|
|
|
|
mainPanel.add(panel, "Exam");
|
|
|
|
|
}
|
|
|
|
|
@ -261,19 +303,58 @@ public class MainFrame extends JFrame {
|
|
|
|
|
|
|
|
|
|
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 30, 20));
|
|
|
|
|
|
|
|
|
|
JButton continueButton = createStyledButton("继续做题", new Color(60, 179, 113));
|
|
|
|
|
// 新增查看错题按钮
|
|
|
|
|
JButton reviewButton = createStyledButton("查看错题");
|
|
|
|
|
reviewButton.addActionListener(e -> showWrongQuestions());
|
|
|
|
|
buttonPanel.add(reviewButton);
|
|
|
|
|
|
|
|
|
|
JButton continueButton = createStyledButton("继续做题");
|
|
|
|
|
continueButton.addActionListener(e -> showGradeSelectionPanel());
|
|
|
|
|
buttonPanel.add(continueButton);
|
|
|
|
|
|
|
|
|
|
JButton exitButton = createStyledButton("退出程序", new Color(220, 20, 60));
|
|
|
|
|
JButton exitButton = createStyledButton("退出程序");
|
|
|
|
|
exitButton.addActionListener(e -> System.exit(0));
|
|
|
|
|
|
|
|
|
|
buttonPanel.add(continueButton);
|
|
|
|
|
buttonPanel.add(exitButton);
|
|
|
|
|
|
|
|
|
|
panel.add(buttonPanel, BorderLayout.SOUTH);
|
|
|
|
|
|
|
|
|
|
mainPanel.add(panel, "Result");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void createWrongQuestionsPanel() {
|
|
|
|
|
JPanel panel = new JPanel(new BorderLayout(10, 10));
|
|
|
|
|
panel.setBorder(BorderFactory.createEmptyBorder(20, 40, 20, 40));
|
|
|
|
|
|
|
|
|
|
// 标题
|
|
|
|
|
JLabel titleLabel = new JLabel("错题回顾", JLabel.CENTER);
|
|
|
|
|
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 20));
|
|
|
|
|
panel.add(titleLabel, BorderLayout.NORTH);
|
|
|
|
|
|
|
|
|
|
// 错题内容区域(使用滚动面板)
|
|
|
|
|
JTextArea wrongQuestionsArea = new JTextArea();
|
|
|
|
|
wrongQuestionsArea.setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
|
|
|
|
wrongQuestionsArea.setEditable(false);
|
|
|
|
|
wrongQuestionsArea.setLineWrap(true);
|
|
|
|
|
wrongQuestionsArea.setWrapStyleWord(true);
|
|
|
|
|
|
|
|
|
|
JScrollPane scrollPane = new JScrollPane(wrongQuestionsArea);
|
|
|
|
|
scrollPane.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
|
|
|
|
|
panel.add(scrollPane, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
|
|
// 存储错题文本区域引用
|
|
|
|
|
panel.putClientProperty("wrongQuestionsArea", wrongQuestionsArea);
|
|
|
|
|
|
|
|
|
|
// 返回按钮
|
|
|
|
|
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
|
|
|
|
|
JButton backButton = createStyledButton("返回成绩");
|
|
|
|
|
backButton.addActionListener(e -> showResultPanel());
|
|
|
|
|
bottomPanel.add(backButton);
|
|
|
|
|
|
|
|
|
|
panel.add(bottomPanel, BorderLayout.SOUTH);
|
|
|
|
|
|
|
|
|
|
mainPanel.add(panel, "WrongQuestions");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void createPasswordChangePanel() {
|
|
|
|
|
JPanel panel = new JPanel(new BorderLayout(10, 10));
|
|
|
|
|
panel.setBorder(BorderFactory.createEmptyBorder(50, 100, 50, 100));
|
|
|
|
|
@ -285,6 +366,10 @@ public class MainFrame extends JFrame {
|
|
|
|
|
JPanel formPanel = new JPanel(new GridLayout(4, 2, 15, 15));
|
|
|
|
|
formPanel.setBorder(BorderFactory.createEmptyBorder(30, 80, 30, 80));
|
|
|
|
|
|
|
|
|
|
formPanel.add(new JLabel("邮箱:", JLabel.RIGHT));
|
|
|
|
|
JTextField emailField = new JTextField();
|
|
|
|
|
formPanel.add(emailField);
|
|
|
|
|
|
|
|
|
|
formPanel.add(new JLabel("原密码:", JLabel.RIGHT));
|
|
|
|
|
JPasswordField oldPasswordField = new JPasswordField();
|
|
|
|
|
formPanel.add(oldPasswordField);
|
|
|
|
|
@ -301,16 +386,17 @@ public class MainFrame extends JFrame {
|
|
|
|
|
|
|
|
|
|
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10));
|
|
|
|
|
|
|
|
|
|
JButton changeButton = createStyledButton("确认修改", new Color(60, 179, 113));
|
|
|
|
|
JButton changeButton = createStyledButton("确认修改");
|
|
|
|
|
changeButton.addActionListener(e -> {
|
|
|
|
|
String email = emailField.getText();
|
|
|
|
|
String oldPassword = new String(oldPasswordField.getPassword());
|
|
|
|
|
String newPassword = new String(newPasswordField.getPassword());
|
|
|
|
|
String confirmPassword = new String(confirmPasswordField.getPassword());
|
|
|
|
|
changePassword(oldPassword, newPassword, confirmPassword);
|
|
|
|
|
changePassword(email, oldPassword, newPassword, confirmPassword);
|
|
|
|
|
});
|
|
|
|
|
buttonPanel.add(changeButton);
|
|
|
|
|
|
|
|
|
|
JButton backButton = createStyledButton("返回", new Color(192, 192, 192));
|
|
|
|
|
JButton backButton = createStyledButton("返回");
|
|
|
|
|
backButton.addActionListener(e -> showGradeSelectionPanel());
|
|
|
|
|
buttonPanel.add(backButton);
|
|
|
|
|
|
|
|
|
|
@ -319,23 +405,17 @@ public class MainFrame extends JFrame {
|
|
|
|
|
mainPanel.add(panel, "PasswordChange");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 工具方法:创建样式化按钮
|
|
|
|
|
private JButton createStyledButton(String text, Color bgColor) {
|
|
|
|
|
private JButton createStyledButton(String text) {
|
|
|
|
|
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) {
|
|
|
|
|
private JButton createGradeButton(String text) {
|
|
|
|
|
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;
|
|
|
|
|
@ -343,7 +423,7 @@ public class MainFrame extends JFrame {
|
|
|
|
|
|
|
|
|
|
// 界面显示方法
|
|
|
|
|
private void showLoginPanel() {
|
|
|
|
|
loginEmailField.setText("");
|
|
|
|
|
loginIdField.setText("");
|
|
|
|
|
loginPasswordField.setText("");
|
|
|
|
|
cardLayout.show(mainPanel, "Login");
|
|
|
|
|
}
|
|
|
|
|
@ -353,6 +433,7 @@ public class MainFrame extends JFrame {
|
|
|
|
|
regCodeField.setText("");
|
|
|
|
|
regPasswordField.setText("");
|
|
|
|
|
regConfirmPasswordField.setText("");
|
|
|
|
|
regUserIdField.setText("");
|
|
|
|
|
cardLayout.show(mainPanel, "Register");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -364,20 +445,34 @@ public class MainFrame extends JFrame {
|
|
|
|
|
cardLayout.show(mainPanel, "PasswordChange");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showExamPanel() {
|
|
|
|
|
cardLayout.show(mainPanel, "Exam");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showResultPanel() {
|
|
|
|
|
cardLayout.show(mainPanel, "Result");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showWrongQuestionsPanel() {
|
|
|
|
|
cardLayout.show(mainPanel, "WrongQuestions");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 业务逻辑方法
|
|
|
|
|
private void login() {
|
|
|
|
|
String email = loginEmailField.getText().trim();
|
|
|
|
|
String id = loginIdField.getText().trim();
|
|
|
|
|
String password = new String(loginPasswordField.getPassword());
|
|
|
|
|
|
|
|
|
|
if (email.isEmpty() || password.isEmpty()) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "请输入邮箱和密码");
|
|
|
|
|
if (id.isEmpty() || password.isEmpty()) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "请输入用户名和密码");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (userService.login(email, password)) {
|
|
|
|
|
String result = userService.login(id, password);
|
|
|
|
|
if (result.equals("登陆成功")) {
|
|
|
|
|
currentUserId = id;
|
|
|
|
|
showGradeSelectionPanel();
|
|
|
|
|
} else {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "登录失败,请检查邮箱和密码");
|
|
|
|
|
JOptionPane.showMessageDialog(this, result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -388,11 +483,8 @@ public class MainFrame extends JFrame {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (userService.sendVerificationCode(email)) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "验证码已发送到您的邮箱,请查收");
|
|
|
|
|
} else {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "验证码发送失败,请检查邮箱地址或稍后重试");
|
|
|
|
|
}
|
|
|
|
|
String result = userService.register(email);
|
|
|
|
|
JOptionPane.showMessageDialog(this, result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void register() {
|
|
|
|
|
@ -400,8 +492,9 @@ public class MainFrame extends JFrame {
|
|
|
|
|
String code = regCodeField.getText().trim();
|
|
|
|
|
String password = new String(regPasswordField.getPassword());
|
|
|
|
|
String confirmPassword = new String(regConfirmPasswordField.getPassword());
|
|
|
|
|
String userId = regUserIdField.getText().trim();
|
|
|
|
|
|
|
|
|
|
if (email.isEmpty() || code.isEmpty() || password.isEmpty()) {
|
|
|
|
|
if (email.isEmpty() || code.isEmpty() || password.isEmpty() || userId.isEmpty()) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "请填写所有字段");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@ -411,114 +504,197 @@ public class MainFrame extends JFrame {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (userService.completeRegistration(email, code, password)) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "注册成功,请登录");
|
|
|
|
|
String result = userService.check_register(email, code, password, userId);
|
|
|
|
|
JOptionPane.showMessageDialog(this, result);
|
|
|
|
|
|
|
|
|
|
if (result.equals("注册成功")) {
|
|
|
|
|
showLoginPanel();
|
|
|
|
|
} else {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "注册失败,请检查验证码和密码格式\n密码要求:6-10位,包含大小写字母和数字");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void startExam(int gradeLevel, String gradeName) {
|
|
|
|
|
private void startExam(String gradeType) {
|
|
|
|
|
String input = JOptionPane.showInputDialog(this,
|
|
|
|
|
"请输入" + gradeName + "题目数量:", "题目数量", JOptionPane.QUESTION_MESSAGE);
|
|
|
|
|
"请输入" + gradeType + "题目数量:", "题目数量", JOptionPane.QUESTION_MESSAGE);
|
|
|
|
|
|
|
|
|
|
if (input == null) return; // 用户取消
|
|
|
|
|
if (input == null) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
int count = Integer.parseInt(input.trim());
|
|
|
|
|
if (count <= 0) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "题目数量必须大于0");
|
|
|
|
|
int numQuestions = Integer.parseInt(input.trim());
|
|
|
|
|
if (numQuestions < 10 || numQuestions > 30) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "题目数量范围是10-30");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (count > 100) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "题目数量不能超过100");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
examService = new Exam_service(numQuestions, gradeType, currentUserId);
|
|
|
|
|
showCurrentQuestion();
|
|
|
|
|
showExamPanel();
|
|
|
|
|
|
|
|
|
|
examService.startExam(gradeLevel, count);
|
|
|
|
|
showNextQuestion();
|
|
|
|
|
cardLayout.show(mainPanel, "Exam");
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "请输入有效的数字");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showNextQuestion() {
|
|
|
|
|
Question question = examService.getCurrentQuestion();
|
|
|
|
|
private void showCurrentQuestion() {
|
|
|
|
|
Question question = examService.get_now_question();
|
|
|
|
|
if (question != null) {
|
|
|
|
|
questionNumberLabel.setText(String.format("第 %d 题 / 共 %d 题",
|
|
|
|
|
examService.getCurrentQuestionNumber(),
|
|
|
|
|
examService.getTotalQuestions()));
|
|
|
|
|
int currentIndex = examService.get_now_index();
|
|
|
|
|
int totalQuestions = examService.get_paper().size();
|
|
|
|
|
|
|
|
|
|
examInfoLabel.setText(getGradeName(question.getGradeLevel()) + "数学题");
|
|
|
|
|
questionNumberLabel.setText(String.format("第 %d 题 / 共 %d 题",
|
|
|
|
|
currentIndex + 1, totalQuestions));
|
|
|
|
|
|
|
|
|
|
questionLabel.setText("<html><div style='text-align: center;'>" + question.getQuestionText() + "</div></html>");
|
|
|
|
|
questionLabel.setText("<html><div style='text-align: center; font-size: 16px;'>" +
|
|
|
|
|
question.toString() + "</div></html>");
|
|
|
|
|
|
|
|
|
|
java.util.List<String> options = question.getOptions();
|
|
|
|
|
String[] optionLetters = {"A", "B", "C", "D"};
|
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
|
optionButtons[i].setText(optionLetters[i] + ". " + options.get(i));
|
|
|
|
|
String optionText = question.getOptions(i);
|
|
|
|
|
optionButtons[i].setText((char)('A' + i) + ": " + optionText);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Integer userAnswer = examService.get_user_answer(currentIndex);
|
|
|
|
|
optionGroup.clearSelection();
|
|
|
|
|
if (userAnswer != null && userAnswer >= 0 && userAnswer < 4) {
|
|
|
|
|
optionButtons[userAnswer].setSelected(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
updateNavigationButtons();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String getGradeName(int gradeLevel) {
|
|
|
|
|
switch (gradeLevel) {
|
|
|
|
|
case 0: return "小学";
|
|
|
|
|
case 1: return "初中";
|
|
|
|
|
case 2: return "高中";
|
|
|
|
|
default: return "未知";
|
|
|
|
|
private void updateNavigationButtons() {
|
|
|
|
|
int currentIndex = examService.get_now_index();
|
|
|
|
|
int totalQuestions = examService.get_paper().size();
|
|
|
|
|
|
|
|
|
|
prevButton.setEnabled(currentIndex > 0);
|
|
|
|
|
nextButton.setEnabled(currentIndex < totalQuestions - 1);
|
|
|
|
|
submitButton.setEnabled(currentIndex == totalQuestions - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void goToPreviousQuestion() {
|
|
|
|
|
if (examService.pre_one()) {
|
|
|
|
|
showCurrentQuestion();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void submitAnswer() {
|
|
|
|
|
int selectedOption = -1;
|
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
|
if (optionButtons[i].isSelected()) {
|
|
|
|
|
selectedOption = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
private void goToNextQuestion() {
|
|
|
|
|
int selectedOption = getSelectedOption();
|
|
|
|
|
if (selectedOption == -1) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "请选择一个答案");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boolean hasNext = examService.next_one(selectedOption);
|
|
|
|
|
if (hasNext) {
|
|
|
|
|
showCurrentQuestion();
|
|
|
|
|
} else {
|
|
|
|
|
showExamResult();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void submitExam() {
|
|
|
|
|
int selectedOption = getSelectedOption();
|
|
|
|
|
if (selectedOption == -1) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "请选择一个答案");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
examService.submitAnswer(selectedOption);
|
|
|
|
|
examService.next_one(selectedOption);
|
|
|
|
|
showExamResult();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (examService.hasNextQuestion()) {
|
|
|
|
|
showNextQuestion();
|
|
|
|
|
} else {
|
|
|
|
|
showResult();
|
|
|
|
|
private int getSelectedOption() {
|
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
|
if (optionButtons[i].isSelected()) {
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showResult() {
|
|
|
|
|
ExamResult result = examService.getExamResult();
|
|
|
|
|
String gradeName = getGradeName(result.getGradeLevel());
|
|
|
|
|
private void showExamResult() {
|
|
|
|
|
Exam_result result = examService.calculate_result();
|
|
|
|
|
|
|
|
|
|
String resultText = String.format(
|
|
|
|
|
"<html><div style='text-align: center;'>" +
|
|
|
|
|
"<h2>%s数学测试完成!</h2>" +
|
|
|
|
|
"<h3>%s</h3>" +
|
|
|
|
|
"<p>正确题数: %d / %d</p>" +
|
|
|
|
|
"<p>考试完成!</p>" +
|
|
|
|
|
"<p>%s数学测试</p>" +
|
|
|
|
|
"<p>总题数: %d</p>" +
|
|
|
|
|
"<p>答对题数: %d</p>" +
|
|
|
|
|
"<p>得分: %.1f</p>" +
|
|
|
|
|
"<p>用时: %s</p>" +
|
|
|
|
|
"<p>正确率: %s</p>" +
|
|
|
|
|
"</div></html>",
|
|
|
|
|
gradeName, result.toString(), result.getCorrectAnswers(),
|
|
|
|
|
result.getTotalQuestions(), result.getScore()
|
|
|
|
|
result.getExamType(),
|
|
|
|
|
result.getTotalQuestions(),
|
|
|
|
|
result.getCorrectAnswers(),
|
|
|
|
|
result.getScore(),
|
|
|
|
|
result.get_time(),
|
|
|
|
|
result.getCorrectRate()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
resultLabel.setText(resultText);
|
|
|
|
|
cardLayout.show(mainPanel, "Result");
|
|
|
|
|
showResultPanel();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void changePassword(String oldPassword, String newPassword, String confirmPassword) {
|
|
|
|
|
if (oldPassword.isEmpty() || newPassword.isEmpty() || confirmPassword.isEmpty()) {
|
|
|
|
|
// 新增:查看错题功能
|
|
|
|
|
// 修正:查看错题功能 - 简洁显示
|
|
|
|
|
private void showWrongQuestions() {
|
|
|
|
|
// 获取考试结果
|
|
|
|
|
Exam_result result = examService.calculate_result();
|
|
|
|
|
java.util.List<Integer> wrongQuestionIndices = result.getWrongQuestions();
|
|
|
|
|
|
|
|
|
|
if (wrongQuestionIndices.isEmpty()) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "恭喜!本次考试没有错题!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取错题面板和文本区域
|
|
|
|
|
JPanel wrongQuestionsPanel = (JPanel) mainPanel.getComponent(5); // 第6个面板是错题面板
|
|
|
|
|
JTextArea wrongQuestionsArea = (JTextArea) ((JScrollPane) wrongQuestionsPanel.getComponent(1)).getViewport().getView();
|
|
|
|
|
|
|
|
|
|
// 构建错题显示内容
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
sb.append("本次考试共有 ").append(wrongQuestionIndices.size()).append(" 道错题:\n\n");
|
|
|
|
|
|
|
|
|
|
java.util.ArrayList<Question> paper = examService.get_paper();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < wrongQuestionIndices.size(); i++) {
|
|
|
|
|
int questionIndex = wrongQuestionIndices.get(i);
|
|
|
|
|
Question question = paper.get(questionIndex);
|
|
|
|
|
|
|
|
|
|
// 只显示一个题号
|
|
|
|
|
sb.append("第 ").append(questionIndex + 1).append(" 题:");
|
|
|
|
|
sb.append(question.toString()).append("\n");
|
|
|
|
|
|
|
|
|
|
// 显示所有选项,在正确答案后打勾
|
|
|
|
|
sb.append("选项:\n");
|
|
|
|
|
for (int j = 0; j < 4; j++) {
|
|
|
|
|
char optionChar = (char) ('A' + j);
|
|
|
|
|
sb.append(" ").append(optionChar).append(". ").append(question.getOptions(j));
|
|
|
|
|
|
|
|
|
|
// 标记正确答案
|
|
|
|
|
if (question.getOptions(j).equals(question.getAnswer())) {
|
|
|
|
|
sb.append(" √");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 标记用户选择的错误答案
|
|
|
|
|
Integer userAnswer = examService.get_user_answer(questionIndex);
|
|
|
|
|
if (userAnswer != null && userAnswer == j && !question.getOptions(j).equals(question.getAnswer())) {
|
|
|
|
|
sb.append(" X");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sb.append("\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sb.append("\n");
|
|
|
|
|
sb.append("-".repeat(50)).append("\n\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wrongQuestionsArea.setText(sb.toString());
|
|
|
|
|
showWrongQuestionsPanel();
|
|
|
|
|
}
|
|
|
|
|
private void changePassword(String email, String oldPassword, String newPassword, String confirmPassword) {
|
|
|
|
|
if (email.isEmpty() || oldPassword.isEmpty() || newPassword.isEmpty()) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "请填写所有字段");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@ -528,30 +704,28 @@ public class MainFrame extends JFrame {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (userService.changePassword(oldPassword, newPassword)) {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "密码修改成功");
|
|
|
|
|
String result = userService.change_pwd(email, oldPassword, newPassword);
|
|
|
|
|
JOptionPane.showMessageDialog(this, result);
|
|
|
|
|
|
|
|
|
|
if (result.equals("修改成功")) {
|
|
|
|
|
showGradeSelectionPanel();
|
|
|
|
|
} else {
|
|
|
|
|
JOptionPane.showMessageDialog(this, "密码修改失败,请检查原密码和新密码格式\n新密码要求:6-10位,包含大小写字母和数字");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void logout() {
|
|
|
|
|
userService.logout();
|
|
|
|
|
currentUserId = null;
|
|
|
|
|
examService = null;
|
|
|
|
|
showLoginPanel();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
// 设置系统样式
|
|
|
|
|
try {
|
|
|
|
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeel());
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
public void exitchoice(){
|
|
|
|
|
System.exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 主函数
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
SwingUtilities.invokeLater(() -> {
|
|
|
|
|
MainFrame frame = new MainFrame();
|
|
|
|
|
frame.setVisible(true);
|
|
|
|
|
new MainFrame().setVisible(true);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|