You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX中loadScene与initialize无限循环问题求助

问题分析与修复方案

核心问题根源

  1. 无限循环加载:StoryController的initialize方法中,遍历故事列表时反复调用loadScene(currentStory + 1),而loadScene会加载新的FXML并创建新的StoryController实例,新实例的initialize又会再次触发loadScene,形成无限递归,导致持续打印FXML路径。
  2. FXML路径空指针:资源路径使用错误,getClass().getResource()的路径格式与文件实际位置不匹配,导致返回null,触发空指针异常。

修复步骤

1. 终止无限循环

修改StoryController的initialize方法,移除自动调用loadScene的逻辑,仅负责初始化当前故事的UI内容:

@FXML
public void initialize() {
    // 仅初始化第一个故事的UI,不自动切换场景
    if (!stories.isEmpty()) {
        Story firstStory = stories.get(currentStory);
        titleLabel.setText(firstStory.getTitle());
        storyDescriptionLabel.setText(firstStory.getStoryDescription());
    }
}

场景切换逻辑应通过用户交互(如按钮点击)触发,而非初始化时自动执行。例如添加一个切换故事的方法:

@FXML
private void switchToNextStory() {
    if (currentStory + 1 < stories.size()) {
        currentStory++;
        loadScene(currentStory + 1);
    }
}

并在对应的FXML中添加按钮绑定此方法。

2. 修正FXML资源路径

  • 绝对路径 vs 相对路径:
    • 绝对路径(以/开头):从资源根目录(通常是src/main/resources)开始查找,例如"/PACKAGE_NAME/src/main/project/classes/Story1.fxml"。
    • 相对路径(无/):相对于当前类的包路径查找,例如StoryController在PACKAGE_NAME.src.main.project.classes包下,若Story1.fxml与该类同目录,直接用"Story1.fxml"即可。
  • 统一路径格式:
    修改StoryController的loadScene方法路径:
    private void loadScene(int storyNumber) {
        try {
            // 使用相对路径(假设FXML与当前类同目录)
            String fxmlFile = "Story" + storyNumber + ".fxml";
            URL url = getClass().getResource(fxmlFile);
            if (url == null) {
                throw new IOException("FXML文件未找到:" + fxmlFile);
            }
            Parent root = FXMLLoader.load(url);
            Stage stage = (Stage) titleLabel.getScene().getWindow();
            stage.setScene(new Scene(root));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    同时修正LibraryController的路径,确保与文件位置匹配:
    @FXML
    public void spil(ActionEvent event) {
        try {
            // 确保路径正确,此处使用相对路径示例
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Story1.fxml"));
            Parent root = loader.load();
            Scene scene = new Scene(root);
            Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow();
            stage.setScene(scene);
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

3. 优化故事文件读取逻辑

避免依赖本地文件路径,改用资源流读取故事文件,增强代码可移植性:

private void loadStoriesFromFile() {
    try (BufferedReader reader = new BufferedReader(
            new InputStreamReader(getClass().getResourceAsStream("/Stories/Story.txt")))) {
        String line;
        while ((line = reader.readLine()) != null) {
            String[] parts = line.split(",");
            if (parts.length >= 2) {
                String title = parts[0];
                String storyDescription = parts[1];
                stories.add(new Story(title, storyDescription));
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

同时修改构造函数:

public StoryController() {
    loadStoriesFromFile();
}

额外注意事项

  • 确保所有FXML文件已正确放置在src/main/resources目录下,包结构与控制器类对应。
  • 解锁第二个故事的逻辑需单独实现(如标记第一个故事完成状态),避免自动切换导致循环。

内容的提问来源于stack exchange,提问作者onuk98

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 21:34:54