import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
class User {
private String password;
private String phone;
private String studentId; // 新增学号字段
public User(String password, String phone) {
this.password = password;
this.phone = phone;
}
// 新增带学号的构造方法
public User(String password, String phone, String studentId) {
this.password = password;
this.phone = phone;
this.studentId = studentId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
// 新增学号getter
public String getStudentId() {
return studentId;
}
}
class LoginFrame extends JFrame {
private JComboBox<String> userTypeComboBox;
private JTextField usernameField;
private JPasswordField passwordField;
private Map<String, User> studentAccounts = new HashMap<>();
private Map<String, User> teacherAccounts = new HashMap<>();
private Map<String, User> adminAccounts = new HashMap<>(); // 新增管理员账号映射
private static final String ADMIN_USERNAME = "1";
private static final String ADMIN_PASSWORD = "123";
private static final String STUDENT_FILE = "students.txt";
private static final String TEACHER_FILE = "teachers.txt";
private static final String ADMIN_FILE = "admin.txt";
private JButton registerButton;
private JButton forgotPasswordButton;
public LoginFrame() {
setTitle("学生选课系统 - 登录");
setSize(400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
gbc.fill = GridBagConstraints.HORIZONTAL;
// 用户类型选择
gbc.gridx = 0;
gbc.gridy = 0;
panel.add(new JLabel("用户类型:"), gbc);
gbc.gridx = 1;
userTypeComboBox = new JComboBox<>(new String[]{"学生", "教师", "管理员"});
userTypeComboBox.addActionListener(this::updateRegisterButton);
panel.add(userTypeComboBox, gbc);
// 用户名
gbc.gridx = 0;
gbc.gridy = 1;
panel.add(new JLabel("用户名:"), gbc);
gbc.gridx = 1;
usernameField = new JTextField(15);
panel.add(usernameField, gbc);
// 密码
gbc.gridx = 0;
gbc.gridy = 2;
panel.add(new JLabel("密码:"), gbc);
gbc.gridx = 1;
passwordField = new JPasswordField(15);
panel.add(passwordField, gbc);
// 登录按钮
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.CENTER;
JButton loginButton = new JButton("登录");
loginButton.addActionListener(this::performLogin);
panel.add(loginButton, gbc);
// 注册按钮
gbc.gridy = 4;
registerButton = new JButton("学生注册"); // 改为成员变量
registerButton.addActionListener(this::performRegister);
panel.add(registerButton, gbc);
// 忘记密码按钮
gbc.gridy = 5;
forgotPasswordButton = new JButton("忘记密码"); // 改为成员变量
forgotPasswordButton.addActionListener(this::performForgotPassword);
panel.add(forgotPasswordButton, gbc);
add(panel);
// 加载账号信息
loadAccounts();
// 初始更新按钮状态
updateButtonVisibility();
}
private void updateButtonVisibility() {
String userType = (String) userTypeComboBox.getSelectedItem();
boolean isAdmin = "管理员".equals(userType);
registerButton.setText(userType + "注册");
registerButton.setVisible(!isAdmin);
forgotPasswordButton.setVisible(!isAdmin); // 管理员时隐藏忘记密码按钮
}
private void loadAccounts() {
// 加载学生账号
try (BufferedReader reader = new BufferedReader(new FileReader(STUDENT_FILE))) {
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",");
if (parts.length >= 4) {
// 新顺序:用户名,学号,密码,手机号
studentAccounts.put(parts[0], new User(parts[2], parts[3], parts[1]));
}
}
} catch (IOException e) {
// 文件不存在是正常的,首次运行时会创建
}
// 加载教师账号
try (BufferedReader reader = new BufferedReader(new FileReader(TEACHER_FILE))) {
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",");
if (parts.length == 3) {
teacherAccounts.put(parts[0], new User(parts[1], parts[2]));
}
}
} catch (IOException e) {
// 文件不存在是正常的
}
// 加载管理员账号
loadAdminAccounts();
}
private void loadAdminAccounts() {
try (BufferedReader reader = new BufferedReader(new FileReader(ADMIN_FILE))) {
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",");
if (parts.length >= 2) {
// 格式:用户名,密码
String phone = parts.length > 2 ? parts[2] : ""; // 手机号可选
adminAccounts.put(parts[0], new User(parts[1], phone));
}
}
} catch (IOException e) {
// 首次运行时创建默认管理员账号
saveAdminAccount();
}
}
private void saveStudentAccounts() {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(STUDENT_FILE))) {
for (Map.Entry<String, User> entry : studentAccounts.entrySet()) {
User user = entry.getValue();
// 修改保存顺序:用户名、学号、密码、手机号
writer.write(entry.getKey() + "," + user.getStudentId() + "," + user.getPassword() + "," + user.getPhone());
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void saveTeacherAccounts() {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(TEACHER_FILE))) {
for (Map.Entry<String, User> entry : teacherAccounts.entrySet()) {
writer.write(entry.getKey() + "," + entry.getValue().getPassword() + "," + entry.getValue().getPhone());
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void saveAdminAccount() {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(ADMIN_FILE))) {
// 保存默认管理员账号
adminAccounts.put(ADMIN_USERNAME, new User(ADMIN_PASSWORD, ""));
for (Map.Entry<String, User> entry : adminAccounts.entrySet()) {
writer.write(entry.getKey() + "," + entry.getValue().getPassword());
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void updateRegisterButton(ActionEvent e) {
updateButtonVisibility(); // 改为调用统一更新方法
}
private void performLogin(ActionEvent e) {
String userType = (String) userTypeComboBox.getSelectedItem();
String username = usernameField.getText().trim();
String password = new String(passwordField.getPassword()).trim();
if (username.isEmpty() || password.isEmpty()) {
showErrorMessage("用户名和密码不能为空");
return;
}
if ("管理员".equals(userType)) {
// 从adminAccounts中验证管理员账号
User admin = adminAccounts.get(username);
if (admin != null && admin.getPassword().equals(password)) {
showSuccessMessage("管理员登录成功!");
new AdminFrame(username).setVisible(true);
dispose();
} else {
showErrorMessage("管理员账号或密码错误");
}
return;
}
boolean isValid = false;
Map<String, User> accounts = "学生".equals(userType) ? studentAccounts : teacherAccounts;
User user = accounts.get(username);
if (user != null && user.getPassword().equals(password)) {
isValid = true;
}
if (isValid) {
showSuccessMessage("登录成功!");
if ("学生".equals(userType)) {
new StudentFrame(username).setVisible(true);
} else {
new TeacherFrame(username).setVisible(true);
}
dispose();
} else {
showErrorMessage("用户名或密码错误");
}
}
private void performRegister(ActionEvent e) {
String userType = (String) userTypeComboBox.getSelectedItem();
showRegisterDialog(userType);
}
private void showRegisterDialog(String userType) {
JDialog dialog = new JDialog(this, userType + "注册", true);
// 改为使用GridBagLayout以便动态显示学号字段
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
// 注册类型标签
panel.add(new JLabel("注册类型:"), gbc);
gbc.gridx = 1;
JLabel typeValue = new JLabel(userType);
panel.add(typeValue, gbc);
// 用户名
gbc.gridy++;
gbc.gridx = 0;
panel.add(new JLabel("用户名:"), gbc);
gbc.gridx = 1;
JTextField userField = new JTextField(15);
panel.add(userField, gbc);
// 新增学号字段(仅对学生显示)
JLabel studentIdLabel = new JLabel("学号:");
JTextField studentIdField = new JTextField(15);
gbc.gridy++;
gbc.gridx = 0;
panel.add(studentIdLabel, gbc);
gbc.gridx = 1;
panel.add(studentIdField, gbc);
studentIdLabel.setVisible("学生".equals(userType));
studentIdField.setVisible("学生".equals(userType));
// 密码
gbc.gridy++;
gbc.gridx = 0;
panel.add(new JLabel("密码:"), gbc);
gbc.gridx = 1;
JPasswordField passField = new JPasswordField(15);
panel.add(passField, gbc);
// 确认密码
gbc.gridy++;
gbc.gridx = 0;
panel.add(new JLabel("确认密码:"), gbc);
gbc.gridx = 1;
JPasswordField confirmField = new JPasswordField(15);
panel.add(confirmField, gbc);
// 手机号
gbc.gridy++;
gbc.gridx = 0;
panel.add(new JLabel("手机号:"), gbc);
gbc.gridx = 1;
JTextField phoneField = new JTextField(15);
panel.add(phoneField, gbc);
// 按钮面板
gbc.gridy++;
gbc.gridx = 0;
gbc.gridwidth = 2;
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
JButton registerBtn = new JButton("注册");
JButton cancelBtn = new JButton("取消");
buttonPanel.add(registerBtn);
buttonPanel.add(cancelBtn);
panel.add(buttonPanel, gbc);
dialog.add(panel);
registerBtn.addActionListener(e -> {
String username = userField.getText().trim();
String password = new String(passField.getPassword()).trim();
String confirm = new String(confirmField.getPassword()).trim();
String phone = phoneField.getText().trim();
String studentId = studentIdField.getText().trim(); // 获取学号
if (username.isEmpty() || password.isEmpty() || phone.isEmpty()) {
showErrorMessage(dialog, "所有字段不能为空");
return;
}
// 学生注册时需要验证学号
if ("学生".equals(userType)) {
if (studentId.isEmpty()) {
showErrorMessage(dialog, "学号不能为空");
return;
}
if (!studentId.matches("\\d{8,12}")) {
showErrorMessage(dialog, "学号必须是8-12位数字");
return;
}
}
if (!password.equals(confirm)) {
showErrorMessage(dialog, "两次输入的密码不一致");
return;
}
if (!phone.matches("^1[3-9]\\d{9}$")) {
showErrorMessage(dialog, "手机号格式不正确");
return;
}
Map<String, User> accounts = "学生".equals(userType) ? studentAccounts : teacherAccounts;
if (accounts.containsKey(username)) {
showErrorMessage(dialog, "用户名已存在");
return;
}
// 创建用户对象时包含学号
User newUser = "学生".equals(userType) ?
new User(password, phone, studentId) :
new User(password, phone);
accounts.put(username, newUser);
if ("学生".equals(userType)) {
saveStudentAccounts();
} else {
saveTeacherAccounts();
}
showSuccessMessage(dialog, userType + "注册成功!");
dialog.dispose();
});
cancelBtn.addActionListener(e -> dialog.dispose());
dialog.pack();
dialog.setLocationRelativeTo(this);
dialog.setVisible(true);
}
private void performForgotPassword(ActionEvent e) {
JDialog dialog = new JDialog(this, "忘记密码", true);
dialog.setLayout(new GridLayout(4, 2, 10, 10));
JComboBox<String> typeCombo = new JComboBox<>(new String[]{"学生", "教师"});
JTextField usernameField = new JTextField();
JTextField phoneField = new JTextField();
JButton submitBtn = new JButton("提交");
submitBtn.addActionListener(ev -> {
String userType = (String) typeCombo.getSelectedItem();
String username = usernameField.getText().trim();
String phone = phoneField.getText().trim();
Map<String, User> accounts = "学生".equals(userType) ? studentAccounts : teacherAccounts;
User user = accounts.get(username);
if (user == null || !user.getPhone().equals(phone)) {
showErrorMessage(dialog, "用户名或手机号错误");
return;
}
dialog.dispose();
showResetPasswordDialog(userType, username);
});
dialog.add(new JLabel("用户类型:"));
dialog.add(typeCombo);
dialog.add(new JLabel("用户名:"));
dialog.add(usernameField);
dialog.add(new JLabel("手机号:"));
dialog.add(phoneField);
dialog.add(new JLabel());
dialog.add(submitBtn);
dialog.pack();
dialog.setLocationRelativeTo(this);
dialog.setVisible(true);
}
private void showResetPasswordDialog(String userType, String username) {
JDialog dialog = new JDialog(this, "重置密码", true);
dialog.setLayout(new GridLayout(3, 2, 10, 10));
JPasswordField newPassField = new JPasswordField();
JPasswordField confirmField = new JPasswordField();
JButton submitBtn = new JButton("提交");
submitBtn.addActionListener(e -> {
String newPass = new String(newPassField.getPassword()).trim();
String confirm = new String(confirmField.getPassword()).trim();
if (!newPass.equals(confirm)) {
showErrorMessage(dialog, "两次输入的密码不一致");
return;
}
Map<String, User> accounts = "学生".equals(userType) ? studentAccounts : teacherAccounts;
User user = accounts.get(username);
user.setPassword(newPass);
if ("学生".equals(userType)) {
saveStudentAccounts();
} else {
saveTeacherAccounts();
}
showSuccessMessage(dialog, "密码重置成功!");
dialog.dispose();
});
dialog.add(new JLabel("新密码:"));
dialog.add(newPassField);
dialog.add(new JLabel("确认密码:"));
dialog.add(confirmField);
dialog.add(new JLabel());
dialog.add(submitBtn);
dialog.pack();
dialog.setLocationRelativeTo(this);
dialog.setVisible(true);
}
private void showErrorMessage(String message) {
JOptionPane.showMessageDialog(this, message, "错误", JOptionPane.ERROR_MESSAGE);
}
private void showSuccessMessage(String message) {
JOptionPane.showMessageDialog(this, message, "成功", JOptionPane.INFORMATION_MESSAGE);
}
private void showErrorMessage(JDialog parent, String message) {
JOptionPane.showMessageDialog(parent, message, "错误", JOptionPane.ERROR_MESSAGE);
}
private void showSuccessMessage(JDialog parent, String message) {
JOptionPane.showMessageDialog(parent, message, "成功", JOptionPane.INFORMATION_MESSAGE);
}
}
关键代码片段及注释,markdown的形式输出给我