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