first commit

刘星宇 5 months ago
commit 7dfe594916

@ -0,0 +1,29 @@
package View;
import javax.swing.*;
import Service.Exam_service;
import Service.User_service;
public class AppLauncher {
public static void main(String[] args) {
// 设置中文显示
setUIFont();
SwingUtilities.invokeLater(() -> {
MainFrame frame = new MainFrame();
frame.setVisible(true);
});
}
private static void setUIFont() {
try {
UIManager.put("Button.font", new javax.swing.plaf.FontUIResource("微软雅黑", java.awt.Font.PLAIN, 13));
UIManager.put("Label.font", new javax.swing.plaf.FontUIResource("微软雅黑", java.awt.Font.PLAIN, 13));
UIManager.put("TextField.font", new javax.swing.plaf.FontUIResource("微软雅黑", java.awt.Font.PLAIN, 13));
UIManager.put("PasswordField.font", new javax.swing.plaf.FontUIResource("微软雅黑", java.awt.Font.PLAIN, 13));
UIManager.put("TextArea.font", new javax.swing.plaf.FontUIResource("微软雅黑", java.awt.Font.PLAIN, 13));
UIManager.put("RadioButton.font", new javax.swing.plaf.FontUIResource("微软雅黑", java.awt.Font.PLAIN, 13));
} catch (Exception e) {
e.printStackTrace();
}
}
}

@ -0,0 +1,557 @@
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("<html><div style='text-align: center;'>" + question.getQuestionText() + "</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));
}
optionGroup.clearSelection();
}
}
private String getGradeName(int gradeLevel) {
switch (gradeLevel) {
case 0: return "小学";
case 1: return "初中";
case 2: return "高中";
default: return "未知";
}
}
private void submitAnswer() {
int selectedOption = -1;
for (int i = 0; i < 4; i++) {
if (optionButtons[i].isSelected()) {
selectedOption = i;
break;
}
}
if (selectedOption == -1) {
JOptionPane.showMessageDialog(this, "请选择一个答案");
return;
}
examService.submitAnswer(selectedOption);
if (examService.hasNextQuestion()) {
showNextQuestion();
} else {
showResult();
}
}
private void showResult() {
ExamResult result = examService.getExamResult();
String gradeName = getGradeName(result.getGradeLevel());
String resultText = String.format(
"<html><div style='text-align: center;'>" +
"<h2>%s数学测试完成</h2>" +
"<h3>%s</h3>" +
"<p>正确题数: %d / %d</p>" +
"<p>得分: %.1f</p>" +
"</div></html>",
gradeName, result.toString(), result.getCorrectAnswers(),
result.getTotalQuestions(), result.getScore()
);
resultLabel.setText(resultText);
cardLayout.show(mainPanel, "Result");
}
private void changePassword(String oldPassword, String newPassword, String confirmPassword) {
if (oldPassword.isEmpty() || newPassword.isEmpty() || confirmPassword.isEmpty()) {
JOptionPane.showMessageDialog(this, "请填写所有字段");
return;
}
if (!newPassword.equals(confirmPassword)) {
JOptionPane.showMessageDialog(this, "两次输入的新密码不一致");
return;
}
if (userService.changePassword(oldPassword, newPassword)) {
JOptionPane.showMessageDialog(this, "密码修改成功");
showGradeSelectionPanel();
} else {
JOptionPane.showMessageDialog(this, "密码修改失败,请检查原密码和新密码格式\n新密码要求6-10位包含大小写字母和数字");
}
}
private void logout() {
userService.logout();
showLoginPanel();
}
public static void main(String[] args) {
// 设置系统样式
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeel());
} catch (Exception e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(() -> {
MainFrame frame = new MainFrame();
frame.setVisible(true);
});
}
}
Loading…
Cancel
Save