From c384fea9013c45c3f505f9070efaae8dc5b6bd87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=8D=9A=E6=96=87?= <15549487+FX_YBW@user.noreply.gitee.com> Date: Sat, 11 Oct 2025 23:58:40 +0800 Subject: [PATCH] =?UTF-8?q?v2.3=20=E4=BF=AE=E5=A4=8DLevelSelectionView?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wsf/mathapp/view/LevelSelectionView.java | 254 +++++++++++++----- 1 file changed, 187 insertions(+), 67 deletions(-) diff --git a/src/main/java/com/wsf/mathapp/view/LevelSelectionView.java b/src/main/java/com/wsf/mathapp/view/LevelSelectionView.java index b9a7092..b35c1a3 100644 --- a/src/main/java/com/wsf/mathapp/view/LevelSelectionView.java +++ b/src/main/java/com/wsf/mathapp/view/LevelSelectionView.java @@ -16,6 +16,10 @@ import javafx.scene.text.Font; import javafx.scene.text.FontWeight; import javafx.scene.text.Text; +/** + * 级别选择视图类,提供用户选择题目难度级别的界面. + * 包含小学、初中、高中三个难度级别的选择按钮. + */ public class LevelSelectionView { private Scene scene; private final SceneManager sceneManager; @@ -25,12 +29,20 @@ public class LevelSelectionView { private Label usernameLabel; private Text avatarText; + /** + * 构造函数,初始化级别选择视图. + * + * @param sceneManager 场景管理器,用于界面导航. + */ public LevelSelectionView(SceneManager sceneManager) { this.sceneManager = sceneManager; this.currentUsername = sceneManager.getCurrentUserName(); createScene(); } + /** + * 创建主场景,包含用户信息栏和级别选择内容. + */ private void createScene() { // 创建主容器 VBox mainContainer = new VBox(); @@ -47,31 +59,45 @@ public class LevelSelectionView { scene = new Scene(mainContainer, 450, 550); } + /** + * 创建用户信息栏,包含用户头像和用户名显示. + * + * @return HBox 用户信息栏布局容器. + */ private HBox createUserInfoBar() { HBox userInfoBar = new HBox(15); userInfoBar.setAlignment(Pos.CENTER_LEFT); userInfoBar.setPadding(new Insets(0, 0, 30, 0)); - userInfoBar.setStyle("-fx-border-color: #e0e0e0; -fx-border-width: 0 0 1 0; -fx-padding: 0 0 15 0;"); + userInfoBar.setStyle("-fx-border-color: #e0e0e0; " + + "-fx-border-width: 0 0 1 0; -fx-padding: 0 0 15 0;"); + // 用户名标签 + usernameLabel = new Label(currentUsername != null ? currentUsername : "用户"); + usernameLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16)); + usernameLabel.setStyle("-fx-text-fill: #2c3e50;"); + // 间隔 + Region spacer = new Region(); + HBox.setHgrow(spacer, Priority.ALWAYS); + // 创建头像容器 + VBox avatarContainer = createAvatarContainer(); + userInfoBar.getChildren().addAll(avatarContainer, usernameLabel, spacer); + return userInfoBar; + } - // 创建圆形头像容器 + /** + * 创建头像容器,包含圆形头像背景和用户首字母. + * + * @return VBox 头像容器布局. + */ + private VBox createAvatarContainer() { VBox avatarContainer = new VBox(); avatarContainer.setAlignment(Pos.CENTER); avatarContainer.setPrefSize(50, 50); - - // 创建圆形头像背景 - Circle avatarCircle = new Circle(22); - avatarCircle.setFill(Color.web("#4CAF50")); // 统一的绿色背景 - avatarCircle.setStroke(Color.WHITE); - avatarCircle.setStrokeWidth(2); - - // 添加阴影效果 - avatarCircle.setStyle("-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 5, 0.3, 2, 2);"); - // 添加首字母文本 avatarText = new Text(getFirstLetter()); avatarText.setFill(Color.WHITE); avatarText.setFont(Font.font("Arial", FontWeight.BOLD, 16)); - + // 创建圆形头像背景 + Circle avatarCircle = createAvatarCircle(); // 使用StackPane将文本放在圆形中心 javafx.scene.layout.StackPane avatarStack = new javafx.scene.layout.StackPane(); avatarStack.getChildren().addAll(avatarCircle, avatarText); @@ -79,101 +105,190 @@ public class LevelSelectionView { avatarStack.setAlignment(Pos.CENTER); avatarContainer.getChildren().add(avatarStack); + return avatarContainer; + } - // 用户名标签 - usernameLabel = new Label(currentUsername != null ? currentUsername : "用户"); - usernameLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16)); - usernameLabel.setStyle("-fx-text-fill: #2c3e50;"); - - // 间隔 - Region spacer = new Region(); - HBox.setHgrow(spacer, Priority.ALWAYS); - - userInfoBar.getChildren().addAll(avatarContainer, usernameLabel, spacer); + /** + * 创建圆形头像背景. + * + * @return Circle 圆形头像背景对象. + */ + private Circle createAvatarCircle() { + Circle avatarCircle = new Circle(22); + avatarCircle.setFill(Color.web("#4CAF50")); // 统一的绿色背景 + avatarCircle.setStroke(Color.WHITE); + avatarCircle.setStrokeWidth(2); - return userInfoBar; + // 添加阴影效果 + avatarCircle.setStyle("-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 5, 0.3, 2, 2);"); + return avatarCircle; } + /** + * 创建级别选择内容区域,包含标题和级别选择按钮. + * + * @return VBox 级别选择内容区域布局容器. + */ private VBox createSelectionContent() { VBox selectionContent = new VBox(25); selectionContent.setPadding(new Insets(30, 20, 20, 20)); selectionContent.setAlignment(Pos.CENTER); + // 创建标题区域 + VBox titleSection = createTitleSection(); + + // 创建级别按钮区域 + VBox levelButtonsSection = createLevelButtonsSection(); + + // 创建返回按钮 + Button backButton = createBackButton(); + + selectionContent.getChildren().addAll(titleSection, levelButtonsSection, backButton); + + return selectionContent; + } + + /** + * 创建标题区域,包含主标题和副标题. + * + * @return VBox 标题区域布局容器. + */ + private VBox createTitleSection() { + VBox titleSection = new VBox(5); + titleSection.setAlignment(Pos.CENTER); + Label titleLabel = new Label("选择题目级别"); titleLabel.setFont(Font.font("Arial", FontWeight.BOLD, 26)); titleLabel.setStyle("-fx-text-fill: #2c3e50;"); - // 添加副标题 Label subtitleLabel = new Label("请选择适合您的学习级别"); subtitleLabel.setFont(Font.font("Arial", 14)); subtitleLabel.setStyle("-fx-text-fill: #7f8c8d; -fx-padding: 0 0 10 0;"); + titleSection.getChildren().addAll(titleLabel, subtitleLabel); + return titleSection; + } + + /** + * 创建级别按钮区域,包含三个难度级别的选择按钮. + * + * @return VBox 级别按钮区域布局容器. + */ + private VBox createLevelButtonsSection() { + VBox levelButtonsSection = new VBox(15); + levelButtonsSection.setAlignment(Pos.CENTER); + Button primaryButton = createLevelButton("小学题目", "#4CAF50", "#45a049"); Button juniorButton = createLevelButton("初中题目", "#2196F3", "#1976D2"); Button seniorButton = createLevelButton("高中题目", "#9C27B0", "#7B1FA2"); - Button backButton = new Button("返回主菜单"); - backButton.setStyle("-fx-background-color: #95a5a6; -fx-text-fill: white; -fx-font-size: 14px; -fx-background-radius: 8; -fx-padding: 8 20;"); - backButton.setPrefSize(180, 45); - backButton.setOnMouseEntered(e -> backButton.setStyle("-fx-background-color: #7f8c8d; -fx-text-fill: white; -fx-font-size: 14px; -fx-background-radius: 8; -fx-padding: 8 20;")); - backButton.setOnMouseExited(e -> backButton.setStyle("-fx-background-color: #95a5a6; -fx-text-fill: white; -fx-font-size: 14px; -fx-background-radius: 8; -fx-padding: 8 20;")); + setupLevelButtonAction(primaryButton, "小学"); + setupLevelButtonAction(juniorButton, "初中"); + setupLevelButtonAction(seniorButton, "高中"); - primaryButton.setOnAction(e -> { - String selectedLevel = "小学"; - sceneManager.getQuestionCountView().setLevel(selectedLevel); - sceneManager.showQuestionCountView(); - }); - - juniorButton.setOnAction(e -> { - String selectedLevel = "初中"; - sceneManager.getQuestionCountView().setLevel(selectedLevel); - sceneManager.showQuestionCountView(); - }); + levelButtonsSection.getChildren().addAll(primaryButton, juniorButton, seniorButton); + return levelButtonsSection; + } - seniorButton.setOnAction(e -> { - String selectedLevel = "高中"; - sceneManager.getQuestionCountView().setLevel(selectedLevel); + /** + * 设置级别按钮的点击事件. + * + * @param button 级别按钮. + * @param level 对应的难度级别. + */ + private void setupLevelButtonAction(Button button, String level) { + button.setOnAction(e -> { + sceneManager.getQuestionCountView().setLevel(level); sceneManager.showQuestionCountView(); }); + } - backButton.setOnAction(e -> { - sceneManager.showMainMenuView(); - }); - - selectionContent.getChildren().addAll( - titleLabel, subtitleLabel, primaryButton, juniorButton, seniorButton, backButton - ); + /** + * 创建返回按钮. + * + * @return Button 返回主菜单按钮. + */ + private Button createBackButton() { + Button backButton = new Button("返回主菜单"); + backButton.setStyle("-fx-background-color: #95a5a6; -fx-text-fill: " + + "white; -fx-font-size: 14px; -fx-background-radius: 8; -fx-padding: 8 20;"); + backButton.setPrefSize(180, 45); + setupButtonHoverEffect(backButton, "#95a5a6", "#7f8c8d"); + backButton.setOnAction(e -> sceneManager.showMainMenuView()); - return selectionContent; + return backButton; } + /** + * 创建级别选择按钮. + * + * @param text 按钮显示文本. + * @param color 按钮正常状态颜色. + * @param hoverColor 按钮悬停状态颜色. + * @return Button 配置好的级别选择按钮. + */ private Button createLevelButton(String text, String color, String hoverColor) { Button button = new Button(text); button.setStyle(String.format( - "-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: 16px; -fx-font-weight: bold; " + - "-fx-background-radius: 12; -fx-padding: 12 30; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 8, 0.3, 2, 2);", + "-fx-background-color: %s; -fx-text-fill: " + + "white; -fx-font-size: 16px; -fx-font-weight: bold;-fx-background-radius: 12;" + + "-fx-padding: 12 30;-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 8, 0.3, 2, 2);", color )); button.setPrefSize(220, 60); - button.setOnMouseEntered(e -> button.setStyle(String.format( - "-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: 16px; -fx-font-weight: bold; " + - "-fx-background-radius: 12; -fx-padding: 12 30; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 10, 0.4, 3, 3);", - hoverColor - ))); - button.setOnMouseExited(e -> button.setStyle(String.format( - "-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: 16px; -fx-font-weight: bold; " + - "-fx-background-radius: 12; -fx-padding: 12 30; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 8, 0.3, 2, 2);", - color - ))); + + setupButtonHoverEffect(button, color, hoverColor); + return button; } + /** + * 设置按钮的悬停效果. + * + * @param button 需要设置悬停效果的按钮. + * @param normalColor 正常状态颜色. + * @param hoverColor 悬停状态颜色. + */ + private void setupButtonHoverEffect(Button button, String normalColor, String hoverColor) { + String normalStyle = String.format( + "-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: %s;" + + " -fx-background-radius: %s; -fx-padding: %s; -fx-effect: " + + "dropshadow(gaussian, rgba(0,0,0,0.2), 8, 0.3, 2, 2);", + normalColor, + button.getStyle().contains("16px") ? "16px" : "14px", + button.getStyle().contains("12") ? "12" : "8", + button.getStyle().contains("12 30") ? "12 30" : "8 20" + ); + + String hoverStyle = String.format( + "-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: %s;" + + " -fx-background-radius: %s; -fx-padding: %s; -fx-effect:" + + " dropshadow(gaussian, rgba(0,0,0,0.3), 10, 0.4, 3, 3);", + hoverColor, + button.getStyle().contains("16px") ? "16px" : "14px", + button.getStyle().contains("12") ? "12" : "8", + button.getStyle().contains("12 30") ? "12 30" : "8 20" + ); + + button.setOnMouseEntered(e -> button.setStyle(hoverStyle)); + button.setOnMouseExited(e -> button.setStyle(normalStyle)); + } + + /** + * 获取用户名的首字母,用于头像显示. + * + * @return String 用户名的首字母大写,如果用户名为空则返回"U". + */ private String getFirstLetter() { - return currentUsername != null && !currentUsername.isEmpty() ? - currentUsername.substring(0, 1).toUpperCase() : "U"; + return currentUsername != null && !currentUsername.isEmpty() + ? currentUsername.substring(0, 1).toUpperCase() : "U"; } - // 添加更新用户名的方法 + /** + * 更新用户名显示. + * + * @param username 新的用户名. + */ public void updateUsername(String username) { this.currentUsername = username; if (usernameLabel != null) { @@ -184,6 +299,11 @@ public class LevelSelectionView { } } + /** + * 获取当前场景. + * + * @return Scene 级别选择界面的场景对象. + */ public Scene getScene() { return scene; }