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);