|
|
|
|
@ -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<String, User> users;
|
|
|
|
|
private Map<String, User> usersByEmail;
|
|
|
|
|
private Map<String, User> 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("<html><div style='text-align: center;'>题目 " + (currentQuestionIndex + 1) + "/" +
|
|
|
|
|
currentExam.size() + "<br>" + question.getContent() + "</div></html>");
|
|
|
|
|
|
|
|
|
|
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("<html><div style='text-align: center;'>" +
|
|
|
|
|
"得分: <font color='" + getHexColor(color) + "'><b>" + percentScore + "分</b></font><br>" +
|
|
|
|
|
"(" + score + "/" + totalQuestions + ")<br>" +
|
|
|
|
|
"<font size='5'>" + comment + "</font></div></html>");
|
|
|
|
|
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);
|
|
|
|
|
|