package user; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.border.EmptyBorder; import publicway.buttonset; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; public class ZhaohuiMima extends JDialog { private JTextField emailField; private JTextField codeField; private JPasswordField passwordField; private JPasswordField confirmPasswordField; private JButton getCodeButton; private JButton saveButton; private JLabel tipLabel; private Timer timer; private int countdown = 60; private String generatedCode; // 存储生成的验证码 // 主题颜色 (参考 Denglu.java) private final Color THEME_COLOR = new Color(46, 139, 87); private final Color THEME_HOVER_COLOR = new Color(30, 107, 69); public ZhaohuiMima(Frame owner) { super(owner, "找回密码", true); setSize(400, 350); setLocationRelativeTo(owner); setResizable(false); initializeUI(); } private void initializeUI() { JPanel mainPanel = new JPanel(); mainPanel.setLayout(new GridBagLayout()); mainPanel.setBorder(new EmptyBorder(20, 20, 20, 20)); mainPanel.setBackground(Color.WHITE); setContentPane(mainPanel); GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(5, 5, 5, 5); gbc.fill = GridBagConstraints.HORIZONTAL; // 邮箱 JLabel emailLabel = new JLabel("邮箱:"); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0.1; mainPanel.add(emailLabel, gbc); emailField = new JTextField(); styleTextField(emailField); gbc.gridx = 1; gbc.gridy = 0; gbc.weightx = 0.9; gbc.gridwidth = 2; mainPanel.add(emailField, gbc); // 验证码 JLabel codeLabel = new JLabel("验证码:"); gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 1; gbc.weightx = 0.1; mainPanel.add(codeLabel, gbc); codeField = new JTextField(); styleTextField(codeField); gbc.gridx = 1; gbc.gridy = 1; gbc.weightx = 0.6; mainPanel.add(codeField, gbc); getCodeButton = new JButton("获取验证码"); styleButton(getCodeButton); getCodeButton.setFont(new Font("微软雅黑", Font.PLAIN, 12)); // 调整按钮高度以匹配文本框 getCodeButton.setPreferredSize(new Dimension(100, 38)); gbc.gridx = 2; gbc.gridy = 1; gbc.weightx = 0.3; mainPanel.add(getCodeButton, gbc); // 新密码 JLabel passwordLabel = new JLabel("新密码:"); gbc.gridx = 0; gbc.gridy = 2; gbc.weightx = 0.1; mainPanel.add(passwordLabel, gbc); JPanel passwordPanel = createPasswordPanel(); passwordField = (JPasswordField) passwordPanel.getComponent(0); gbc.gridx = 1; gbc.gridy = 2; gbc.gridwidth = 2; gbc.weightx = 0.9; mainPanel.add(passwordPanel, gbc); // 确认密码 JLabel confirmPasswordLabel = new JLabel("确认密码:"); gbc.gridx = 0; gbc.gridy = 3; gbc.gridwidth = 1; gbc.weightx = 0.1; mainPanel.add(confirmPasswordLabel, gbc); JPanel confirmPasswordPanel = createPasswordPanel(); confirmPasswordField = (JPasswordField) confirmPasswordPanel.getComponent(0); gbc.gridx = 1; gbc.gridy = 3; gbc.gridwidth = 2; gbc.weightx = 0.9; mainPanel.add(confirmPasswordPanel, gbc); // 提示信息 tipLabel = new JLabel("密码6-25个字符"); tipLabel.setForeground(Color.GRAY); tipLabel.setFont(new Font("微软雅黑", Font.PLAIN, 10)); gbc.gridx = 1; gbc.gridy = 4; gbc.gridwidth = 2; mainPanel.add(tipLabel, gbc); // 保存按钮 saveButton = buttonset.createStyledButton("保存密码", THEME_COLOR); gbc.gridx = 0; gbc.gridy = 5; gbc.gridwidth = 3; gbc.insets = new Insets(20, 5, 5, 5); mainPanel.add(saveButton, gbc); // 事件监听 setupEvents(); } private void styleTextField(JTextField field) { field.setPreferredSize(new Dimension(0, 38)); // 宽度由GridBagLayout控制,高度设为38 field.setFont(new Font("PingFang SC", Font.PLAIN, 14)); field.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(new Color(200, 200, 200)), BorderFactory.createEmptyBorder(8, 10, 8, 10) )); field.setForeground(new Color(60, 60, 60)); } private void styleButton(JButton button) { button.setBackground(THEME_COLOR); button.setForeground(Color.WHITE); button.setFocusPainted(false); button.setBorderPainted(false); button.setFont(new Font("微软雅黑", Font.BOLD, 14)); button.setCursor(new Cursor(Cursor.HAND_CURSOR)); button.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseEntered(java.awt.event.MouseEvent evt) { if (button.isEnabled()) { button.setBackground(THEME_HOVER_COLOR); } } public void mouseExited(java.awt.event.MouseEvent evt) { if (button.isEnabled()) { button.setBackground(THEME_COLOR); } } }); } private void setupEvents() { getCodeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String email = emailField.getText().trim(); if (email.isEmpty()) { JOptionPane.showMessageDialog(ZhaohuiMima.this, "请输入邮箱", "提示", JOptionPane.WARNING_MESSAGE); return; } // 这里应该添加发送验证码的逻辑 // 模拟生成验证码 generatedCode = String.valueOf((int)((Math.random() * 9 + 1) * 100000)); startCountdown(); JOptionPane.showMessageDialog(ZhaohuiMima.this, "验证码已发送: " + generatedCode, "提示", JOptionPane.INFORMATION_MESSAGE); } }); // 实时验证密码一致性 DocumentListener passwordListener = new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { checkPasswordMatch(); } @Override public void removeUpdate(DocumentEvent e) { checkPasswordMatch(); } @Override public void changedUpdate(DocumentEvent e) { checkPasswordMatch(); } }; passwordField.getDocument().addDocumentListener(passwordListener); confirmPasswordField.getDocument().addDocumentListener(passwordListener); saveButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { savePassword(); } }); } private void checkPasswordMatch() { String pass = new String(passwordField.getPassword()); String confirm = new String(confirmPasswordField.getPassword()); if (pass.isEmpty()) { tipLabel.setText("密码6-25个字符"); tipLabel.setForeground(Color.GRAY); return; } // 先判断新密码长度 if (pass.length() < 6) { tipLabel.setText("密码长度不能少于6个字符"); tipLabel.setForeground(Color.RED); return; } else if (pass.length() > 25) { tipLabel.setText("密码长度不能超过25个字符"); tipLabel.setForeground(Color.RED); return; } // 如果确认密码为空,提示输入 if (confirm.isEmpty()) { tipLabel.setText("密码6-25个字符"); tipLabel.setForeground(Color.GRAY); return; } // 只有当确认密码长度和新密码长度一致时,才进行比对 if (pass.length() == confirm.length()) { if (!pass.equals(confirm)) { tipLabel.setText("两次输入的密码不一致"); tipLabel.setForeground(Color.RED); } else { tipLabel.setText("密码一致"); tipLabel.setForeground(new Color(46, 139, 87)); // Green } } else { // 长度不一致时,恢复默认提示,避免在输入过程中一直提示不一致 tipLabel.setText("密码6-25个字符"); tipLabel.setForeground(Color.GRAY); } } private void startCountdown() { getCodeButton.setEnabled(false); getCodeButton.setBackground(Color.GRAY); countdown = 60; getCodeButton.setText(countdown + "秒"); timer = new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { countdown--; if (countdown > 0) { getCodeButton.setText(countdown + "秒"); } else { timer.stop(); getCodeButton.setText("获取验证码"); getCodeButton.setEnabled(true); getCodeButton.setBackground(THEME_COLOR); } } }); timer.start(); } private void savePassword() { String email = emailField.getText().trim(); String code = codeField.getText().trim(); String password = new String(passwordField.getPassword()); String confirmPassword = new String(confirmPasswordField.getPassword()); if (email.isEmpty()) { JOptionPane.showMessageDialog(this, "请输入邮箱", "错误", JOptionPane.ERROR_MESSAGE); return; } if (code.isEmpty()) { JOptionPane.showMessageDialog(this, "请输入验证码", "错误", JOptionPane.ERROR_MESSAGE); return; } // 验证验证码 if (generatedCode == null || !generatedCode.equals(code)) { JOptionPane.showMessageDialog(this, "验证码错误", "错误", JOptionPane.ERROR_MESSAGE); return; } if (password.length() < 6) { JOptionPane.showMessageDialog(this, "密码长度不能少于6个字符", "错误", JOptionPane.ERROR_MESSAGE); return; } if (password.length() > 25) { JOptionPane.showMessageDialog(this, "密码长度不能超过25个字符", "错误", JOptionPane.ERROR_MESSAGE); return; } if (!password.equals(confirmPassword)) { JOptionPane.showMessageDialog(this, "两次输入的密码不一致", "错误", JOptionPane.ERROR_MESSAGE); return; } // 验证邮箱是否匹配 (可选,根据需求) String savedEmail = Usrdell.getProperty("email"); if (savedEmail != null && !savedEmail.equals(email)) { // 这里假设必须匹配已存邮箱,或者这是一个新功能允许任意邮箱找回? // 通常找回密码需要匹配账号绑定的邮箱 // 如果本地没有存邮箱,或者输入的邮箱不对 // JOptionPane.showMessageDialog(this, "邮箱不匹配", "错误", JOptionPane.ERROR_MESSAGE); // return; } // 这里应该验证验证码是否正确 // ... // 保存密码 try { Usrdell.updateProperty("password", password); JOptionPane.showMessageDialog(this, "密码修改成功", "成功", JOptionPane.INFORMATION_MESSAGE); dispose(); } catch (Exception ex) { JOptionPane.showMessageDialog(this, "保存失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE); } } private JPanel createPasswordPanel() { JPanel panel = new JPanel(new BorderLayout()); panel.setBackground(Color.WHITE); JPasswordField pf = new JPasswordField(); styleTextField(pf); // 移除右边框,为了和眼睛按钮无缝连接 pf.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createMatteBorder(1, 1, 1, 0, new Color(200, 200, 200)), BorderFactory.createEmptyBorder(8, 10, 8, 5) )); JToggleButton eyeButton = new JToggleButton("👁"); eyeButton.setPreferredSize(new Dimension(40, 38)); eyeButton.setBackground(Color.WHITE); eyeButton.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, new Color(200, 200, 200))); eyeButton.setFocusPainted(false); eyeButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); eyeButton.setFont(new Font("Segoe UI Symbol", Font.PLAIN, 16)); // 确保支持Unicode字符 eyeButton.addActionListener(e -> { if (eyeButton.isSelected()) { pf.setEchoChar((char) 0); // 显示密码 } else { pf.setEchoChar('•'); // 隐藏密码 (默认字符) } }); panel.add(pf, BorderLayout.CENTER); panel.add(eyeButton, BorderLayout.EAST); return panel; } }