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