From caac1f363d0f2f828457768860dc8b041d99fa0b Mon Sep 17 00:00:00 2001 From: ZHW <1941286652@qq.com> Date: Sat, 11 Oct 2025 19:31:36 +0800 Subject: [PATCH] v2.0 --- src/.idea/.name | 1 + .../inspectionProfiles/Project_Default.xml | 6 + src/.idea/misc.xml | 2 +- src/.idea/vcs.xml | 1 + src/src/MathLearningApp.java | 292 ++++++++++++++---- 5 files changed, 240 insertions(+), 62 deletions(-) create mode 100644 src/.idea/.name create mode 100644 src/.idea/inspectionProfiles/Project_Default.xml diff --git a/src/.idea/.name b/src/.idea/.name new file mode 100644 index 0000000..696aa06 --- /dev/null +++ b/src/.idea/.name @@ -0,0 +1 @@ +MathLearningApp.java \ No newline at end of file diff --git a/src/.idea/inspectionProfiles/Project_Default.xml b/src/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..a374ccf --- /dev/null +++ b/src/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/src/.idea/misc.xml b/src/.idea/misc.xml index 6f29fee..28c56bd 100644 --- a/src/.idea/misc.xml +++ b/src/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/.idea/vcs.xml b/src/.idea/vcs.xml index 94a25f7..288b36b 100644 --- a/src/.idea/vcs.xml +++ b/src/.idea/vcs.xml @@ -1,6 +1,7 @@ + \ No newline at end of file diff --git a/src/src/MathLearningApp.java b/src/src/MathLearningApp.java index 7b7e167..64c9b95 100644 --- a/src/src/MathLearningApp.java +++ b/src/src/MathLearningApp.java @@ -11,15 +11,18 @@ import java.util.Map; // 用户类 class User { + private String username; private String email; private String password; private String verificationCode; - public User(String email, String password) { + public User(String username, String email, String password) { + this.username = username; this.email = email; this.password = password; } + public String getUsername() { return username; } public String getEmail() { return email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @@ -245,27 +248,36 @@ class EmailUtil { // 用户管理类 class UserManager { - private Map users; + private Map usersByEmail; + private Map usersByUsername; public UserManager() { - users = new HashMap<>(); + usersByEmail = new HashMap<>(); + usersByUsername = new HashMap<>(); // 添加一些测试用户 - users.put("test@test.com", new User("test@test.com", "Test123")); - users.put("user@example.com", new User("user@example.com", "User123")); + addUser("测试用户", "test@test.com", "Test123"); + addUser("示例用户", "user@example.com", "User123"); } - public boolean registerUser(String email, String password) { - if (users.containsKey(email)) { + private void addUser(String username, String email, String password) { + User user = new User(username, email, password); + usersByEmail.put(email, user); + usersByUsername.put(username, user); + } + + public boolean registerUser(String username, String email, String password) { + if (usersByEmail.containsKey(email) || usersByUsername.containsKey(username)) { return false; } - User user = new User(email, password); - users.put(email, user); + User user = new User(username, email, password); + usersByEmail.put(email, user); + usersByUsername.put(username, user); return true; } public User login(String email, String password) { - User user = users.get(email); + User user = usersByEmail.get(email); if (user != null && user.getPassword().equals(password)) { return user; } @@ -273,7 +285,7 @@ class UserManager { } public boolean updatePassword(String email, String oldPassword, String newPassword) { - User user = users.get(email); + User user = usersByEmail.get(email); if (user != null && user.getPassword().equals(oldPassword)) { user.setPassword(newPassword); return true; @@ -282,7 +294,11 @@ class UserManager { } public boolean isEmailRegistered(String email) { - return users.containsKey(email); + return usersByEmail.containsKey(email); + } + + public boolean isUsernameRegistered(String username) { + return usersByUsername.containsKey(username); } } @@ -304,6 +320,7 @@ public class MathLearningApp { private ButtonGroup optionGroup; private JRadioButton[] optionButtons; private JLabel scoreLabel; + private JLabel welcomeLabel; public MathLearningApp() { userManager = new UserManager(); @@ -313,7 +330,7 @@ public class MathLearningApp { private void initializeUI() { mainFrame = new JFrame("数学学习软件"); mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - mainFrame.setSize(500, 400); + mainFrame.setSize(600, 500); mainFrame.setLocationRelativeTo(null); cardLayout = new CardLayout(); @@ -335,46 +352,66 @@ public class MathLearningApp { private void createLoginPanel() { JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); - gbc.insets = new Insets(10, 10, 10, 10); + gbc.insets = new Insets(15, 15, 15, 15); gbc.fill = GridBagConstraints.HORIZONTAL; - JLabel titleLabel = new JLabel("用户登录", JLabel.CENTER); - titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 20)); + JLabel titleLabel = new JLabel("数学学习软件", JLabel.CENTER); + titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24)); + titleLabel.setForeground(new Color(0, 100, 200)); gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 2; panel.add(titleLabel, gbc); + JLabel subtitleLabel = new JLabel("用户登录", JLabel.CENTER); + subtitleLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16)); + subtitleLabel.setForeground(Color.GRAY); + gbc.gridy = 1; + panel.add(subtitleLabel, gbc); + gbc.gridwidth = 1; - gbc.gridy = 1; gbc.gridx = 0; - panel.add(new JLabel("邮箱:"), gbc); + gbc.gridy = 2; gbc.gridx = 0; + JLabel emailLabel = new JLabel("邮箱:"); + emailLabel.setFont(new Font("微软雅黑", Font.BOLD, 14)); + panel.add(emailLabel, gbc); gbc.gridx = 1; emailField = new JTextField(20); + emailField.setFont(new Font("微软雅黑", Font.PLAIN, 14)); panel.add(emailField, gbc); - gbc.gridy = 2; gbc.gridx = 0; - panel.add(new JLabel("密码:"), gbc); + gbc.gridy = 3; gbc.gridx = 0; + JLabel passwordLabel = new JLabel("密码:"); + passwordLabel.setFont(new Font("微软雅黑", Font.BOLD, 14)); + panel.add(passwordLabel, gbc); gbc.gridx = 1; passwordField = new JPasswordField(20); + passwordField.setFont(new Font("微软雅黑", Font.PLAIN, 14)); panel.add(passwordField, gbc); - gbc.gridy = 3; gbc.gridx = 0; gbc.gridwidth = 2; + gbc.gridy = 4; gbc.gridx = 0; gbc.gridwidth = 2; JPanel buttonPanel = new JPanel(new FlowLayout()); - JButton loginButton = new JButton("登录"); + JButton loginButton = createStyledButton("登录", new Color(70, 130, 180)); loginButton.addActionListener(e -> handleLogin()); buttonPanel.add(loginButton); - JButton registerButton = new JButton("注册"); + JButton registerButton = createStyledButton("注册", new Color(60, 179, 113)); registerButton.addActionListener(e -> cardLayout.show(mainPanel, "Register")); buttonPanel.add(registerButton); - JButton changePasswordButton = new JButton("修改密码"); + JButton changePasswordButton = createStyledButton("修改密码", new Color(218, 165, 32)); changePasswordButton.addActionListener(e -> cardLayout.show(mainPanel, "ChangePassword")); buttonPanel.add(changePasswordButton); panel.add(buttonPanel, gbc); + // 添加测试账号提示 + gbc.gridy = 5; + JLabel testAccountLabel = new JLabel("测试账号: test@test.com / Test123", JLabel.CENTER); + testAccountLabel.setFont(new Font("微软雅黑", Font.ITALIC, 12)); + testAccountLabel.setForeground(Color.GRAY); + panel.add(testAccountLabel, gbc); + mainPanel.add(panel, "Login"); } @@ -391,38 +428,52 @@ public class MathLearningApp { gbc.gridwidth = 1; gbc.gridy = 1; gbc.gridx = 0; + panel.add(new JLabel("用户名:"), gbc); + + gbc.gridx = 1; + JTextField usernameField = new JTextField(20); + panel.add(usernameField, gbc); + + gbc.gridy = 2; gbc.gridx = 0; panel.add(new JLabel("邮箱:"), gbc); gbc.gridx = 1; JTextField registerEmailField = new JTextField(20); panel.add(registerEmailField, gbc); - gbc.gridy = 2; gbc.gridx = 0; gbc.gridwidth = 2; - JButton sendCodeButton = new JButton("发送验证码"); + gbc.gridy = 3; gbc.gridx = 0; gbc.gridwidth = 2; + JButton sendCodeButton = createStyledButton("发送验证码", new Color(70, 130, 180)); panel.add(sendCodeButton, gbc); gbc.gridwidth = 1; - gbc.gridy = 3; gbc.gridx = 0; + gbc.gridy = 4; gbc.gridx = 0; panel.add(new JLabel("验证码:"), gbc); gbc.gridx = 1; JTextField registerCodeField = new JTextField(20); panel.add(registerCodeField, gbc); - gbc.gridy = 4; gbc.gridx = 0; gbc.gridwidth = 2; - JButton registerButton = new JButton("注册"); + gbc.gridy = 5; gbc.gridx = 0; gbc.gridwidth = 2; + JButton registerButton = createStyledButton("注册", new Color(60, 179, 113)); registerButton.addActionListener(e -> { + String username = usernameField.getText(); String email = registerEmailField.getText(); String code = registerCodeField.getText(); - if (email.isEmpty() || code.isEmpty()) { - JOptionPane.showMessageDialog(panel, "请填写邮箱和验证码"); + if (username.isEmpty() || email.isEmpty() || code.isEmpty()) { + JOptionPane.showMessageDialog(panel, "请填写所有信息"); + return; + } + + if (userManager.isUsernameRegistered(username)) { + JOptionPane.showMessageDialog(panel, "用户名已被使用"); return; } // 验证验证码(简化处理,只要6位就通过) if (code.length() == 6) { - // 保存邮箱信息用于后续设置密码 + // 保存用户信息用于后续设置密码 + mainPanel.putClientProperty("registerUsername", username); mainPanel.putClientProperty("registerEmail", email); cardLayout.show(mainPanel, "SetPassword"); } else { @@ -431,13 +482,25 @@ public class MathLearningApp { }); panel.add(registerButton, gbc); - gbc.gridy = 5; - JButton backButton = new JButton("返回登录"); + gbc.gridy = 6; + JButton backButton = createStyledButton("返回登录", new Color(169, 169, 169)); backButton.addActionListener(e -> cardLayout.show(mainPanel, "Login")); panel.add(backButton, gbc); sendCodeButton.addActionListener(e -> { + String username = usernameField.getText(); String email = registerEmailField.getText(); + + if (username.isEmpty() || email.isEmpty()) { + JOptionPane.showMessageDialog(panel, "请填写用户名和邮箱"); + return; + } + + if (userManager.isUsernameRegistered(username)) { + JOptionPane.showMessageDialog(panel, "用户名已被使用"); + return; + } + if (isValidEmail(email)) { if (userManager.isEmailRegistered(email)) { JOptionPane.showMessageDialog(panel, "该邮箱已被注册"); @@ -485,14 +548,15 @@ public class MathLearningApp { panel.add(confirmSetPasswordField, gbc); gbc.gridy = 3; gbc.gridx = 0; gbc.gridwidth = 2; - JButton setPasswordButton = new JButton("设置密码"); + JButton setPasswordButton = createStyledButton("设置密码", new Color(60, 179, 113)); setPasswordButton.addActionListener(e -> { String password = new String(setPasswordField.getPassword()); String confirmPassword = new String(confirmSetPasswordField.getPassword()); + String username = (String) mainPanel.getClientProperty("registerUsername"); String email = (String) mainPanel.getClientProperty("registerEmail"); if (validatePassword(password, confirmPassword)) { - if (userManager.registerUser(email, password)) { + if (userManager.registerUser(username, email, password)) { JOptionPane.showMessageDialog(panel, "注册成功!"); cardLayout.show(mainPanel, "Login"); } else { @@ -506,24 +570,37 @@ public class MathLearningApp { } private void createLevelSelectionPanel() { - JPanel panel = new JPanel(new GridLayout(4, 1, 10, 10)); - panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30)); + panel.setBackground(new Color(240, 248, 255)); JLabel titleLabel = new JLabel("选择学习阶段", JLabel.CENTER); - titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 20)); - panel.add(titleLabel); + titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24)); + titleLabel.setForeground(new Color(0, 100, 200)); + panel.add(titleLabel, BorderLayout.NORTH); + + welcomeLabel = new JLabel("", JLabel.CENTER); + welcomeLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16)); + welcomeLabel.setForeground(Color.DARK_GRAY); + panel.add(welcomeLabel, BorderLayout.CENTER); - JButton primaryButton = new JButton("小学"); + JPanel buttonPanel = new JPanel(new GridLayout(3, 1, 20, 20)); + buttonPanel.setBorder(BorderFactory.createEmptyBorder(20, 50, 20, 50)); + buttonPanel.setBackground(new Color(240, 248, 255)); + + JButton primaryButton = createLevelButton("小学", new Color(135, 206, 250)); primaryButton.addActionListener(e -> startExam("小学")); - panel.add(primaryButton); + buttonPanel.add(primaryButton); - JButton juniorButton = new JButton("初中"); + JButton juniorButton = createLevelButton("初中", new Color(100, 149, 237)); juniorButton.addActionListener(e -> startExam("初中")); - panel.add(juniorButton); + buttonPanel.add(juniorButton); - JButton seniorButton = new JButton("高中"); + JButton seniorButton = createLevelButton("高中", new Color(65, 105, 225)); seniorButton.addActionListener(e -> startExam("高中")); - panel.add(seniorButton); + buttonPanel.add(seniorButton); + + panel.add(buttonPanel, BorderLayout.SOUTH); mainPanel.add(panel, "LevelSelection"); } @@ -531,7 +608,7 @@ public class MathLearningApp { private void createQuestionCountPanel() { JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); - gbc.insets = new Insets(10, 10, 10, 10); + gbc.insets = new Insets(15, 15, 15, 15); JLabel titleLabel = new JLabel("请输入题目数量", JLabel.CENTER); titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 20)); @@ -539,10 +616,17 @@ public class MathLearningApp { panel.add(titleLabel, gbc); JTextField countField = new JTextField(10); + countField.setFont(new Font("微软雅黑", Font.PLAIN, 16)); gbc.gridy = 1; panel.add(countField, gbc); - JButton startButton = new JButton("开始答题"); + JLabel hintLabel = new JLabel("(建议5-20题)", JLabel.CENTER); + hintLabel.setFont(new Font("微软雅黑", Font.ITALIC, 12)); + hintLabel.setForeground(Color.GRAY); + gbc.gridy = 2; + panel.add(hintLabel, gbc); + + JButton startButton = createStyledButton("开始答题", new Color(60, 179, 113)); startButton.addActionListener(e -> { try { int count = Integer.parseInt(countField.getText()); @@ -556,7 +640,7 @@ public class MathLearningApp { JOptionPane.showMessageDialog(panel, "请输入有效的数字"); } }); - gbc.gridy = 2; + gbc.gridy = 3; panel.add(startButton, gbc); mainPanel.add(panel, "QuestionCount"); @@ -565,24 +649,31 @@ public class MathLearningApp { private void createExamPanel() { JPanel panel = new JPanel(new BorderLayout()); panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); + panel.setBackground(new Color(240, 248, 255)); questionLabel = new JLabel("", JLabel.CENTER); - questionLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16)); + questionLabel.setFont(new Font("微软雅黑", Font.PLAIN, 18)); + questionLabel.setBorder(BorderFactory.createEmptyBorder(10, 10, 20, 10)); panel.add(questionLabel, BorderLayout.NORTH); - JPanel optionsPanel = new JPanel(new GridLayout(4, 1, 10, 10)); + JPanel optionsPanel = new JPanel(new GridLayout(4, 1, 15, 15)); + optionsPanel.setBorder(BorderFactory.createEmptyBorder(20, 50, 20, 50)); + optionsPanel.setBackground(new Color(240, 248, 255)); + optionGroup = new ButtonGroup(); optionButtons = new JRadioButton[4]; for (int i = 0; i < 4; i++) { optionButtons[i] = new JRadioButton(); + optionButtons[i].setFont(new Font("微软雅黑", Font.PLAIN, 16)); + optionButtons[i].setBackground(new Color(240, 248, 255)); optionGroup.add(optionButtons[i]); optionsPanel.add(optionButtons[i]); } panel.add(optionsPanel, BorderLayout.CENTER); - JButton submitButton = new JButton("提交答案"); + JButton submitButton = createStyledButton("提交答案", new Color(70, 130, 180)); submitButton.addActionListener(e -> handleAnswerSubmission()); panel.add(submitButton, BorderLayout.SOUTH); @@ -591,19 +682,26 @@ public class MathLearningApp { private void createScorePanel() { JPanel panel = new JPanel(new BorderLayout()); - panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); + panel.setBorder(BorderFactory.createEmptyBorder(40, 40, 40, 40)); + panel.setBackground(new Color(240, 248, 255)); + + JLabel titleLabel = new JLabel("答题完成", JLabel.CENTER); + titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 28)); + titleLabel.setForeground(new Color(0, 100, 200)); + panel.add(titleLabel, BorderLayout.NORTH); scoreLabel = new JLabel("", JLabel.CENTER); - scoreLabel.setFont(new Font("微软雅黑", Font.BOLD, 24)); + scoreLabel.setFont(new Font("微软雅黑", Font.BOLD, 36)); + scoreLabel.setForeground(new Color(220, 20, 60)); panel.add(scoreLabel, BorderLayout.CENTER); JPanel buttonPanel = new JPanel(new FlowLayout()); - JButton continueButton = new JButton("继续做题"); + JButton continueButton = createStyledButton("继续做题", new Color(60, 179, 113)); continueButton.addActionListener(e -> cardLayout.show(mainPanel, "LevelSelection")); buttonPanel.add(continueButton); - JButton exitButton = new JButton("退出"); + JButton exitButton = createStyledButton("退出登录", new Color(205, 92, 92)); exitButton.addActionListener(e -> { currentUser = null; cardLayout.show(mainPanel, "Login"); @@ -658,7 +756,7 @@ public class MathLearningApp { gbc.gridy = 5; gbc.gridx = 0; gbc.gridwidth = 2; JPanel buttonPanel = new JPanel(new FlowLayout()); - JButton changeButton = new JButton("修改密码"); + JButton changeButton = createStyledButton("修改密码", new Color(60, 179, 113)); changeButton.addActionListener(e -> { String email = changePasswordEmailField.getText(); String oldPassword = new String(oldPasswordField.getPassword()); @@ -676,7 +774,7 @@ public class MathLearningApp { }); buttonPanel.add(changeButton); - JButton backButton = new JButton("返回"); + JButton backButton = createStyledButton("返回", new Color(169, 169, 169)); backButton.addActionListener(e -> cardLayout.show(mainPanel, "Login")); buttonPanel.add(backButton); @@ -697,6 +795,7 @@ public class MathLearningApp { currentUser = userManager.login(email, password); if (currentUser != null) { + welcomeLabel.setText("欢迎, " + currentUser.getUsername() + "!"); JOptionPane.showMessageDialog(mainPanel, "登录成功!"); cardLayout.show(mainPanel, "LevelSelection"); } else { @@ -746,7 +845,8 @@ public class MathLearningApp { private void displayCurrentQuestion() { if (currentQuestionIndex < currentExam.size()) { Question question = currentExam.get(currentQuestionIndex); - questionLabel.setText("题目 " + (currentQuestionIndex + 1) + "/" + currentExam.size() + ": " + question.getContent()); + questionLabel.setText("
题目 " + (currentQuestionIndex + 1) + "/" + + currentExam.size() + "
" + question.getContent() + "
"); String[] options = question.getOptions(); for (int i = 0; i < 4; i++) { @@ -785,12 +885,82 @@ public class MathLearningApp { } private void showScore() { - double percentage = (double) score / currentExam.size() * 100; - scoreLabel.setText(String.format("得分: %d/%d (%.1f%%)", score, currentExam.size(), percentage)); + // 计算百分制得分 + 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); -- 2.34.1