我们的申请背景(如果您认为不相关,可以跳过): 我们正在为自闭症儿童创建一个应用程序来识别和理解手势和面部表情。我们通过呈现一个故事来做到这一点,然后给他们一个任务,在不同的手势和面部表情之间切换,以尝试绘制他们认为故事中的角色具有或感觉的表情和手势。然后我们有一个反思页面,孩子和老师可以反思或讨论自闭症孩子所做的选择,然后他们可以回去尝试不同的面部表情和手势。如果他们对结果感到满意,他们可以结束任务,第一个故事完成,第二个故事将在图书馆中解锁。我们的故事在两个故事中都只包含一个角色。只是在不同的场景下。
我们的代码问题:
我们现在的代码没有打开 FXML 文件,而是在无限循环中打印 FXML 文件路径,我们认为这是因为 StoryController 类的初始化方法中存在问题。具体来说,loadScene 方法在循环中被重复调用,导致 FXML 文件被一遍又一遍地加载(我们认为)。那么我们应该如何解决这个问题呢?我们尝试询问各种 AI 工具并查找 Java 等中的 FXML 文档。有一次,循环被随机修复,然后我们的 Story FXML 文件的 URL 出现了 nullpointerException。 我们几乎没有其他类,但它们还没有构建,所以这是我们实现过程的第一步,在解决这个问题之前我们不能再进一步......任何帮助将不胜感激。谢谢
这是我们的 StoryController 代码,其中包含加载场景和初始化方法:
package PACKAGE_NAME.src.main.project.classes;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
public class StoryController {
@FXML
private Label titleLabel;
@FXML
private Label storyDescriptionLabel;
private int currentStory = 0;
private List<Story> stories = new ArrayList<>();
public StoryController() {
loadStoriesFromFile("src/main/project/classes/Stories/Story.txt");
}
public List<Story> getStories() {
return stories;
}
/**
* @param filename This method reads the stories from a file and adds them to the stories list.
* It seperates the title and the story description by a comma.
*/
private void loadStoriesFromFile(String filename) {
// The method uses a try-with-resources statement to ensure that the BufferedReader is closed after it's no longer needed. This is a good practice to avoid resource leaks.
try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
String line;
Story previousStory = null;
// While loop to read the file line by line
while ((line = reader.readLine()) != null) {
// Each line is split into parts using a comma (,) as the delimiter.
String[] parts = line.split(",");
// The first part is considered the title, and the second part is considered the story description.
String title = parts[0];
String storyDescription = parts[1];
// A new Story object is created using the extracted title and story description.
Story story = new Story(title, storyDescription);
// Then add the newly created story object to the "stories" ArrayList.
stories.add(story);
}
// If any IOException occurs during the file reading process, it's caught and the error message is printed to the console.
// IOException is typically thrown when an error occurs while performing input or output operations, such as reading or writing to a file
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* if the story list is not empty, it sets the title and story description of the first story
* in the list to the corresponding labels.
*/
@FXML
public void initialize() {
// Check if the stories ArrayList is not empty
if (!stories.isEmpty()) {
for (int i = 0; i < stories.size(); i++) {
String title = stories.get(i).getTitle();
titleLabel.setText(title);
storyDescriptionLabel.setText(stories.get(i).getStoryDescription());
// Load the scene for the story
loadScene(currentStory + 1);
}
}
}
private void loadScene(int storyNumber) {
try {
// Append the story number to the ".fxml"
String fxmlFile = "/Story" + storyNumber + ".fxml";
System.out.println("Loading FXML file: " + fxmlFile);
URL url = getClass().getResource(fxmlFile);
System.out.println(url);
// Load the FXML file
Parent root = FXMLLoader.load(url);
// Get the current stage
Stage stage = (Stage) titleLabel.getScene().getWindow();
// Set the new scene
stage.setScene(new Scene(root));
} catch (IOException e) {
e.printStackTrace();
}
}
}
此外,我们还有这个 LibraryController 类(如果相关): 我们应用程序中的库供用户在故事之间进行选择。 (我们只会实施两个)
package PACKAGE_NAME.src.main.project.classes;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.event.ActionEvent;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.Objects;
public class LibraryController {
@FXML
private GridPane gridPane;
@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();
}
}
}
我不确定我是否很好地理解这个问题,但似乎您在循环内调用 loadScene 方法,但它始终从相同的值加载...currentStory + 1,并且 currentStory 始终设置为零并且在整个程序中不会改变它的值