package ui; import model.Grade; import model.UserManager; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import java.awt.Dimension; import java.awt.Frame; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.io.Serial; import java.util.regex.Pattern; /** * 密码设置对话框 * 用于新用户注册时设置密码和选择年级 */ public class PasswordSetupDialog extends JDialog { @Serial private static final long serialVersionUID = 1L; private static final Pattern PASSWORD_PATTERN = Pattern.compile("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z0-9]{6,10}$"); private final JTextField usernameField; private final JPasswordField password1Field; private final JPasswordField password2Field; private final JComboBox gradeComboBox; private final JButton confirmButton; private final UserManager userManager; private final String email; private boolean registrationComplete; /** * 构造密码设置对话框 * * @param parent 父窗口 * @param userManager 用户管理器 * @param email 用户邮箱 */ public PasswordSetupDialog(Frame parent, UserManager userManager, String email) { super(parent, "设置密码和用户名", true); this.userManager = userManager; this.email = email; this.registrationComplete = false; setSize(600, 420); setLocationRelativeTo(parent); setResizable(true); JPanel panel = new JPanel(new GridBagLayout()); panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(5, 5, 5, 5); gbc.fill = GridBagConstraints.HORIZONTAL; JLabel infoLabel = new JLabel("密码要求:
" + "1. 长度 6-10位
" + "2. 必须包含大写字母
" + "3. 必须包含小写字母
" + "4. 必须包含数字
" + "5. 不能包含其他特殊字符"); infoLabel.setFont(new Font("微软雅黑", Font.PLAIN, 11)); gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 2; panel.add(infoLabel, gbc); gbc.gridwidth = 1; gbc.gridy = 1; panel.add(new JLabel("输入密码:"), gbc); password1Field = new JPasswordField(20); gbc.gridx = 1; gbc.weightx = 1.0; panel.add(password1Field, gbc); gbc.weightx = 0.0; gbc.gridx = 0; gbc.gridy = 2; panel.add(new JLabel("确认密码:"), gbc); password2Field = new JPasswordField(20); gbc.gridx = 1; gbc.weightx = 1.0; panel.add(password2Field, gbc); gbc.weightx = 0.0; gbc.gridx = 0; gbc.gridy = 3; panel.add(new JLabel("设置用户名:"), gbc); usernameField = new JTextField(20); gbc.gridx = 1; gbc.weightx = 1.0; panel.add(usernameField, gbc); gbc.weightx = 0.0; gbc.gridx = 0; gbc.gridy = 4; panel.add(new JLabel("选择年级:"), gbc); String[] grades = {"小学", "初中", "高中"}; gradeComboBox = new JComboBox<>(grades); gbc.gridx = 1; gbc.weightx = 1.0; panel.add(gradeComboBox, gbc); gbc.weightx = 0.0; confirmButton = new JButton("确认注册"); confirmButton.setPreferredSize(new Dimension(120, 30)); gbc.gridx = 0; gbc.gridy = 5; gbc.gridwidth = 2; gbc.anchor = GridBagConstraints.CENTER; panel.add(confirmButton, gbc); add(panel); confirmButton.addActionListener(e -> handleConfirm()); getRootPane().setDefaultButton(confirmButton); } /** * 处理确认注册 */ private void handleConfirm() { String password1 = new String(password1Field.getPassword()); String password2 = new String(password2Field.getPassword()); String username = usernameField.getText().trim(); if (username.isEmpty() || password1.isEmpty() || password2.isEmpty()) { showError("用户名和密码不能为空"); return; } if (userManager.usernameExists(username)) { showError("该用户名已被使用,请更换一个"); return; } if (!password1.equals(password2)) { showError("两次输入的密码不一致"); return; } if (!PASSWORD_PATTERN.matcher(password1).matches()) { showError("密码不符合要求:\n" + "长度6-10位, 必须包含大小写字母和数字, 且不能包含特殊字符"); return; } Grade gradeType = getSelectedGradeType(); boolean success = userManager.register(email, password1, gradeType, username); if (success) { JOptionPane.showMessageDialog(this, "注册成功!请返回登录。", "成功", JOptionPane.INFORMATION_MESSAGE); registrationComplete = true; dispose(); } else { showError("注册失败,该邮箱可能已被注册"); } } /** * 获取选择的年级类型 * * @return 年级类型 */ private Grade getSelectedGradeType() { String selected = (String) gradeComboBox.getSelectedItem(); switch (selected) { case "小学": return Grade.primary; case "初中": return Grade.middle; case "高中": return Grade.high; default: return Grade.primary; } } /** * 显示错误信息 * * @param message 错误消息 */ private void showError(String message) { JOptionPane.showMessageDialog(this, message, "错误", JOptionPane.ERROR_MESSAGE); } /** * 检查注册是否完成 * * @return 注册是否完成 */ public boolean isRegistrationComplete() { return registrationComplete; } }