You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
math-learing/src/main/java/com/personalproject/ui/scenes/RegistrationScene.java

264 lines
8.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.personalproject.ui.scenes;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import com.personalproject.controller.MathLearningController;
import com.personalproject.model.DifficultyLevel;
import com.personalproject.ui.scenes.LoginScene;
/**
* Scene for handling user registration.
*/
public class RegistrationScene extends BorderPane {
private final Stage primaryStage;
private final MathLearningController controller;
private TextField usernameField;
private TextField emailField;
private ComboBox<DifficultyLevel> difficultyComboBox;
private Button sendCodeButton;
private TextField registrationCodeField;
private Button verifyCodeButton;
private PasswordField passwordField;
private PasswordField confirmPasswordField;
private Button setPasswordButton;
private Button backButton;
private VBox registrationForm;
/**
* Constructor for RegistrationScene.
*
* @param primaryStage The main stage of the application
* @param controller The math learning controller
*/
public RegistrationScene(Stage primaryStage, MathLearningController controller) {
this.primaryStage = primaryStage;
this.controller = controller;
initializeUI();
}
/**
* Initializes the UI components.
*/
private void initializeUI() {
// Create the main layout
VBox mainLayout = new VBox(15);
mainLayout.setAlignment(Pos.CENTER);
mainLayout.setPadding(new Insets(20));
// Title
Label titleLabel = new Label("用户注册");
titleLabel.setFont(Font.font("System", FontWeight.BOLD, 24));
// Registration Form
registrationForm = new VBox(15);
registrationForm.setAlignment(Pos.CENTER);
// Step 1: Basic Info
GridPane basicInfoForm = new GridPane();
basicInfoForm.setHgap(10);
basicInfoForm.setVgap(10);
basicInfoForm.setAlignment(Pos.CENTER);
Label usernameLabel = new Label("用户名:");
usernameField = new TextField();
usernameField.setPrefWidth(200);
Label emailLabel = new Label("邮箱:");
emailField = new TextField();
emailField.setPrefWidth(200);
Label difficultyLabel = new Label("默认难度:");
difficultyComboBox = new ComboBox<>();
difficultyComboBox.getItems().addAll(DifficultyLevel.PRIMARY, DifficultyLevel.MIDDLE, DifficultyLevel.HIGH);
difficultyComboBox.setValue(DifficultyLevel.PRIMARY);
difficultyComboBox.setPrefWidth(200);
basicInfoForm.add(usernameLabel, 0, 0);
basicInfoForm.add(usernameField, 1, 0);
basicInfoForm.add(emailLabel, 0, 1);
basicInfoForm.add(emailField, 1, 1);
basicInfoForm.add(difficultyLabel, 0, 2);
basicInfoForm.add(difficultyComboBox, 1, 2);
sendCodeButton = new Button("发送注册码");
sendCodeButton.setPrefWidth(120);
registrationForm.getChildren().addAll(basicInfoForm, sendCodeButton);
// Step 2: Verification (hidden initially)
VBox verificationSection = new VBox(10);
verificationSection.setAlignment(Pos.CENTER);
verificationSection.setVisible(false);
verificationSection.setManaged(false);
Label codeLabel = new Label("注册码:");
registrationCodeField = new TextField();
registrationCodeField.setPrefWidth(200);
verifyCodeButton = new Button("验证注册码");
verifyCodeButton.setPrefWidth(120);
verificationSection.getChildren().addAll(codeLabel, registrationCodeField, verifyCodeButton);
registrationForm.getChildren().add(verificationSection);
// Step 3: Password Setting (hidden initially)
VBox passwordSection = new VBox(10);
passwordSection.setAlignment(Pos.CENTER);
passwordSection.setVisible(false);
passwordSection.setManaged(false);
Label passwordLabel = new Label("设置密码 (6-10位包含大小写字母和数字):");
passwordField = new PasswordField();
passwordField.setPrefWidth(200);
Label confirmPasswordLabel = new Label("确认密码:");
confirmPasswordField = new PasswordField();
confirmPasswordField.setPrefWidth(200);
setPasswordButton = new Button("设置密码");
setPasswordButton.setPrefWidth(120);
passwordSection.getChildren().addAll(passwordLabel, passwordField, confirmPasswordLabel,
confirmPasswordField, setPasswordButton);
registrationForm.getChildren().add(passwordSection);
// Back button
backButton = new Button("返回");
backButton.setPrefWidth(100);
// Add components to main layout
mainLayout.getChildren().addAll(titleLabel, registrationForm, backButton);
setCenter(mainLayout);
// Add event handlers
addEventHandlers(sendCodeButton, verificationSection, verifyCodeButton, passwordSection);
}
/**
* Adds event handlers to UI components.
*/
private void addEventHandlers(Button sendCodeButton, VBox verificationSection,
Button verifyCodeButton, VBox passwordSection) {
sendCodeButton.setOnAction(e -> handleSendCode(verificationSection));
verifyCodeButton.setOnAction(e -> handleVerifyCode(passwordSection));
setPasswordButton.setOnAction(e -> handleSetPassword());
backButton.setOnAction(e -> handleBack());
}
/**
* Handles sending registration code.
*/
private void handleSendCode(VBox verificationSection) {
String username = usernameField.getText().trim();
String email = emailField.getText().trim();
DifficultyLevel difficultyLevel = difficultyComboBox.getValue();
if (username.isEmpty() || email.isEmpty()) {
showAlert(Alert.AlertType.WARNING, "警告", "请输入用户名和邮箱");
return;
}
if (!controller.isValidEmail(email)) {
showAlert(Alert.AlertType.ERROR, "邮箱格式错误", "请输入有效的邮箱地址");
return;
}
// Initiate registration
boolean success = controller.initiateRegistration(username, email, difficultyLevel);
if (success) {
showAlert(Alert.AlertType.INFORMATION, "注册码已发送", "注册码已发送至您的邮箱,请查收。");
verificationSection.setVisible(true);
verificationSection.setManaged(true);
} else {
showAlert(Alert.AlertType.ERROR, "注册失败", "用户名或邮箱可能已存在,请重试。");
}
}
/**
* Handles verification of registration code.
*/
private void handleVerifyCode(VBox passwordSection) {
String username = usernameField.getText().trim();
String registrationCode = registrationCodeField.getText().trim();
if (registrationCode.isEmpty()) {
showAlert(Alert.AlertType.WARNING, "警告", "请输入注册码");
return;
}
boolean verified = controller.verifyRegistrationCode(username, registrationCode);
if (verified) {
showAlert(Alert.AlertType.INFORMATION, "验证成功", "注册码验证成功!");
passwordSection.setVisible(true);
passwordSection.setManaged(true);
} else {
showAlert(Alert.AlertType.ERROR, "验证失败", "注册码验证失败,请检查后重试。");
}
}
/**
* Handles setting the user password.
*/
private void handleSetPassword() {
String username = usernameField.getText().trim();
String password = passwordField.getText();
String confirmPassword = confirmPasswordField.getText();
if (password.isEmpty() || confirmPassword.isEmpty()) {
showAlert(Alert.AlertType.WARNING, "警告", "请输入并确认密码");
return;
}
if (!password.equals(confirmPassword)) {
showAlert(Alert.AlertType.ERROR, "密码不匹配", "两次输入的密码不一致");
return;
}
if (!controller.isValidPassword(password)) {
showAlert(Alert.AlertType.ERROR, "密码不符合要求",
"密码长度必须为6-10位且包含大小写字母和数字");
return;
}
boolean success = controller.setPassword(username, password);
if (success) {
showAlert(Alert.AlertType.INFORMATION, "注册成功", "注册成功!请登录。");
handleBack(); // Go back to login screen
} else {
showAlert(Alert.AlertType.ERROR, "设置密码失败", "设置密码失败,请重试。");
}
}
/**
* Handles the back button action.
*/
private void handleBack() {
LoginScene loginScene = new LoginScene(primaryStage, controller);
primaryStage.getScene().setRoot(loginScene);
}
/**
* Shows an alert dialog.
*
* @param alertType Type of alert
* @param title Title of the alert
* @param message Message to display
*/
private void showAlert(Alert.AlertType alertType, String title, String message) {
Alert alert = new Alert(alertType);
alert.setTitle(title);
alert.setHeaderText(null);
alert.setContentText(message);
alert.showAndWait();
}
}