package denglu; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.HashMap; import java.util.Map; public class RegistrationFrame extends JFrame { private JTextField userField; private JTextField emailField; private JTextField verificationCodeField; private JPasswordField passField; private JPasswordField confirmPassField; private JButton registerButton; private JButton cancelButton; private JButton sendCodeButton; private JLabel userLabel, emailLabel, verificationCodeLabel, passLabel, confirmPassLabel; // 主题颜色 private final Color THEME_COLOR = new Color(46, 139, 87); private final Color THEME_HOVER_COLOR = new Color(30, 107, 69); // 多语言支持 private Map> translations; private String currentLanguageCode; private Denglu parentFrame; // 验证码相关 private Timer countdownTimer; private int countdownSeconds = 60; private String generatedVerificationCode; public RegistrationFrame(Denglu parent, String languageCode) { this.parentFrame = parent; this.currentLanguageCode = languageCode; initializeTranslations(); initializeUI(); setupEventHandlers(); } private void initializeTranslations() { translations = new HashMap<>(); // 中文翻译 Map zh = new HashMap<>(); zh.put("title", "用户注册"); zh.put("username_label", "用户名"); zh.put("email_label", "邮箱地址"); zh.put("verification_code_label", "验证码"); zh.put("password_label", "密码"); zh.put("confirm_password_label", "确认密码"); zh.put("register_button", "注册"); zh.put("cancel_button", "取消"); zh.put("send_code_button", "发送验证码"); zh.put("resend_code_button", "重新发送"); zh.put("success_message", "注册成功!"); zh.put("empty_fields_error", "请填写所有字段"); zh.put("password_mismatch_error", "两次输入的密码不一致"); zh.put("verification_code_sent", "验证码已发送到您的邮箱"); zh.put("invalid_verification_code", "验证码错误"); zh.put("countdown_format", "秒后重新发送"); zh.put("invalid_email_error", "请输入有效的邮箱地址"); zh.put("password_length_error", "密码长度不能少于6位"); translations.put("zh", zh); // 英文翻译 Map en = new HashMap<>(); en.put("title", "User Registration"); en.put("username_label", "Username"); en.put("email_label", "Email Address"); en.put("verification_code_label", "Verification Code"); en.put("password_label", "Password"); en.put("confirm_password_label", "Confirm Password"); en.put("register_button", "Register"); en.put("cancel_button", "Cancel"); en.put("send_code_button", "Send Code"); en.put("resend_code_button", "Resend"); en.put("success_message", "Registration successful!"); en.put("empty_fields_error", "Please fill in all fields"); en.put("password_mismatch_error", "Passwords do not match"); en.put("verification_code_sent", "Verification code sent to your email"); en.put("invalid_verification_code", "Invalid verification code"); en.put("countdown_format", "s to resend"); en.put("invalid_email_error", "Please enter a valid email address"); en.put("password_length_error", "Password must be at least 6 characters"); translations.put("en", en); // 西班牙语翻译 Map es = new HashMap<>(); es.put("title", "Registro de Usuario"); es.put("username_label", "Usuario"); es.put("email_label", "Correo Electrónico"); es.put("verification_code_label", "Código de Verificación"); es.put("password_label", "Contraseña"); es.put("confirm_password_label", "Confirmar Contraseña"); es.put("register_button", "Registrar"); es.put("cancel_button", "Cancelar"); es.put("send_code_button", "Enviar Código"); es.put("resend_code_button", "Reenviar"); es.put("success_message", "¡Registro exitoso!"); es.put("empty_fields_error", "Por favor complete todos los campos"); es.put("password_mismatch_error", "Las contraseñas no coinciden"); es.put("verification_code_sent", "Código de verificación enviado a su correo"); es.put("invalid_verification_code", "Código de verificación incorrecto"); es.put("countdown_format", "s para reenviar"); es.put("invalid_email_error", "Por favor ingrese una dirección de correo válida"); es.put("password_length_error", "La contraseña debe tener al menos 6 caracteres"); translations.put("es", es); // 法语翻译 Map fr = new HashMap<>(); fr.put("title", "Inscription Utilisateur"); fr.put("username_label", "Nom d'utilisateur"); fr.put("email_label", "Adresse Email"); fr.put("verification_code_label", "Code de Vérification"); fr.put("password_label", "Mot de passe"); fr.put("confirm_password_label", "Confirmer le mot de passe"); fr.put("register_button", "S'inscrire"); fr.put("cancel_button", "Annuler"); fr.put("send_code_button", "Envoyer le code"); fr.put("resend_code_button", "Renvoyer"); fr.put("success_message", "Inscription réussie!"); fr.put("empty_fields_error", "Veuillez remplir tous les champs"); fr.put("password_mismatch_error", "Les mots de passe ne correspondent pas"); fr.put("verification_code_sent", "Code de vérification envoyé à votre email"); fr.put("invalid_verification_code", "Code de vérification incorrect"); fr.put("countdown_format", "s pour renvoyer"); fr.put("invalid_email_error", "Veuillez entrer une adresse email valide"); fr.put("password_length_error", "Le mot de passe doit comporter au moins 6 caractères"); translations.put("fr", fr); // 德语翻译 Map de = new HashMap<>(); de.put("title", "Benutzerregistrierung"); de.put("username_label", "Benutzername"); de.put("email_label", "E-Mail-Adresse"); de.put("verification_code_label", "Verifizierungscode"); de.put("password_label", "Passwort"); de.put("confirm_password_label", "Passwort bestätigen"); de.put("register_button", "Registrieren"); de.put("cancel_button", "Abbrechen"); de.put("send_code_button", "Code senden"); de.put("resend_code_button", "Erneut senden"); de.put("success_message", "Registrierung erfolgreich!"); de.put("empty_fields_error", "Bitte füllen Sie alle Felder aus"); de.put("password_mismatch_error", "Passwörter stimmen nicht überein"); de.put("verification_code_sent", "Verifizierungscode an Ihre E-Mail gesendet"); de.put("invalid_verification_code", "Ungültiger Verifizierungscode"); de.put("countdown_format", "s zum erneuten Senden"); de.put("invalid_email_error", "Bitte geben Sie eine gültige E-Mail-Adresse ein"); de.put("password_length_error", "Das Passwort muss mindestens 6 Zeichen lang sein"); translations.put("de", de); } private void initializeUI() { setTitle("AutoMow - 用户注册"); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setSize(350, 500); setLocationRelativeTo(parentFrame); setResizable(false); setupUI(); updateLanguage(currentLanguageCode); } private void setupUI() { JPanel mainPanel = new JPanel(new BorderLayout()); mainPanel.setBackground(Color.WHITE); mainPanel.setBorder(BorderFactory.createEmptyBorder(15, 20, 15, 20)); // 创建滚动面板 JScrollPane scrollPane = new JScrollPane(); scrollPane.setBorder(BorderFactory.createEmptyBorder()); scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); scrollPane.getVerticalScrollBar().setUnitIncrement(16); // 表单面板 JPanel formPanel = new JPanel(); formPanel.setLayout(new BoxLayout(formPanel, BoxLayout.Y_AXIS)); formPanel.setBackground(Color.WHITE); formPanel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(new Color(230, 230, 230)), BorderFactory.createEmptyBorder(20, 20, 20, 20) )); // 用户名 - 标签左对齐 userLabel = new JLabel("用户名"); userLabel.setFont(new Font("PingFang SC", Font.BOLD, 13)); userLabel.setForeground(THEME_COLOR); userLabel.setAlignmentX(Component.LEFT_ALIGNMENT); userField = new JTextField(); userField.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35)); userField.setFont(new Font("PingFang SC", Font.PLAIN, 14)); userField.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(new Color(200, 200, 200)), BorderFactory.createEmptyBorder(5, 8, 5, 8) )); userField.setAlignmentX(Component.LEFT_ALIGNMENT); // 邮箱 - 标签左对齐 emailLabel = new JLabel("邮箱地址"); emailLabel.setFont(new Font("PingFang SC", Font.BOLD, 13)); emailLabel.setForeground(THEME_COLOR); emailLabel.setAlignmentX(Component.LEFT_ALIGNMENT); emailField = new JTextField(); emailField.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35)); emailField.setFont(new Font("PingFang SC", Font.PLAIN, 14)); emailField.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(new Color(200, 200, 200)), BorderFactory.createEmptyBorder(5, 8, 5, 8) )); emailField.setAlignmentX(Component.LEFT_ALIGNMENT); // 验证码 - 标签左对齐 verificationCodeLabel = new JLabel("验证码"); verificationCodeLabel.setFont(new Font("PingFang SC", Font.BOLD, 13)); verificationCodeLabel.setForeground(THEME_COLOR); verificationCodeLabel.setAlignmentX(Component.LEFT_ALIGNMENT); // 验证码输入框 - 单独一行 verificationCodeField = new JTextField(); verificationCodeField.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35)); verificationCodeField.setFont(new Font("PingFang SC", Font.PLAIN, 14)); verificationCodeField.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(new Color(200, 200, 200)), BorderFactory.createEmptyBorder(5, 8, 5, 8) )); verificationCodeField.setAlignmentX(Component.LEFT_ALIGNMENT); // 发送验证码按钮 - 单独一行 sendCodeButton = new JButton("发送验证码"); sendCodeButton.setBackground(THEME_COLOR); sendCodeButton.setForeground(Color.WHITE); sendCodeButton.setFont(new Font("PingFang SC", Font.BOLD, 14)); sendCodeButton.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35)); sendCodeButton.setBorderPainted(false); sendCodeButton.setFocusPainted(false); sendCodeButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); sendCodeButton.setAlignmentX(Component.LEFT_ALIGNMENT); // 验证码按钮悬停效果 sendCodeButton.addMouseListener(new MouseAdapter() { public void mouseEntered(MouseEvent e) { if (sendCodeButton.isEnabled()) { sendCodeButton.setBackground(THEME_HOVER_COLOR); } } public void mouseExited(MouseEvent e) { if (sendCodeButton.isEnabled()) { sendCodeButton.setBackground(THEME_COLOR); } } }); // 密码 - 标签左对齐 passLabel = new JLabel("密码"); passLabel.setFont(new Font("PingFang SC", Font.BOLD, 13)); passLabel.setForeground(THEME_COLOR); passLabel.setAlignmentX(Component.LEFT_ALIGNMENT); passField = new JPasswordField(); passField.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35)); passField.setFont(new Font("PingFang SC", Font.PLAIN, 14)); passField.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(new Color(200, 200, 200)), BorderFactory.createEmptyBorder(5, 8, 5, 8) )); passField.setAlignmentX(Component.LEFT_ALIGNMENT); // 确认密码 - 标签左对齐 confirmPassLabel = new JLabel("确认密码"); confirmPassLabel.setFont(new Font("PingFang SC", Font.BOLD, 13)); confirmPassLabel.setForeground(THEME_COLOR); confirmPassLabel.setAlignmentX(Component.LEFT_ALIGNMENT); confirmPassField = new JPasswordField(); confirmPassField.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35)); confirmPassField.setFont(new Font("PingFang SC", Font.PLAIN, 14)); confirmPassField.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(new Color(200, 200, 200)), BorderFactory.createEmptyBorder(5, 8, 5, 8) )); confirmPassField.setAlignmentX(Component.LEFT_ALIGNMENT); // 注册按钮 - 单独一行,长度与文本框相同 registerButton = new JButton("注册"); registerButton.setBackground(THEME_COLOR); registerButton.setForeground(Color.WHITE); registerButton.setFont(new Font("PingFang SC", Font.BOLD, 14)); registerButton.setMaximumSize(new Dimension(Integer.MAX_VALUE, 40)); registerButton.setBorderPainted(false); registerButton.setFocusPainted(false); registerButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); registerButton.setAlignmentX(Component.LEFT_ALIGNMENT); // 注册按钮悬停效果 registerButton.addMouseListener(new MouseAdapter() { public void mouseEntered(MouseEvent e) { registerButton.setBackground(THEME_HOVER_COLOR); } public void mouseExited(MouseEvent e) { registerButton.setBackground(THEME_COLOR); } }); // 取消按钮 - 单独一行,长度与文本框相同 cancelButton = new JButton("取消"); cancelButton.setBackground(Color.LIGHT_GRAY); cancelButton.setForeground(Color.DARK_GRAY); cancelButton.setFont(new Font("PingFang SC", Font.BOLD, 14)); cancelButton.setMaximumSize(new Dimension(Integer.MAX_VALUE, 40)); cancelButton.setBorderPainted(false); cancelButton.setFocusPainted(false); cancelButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); cancelButton.setAlignmentX(Component.LEFT_ALIGNMENT); // 组装表单 - 缩小行间距 formPanel.add(userLabel); formPanel.add(Box.createRigidArea(new Dimension(0, 3))); formPanel.add(userField); formPanel.add(Box.createRigidArea(new Dimension(0, 10))); formPanel.add(emailLabel); formPanel.add(Box.createRigidArea(new Dimension(0, 3))); formPanel.add(emailField); formPanel.add(Box.createRigidArea(new Dimension(0, 10))); formPanel.add(verificationCodeLabel); formPanel.add(Box.createRigidArea(new Dimension(0, 3))); formPanel.add(verificationCodeField); formPanel.add(Box.createRigidArea(new Dimension(0, 5))); formPanel.add(sendCodeButton); formPanel.add(Box.createRigidArea(new Dimension(0, 10))); formPanel.add(passLabel); formPanel.add(Box.createRigidArea(new Dimension(0, 3))); formPanel.add(passField); formPanel.add(Box.createRigidArea(new Dimension(0, 10))); formPanel.add(confirmPassLabel); formPanel.add(Box.createRigidArea(new Dimension(0, 3))); formPanel.add(confirmPassField); formPanel.add(Box.createRigidArea(new Dimension(0, 20))); formPanel.add(registerButton); formPanel.add(Box.createRigidArea(new Dimension(0, 8))); formPanel.add(cancelButton); // 设置滚动面板的视图 scrollPane.setViewportView(formPanel); mainPanel.add(scrollPane, BorderLayout.CENTER); add(mainPanel); } private void setupEventHandlers() { // 注册按钮事件 registerButton.addActionListener(e -> performRegistration()); // 取消按钮事件 cancelButton.addActionListener(e -> dispose()); // 发送验证码按钮事件 sendCodeButton.addActionListener(e -> sendVerificationCode()); // 回车键注册 confirmPassField.addActionListener(e -> performRegistration()); } private void updateLanguage(String languageCode) { Map translation = translations.get(languageCode); if (translation != null) { // 更新所有界面文本 setTitle("AutoMow - " + translation.get("title")); userLabel.setText(translation.get("username_label")); emailLabel.setText(translation.get("email_label")); verificationCodeLabel.setText(translation.get("verification_code_label")); passLabel.setText(translation.get("password_label")); confirmPassLabel.setText(translation.get("confirm_password_label")); registerButton.setText(translation.get("register_button")); cancelButton.setText(translation.get("cancel_button")); sendCodeButton.setText(translation.get("send_code_button")); } } // 邮箱验证方法 private boolean isValidEmail(String email) { // 简单的邮箱格式验证 String emailRegex = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$"; return email != null && email.matches(emailRegex); } // 发送验证码 private void sendVerificationCode() { String email = emailField.getText().trim(); if (email.isEmpty()) { JOptionPane.showMessageDialog(this, "请输入邮箱地址", "输入错误", JOptionPane.WARNING_MESSAGE); emailField.requestFocus(); return; } // 验证邮箱格式 if (!isValidEmail(email)) { // 获取当前语言的翻译 Map translationMap = translations.get(currentLanguageCode); String errorMessage = translationMap != null ? translationMap.get("invalid_email_error") : "请输入有效的邮箱地址"; JOptionPane.showMessageDialog(this, errorMessage, "输入错误", JOptionPane.WARNING_MESSAGE); emailField.requestFocus(); return; } // 生成随机验证码(实际应用中应该通过邮件发送) generatedVerificationCode = generateRandomCode(); // 在实际应用中,这里应该调用邮件发送服务 // 这里仅模拟发送过程 System.out.println("验证码 " + generatedVerificationCode + " 已发送到 " + email); // 获取当前语言的翻译 Map translationMap = translations.get(currentLanguageCode); if (translationMap != null) { JOptionPane.showMessageDialog(this, translationMap.get("verification_code_sent"), "提示", JOptionPane.INFORMATION_MESSAGE); } else { JOptionPane.showMessageDialog(this, "验证码已发送到您的邮箱", "提示", JOptionPane.INFORMATION_MESSAGE); } // 开始倒计时 startCountdown(); } // 生成随机验证码 private String generateRandomCode() { // 生成6位随机数字 return String.valueOf((int)((Math.random() * 9 + 1) * 100000)); } // 开始倒计时 private void startCountdown() { sendCodeButton.setEnabled(false); countdownSeconds = 60; if (countdownTimer != null) { countdownTimer.stop(); } countdownTimer = new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Map translation = translations.get(currentLanguageCode); String countdownText = translation != null ? translation.get("countdown_format") : "秒后重新发送"; sendCodeButton.setText(countdownSeconds + countdownText); countdownSeconds--; if (countdownSeconds < 0) { countdownTimer.stop(); sendCodeButton.setEnabled(true); String resendText = translation != null ? translation.get("resend_code_button") : "重新发送"; sendCodeButton.setText(resendText); } } }); countdownTimer.start(); } // 公开方法,用于从父窗口更新语言 public void setLanguage(String languageCode) { this.currentLanguageCode = languageCode; updateLanguage(languageCode); } private void performRegistration() { String username = userField.getText().trim(); String email = emailField.getText().trim(); String verificationCode = verificationCodeField.getText().trim(); String password = new String(passField.getPassword()); String confirmPassword = new String(confirmPassField.getPassword()); // 获取当前语言的翻译 Map translationMap = translations.get(currentLanguageCode); // 输入验证 if (username.isEmpty() || email.isEmpty() || verificationCode.isEmpty() || password.isEmpty() || confirmPassword.isEmpty()) { String errorMessage = translationMap != null ? translationMap.get("empty_fields_error") : "请填写所有字段"; JOptionPane.showMessageDialog(this, errorMessage, "输入错误", JOptionPane.WARNING_MESSAGE); return; } // 验证邮箱格式 if (!isValidEmail(email)) { String errorMessage = translationMap != null ? translationMap.get("invalid_email_error") : "请输入有效的邮箱地址"; JOptionPane.showMessageDialog(this, errorMessage, "输入错误", JOptionPane.WARNING_MESSAGE); emailField.requestFocus(); return; } // 验证密码长度 if (password.length() < 6) { String errorMessage = translationMap != null ? translationMap.get("password_length_error") : "密码长度不能少于6位"; JOptionPane.showMessageDialog(this, errorMessage, "输入错误", JOptionPane.WARNING_MESSAGE); passField.setText(""); confirmPassField.setText(""); passField.requestFocus(); return; } // 验证验证码 if (!verificationCode.equals(generatedVerificationCode)) { String errorMessage = translationMap != null ? translationMap.get("invalid_verification_code") : "验证码错误"; JOptionPane.showMessageDialog(this, errorMessage, "输入错误", JOptionPane.WARNING_MESSAGE); verificationCodeField.setText(""); verificationCodeField.requestFocus(); return; } if (!password.equals(confirmPassword)) { String errorMessage = translationMap != null ? translationMap.get("password_mismatch_error") : "两次输入的密码不一致"; JOptionPane.showMessageDialog(this, errorMessage, "输入错误", JOptionPane.WARNING_MESSAGE); passField.setText(""); confirmPassField.setText(""); passField.requestFocus(); return; } // 保存用户信息 UserChuShiHua.updateProperty("userName", username); UserChuShiHua.updateProperty("email", email); UserChuShiHua.updateProperty("password", password); String successMessage = translationMap != null ? translationMap.get("success_message") : "注册成功!"; JOptionPane.showMessageDialog(this, successMessage, "成功", JOptionPane.INFORMATION_MESSAGE); dispose(); // 自动填充登录表单 if (parentFrame != null) { // 这里需要访问父窗口的usernameField,但由于封装性,我们可能需要添加公共方法 // 暂时留空,可以根据需要实现 } } @Override public void dispose() { // 停止计时器 if (countdownTimer != null) { countdownTimer.stop(); } super.dispose(); } }