我目前正在构建一个简单的应用程序来读取 .txt 文件并可视化场景上的 3D 点。
这是我当前的代码:
----------Main.java----------
import controllers.ImportMenuController;
import controllers.MainController;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader mainLoader = new FXMLLoader(getClass().getResource("FXML/Main.fxml"));
Parent root = mainLoader.load();
MainController mainController = mainLoader.getController();
FXMLLoader importMenuLoader = new FXMLLoader(getClass().getResource("FXML/ImportMenu.fxml"));
importMenuLoader.load();
ImportMenuController importMenuController = importMenuLoader.getController();
importMenuController.setMainController(mainController);
Scene scene = new Scene(root, 1920, 1080);
primaryStage.setTitle("Test");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
---------- Main.fxml----------
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.Group?>
<?import javafx.scene.layout.*?>
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="controllers.MainController">
<top>
<MenuBar>
<fx:include source="FileMenu.fxml" fx:id="fileMenu"/>
</MenuBar>
</top>
<center>
<Group fx:id="centerGroup"/>
</center>
</BorderPane>
----------FileMenu.fxml----------
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<Menu xmlns:fx="http://javafx.com/fxml"
fx:controller="controllers.FileMenuController" text="File">
<MenuItem text="New"/>
<MenuItem text="Open"/>
<MenuItem text="Save"/>
<MenuItem text="Save As"/>
<SeparatorMenuItem/>
<fx:include source="ImportMenu.fxml" fx:id="importMenu"/>
</Menu>
----------ImportMenu.fxml------------
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<Menu xmlns:fx="http://javafx.com/fxml" text="Import"
fx:controller="controllers.ImportMenuController">
<MenuItem text="Model"/>
<MenuItem text="Solver Deck" onAction="#onImportSolverDeck"/>
<MenuItem text="Geometry"/>
</Menu>
----------MainController.java----------
package controllers;
import javafx.fxml.FXML;
import javafx.scene.Group;
import javafx.scene.control.Menu;
import node.Node;
public class MainController {
@FXML private Menu fileMenu;
@FXML private FileMenuController fileMenuController;
@FXML private Group centerGroup;
@FXML
public void initialize() {
}
public void addNodeToScene(double x, double y, double z, int ID) {
Node node = new Node(x, y, z, ID);
centerGroup.getChildren().add(node.getSphere());
}
}
----------文件菜单控制器----------
package controllers;
import javafx.fxml.FXML;
import javafx.scene.control.Menu;
public class FileMenuController {
@FXML private Menu importMenu;
@FXML private ImportMenuController importMenuController;
@FXML
public void initialize() {
}
}
----------导入菜单控制器----------
package controllers;
import javafx.fxml.FXML;
import javafx.stage.FileChooser;
import java.io.*;
public class ImportMenuController {
private MainController mainController;
@FXML
public void initialize() {
}
public void setMainController(MainController mainController) {
this.mainController = mainController;
}
@FXML
public void onImportSolverDeck() {
try {
FileChooser fileChooser = new FileChooser();
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Text File (.txt)", "*.txt"));
File selectedFile = fileChooser.showOpenDialog(null);
if (selectedFile != null) {
femLoader(selectedFile);
}
} catch (IOException e) {
System.out.println("Unable to read the selected file: " + e.getMessage());
}
}
private void femLoader(File femFile) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(femFile))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("GRID")) {
String[] parts = line.split("\\s+");
int ID = Integer.parseInt(parts[1]);
double x = Double.parseDouble(parts[2]);
double y = Double.parseDouble(parts[3]);
double z = Double.parseDouble(parts[4]);
mainController.addNodeToScene(x, y, z, ID);
}
}
}
}
}
Node.java 类只是 Point3D 的扩展,添加到已经很长的帖子中是没有意义的。 场景加载正常,但每当我单击 .txt 文件时,就会出现
NullPointerException
。
特别是在选择文件后,this.mainController
突然变成了null
。
我真的很难在这里找到问题,任何帮助将不胜感激。
据我了解,
FXMLLoader mainLoader
和FXMLLoader importMenuLoader
是完全独立的对象。 mainLoader
将负责子组件的初始化,因此通过调用 importMenuLoader
,您将获得另一个实例,并且您在此实例上调用 setMainController
。
我的JavaFX知识有点生疏,但据我记得,你必须将
MainController
直接注入到ImportMenuController
您不需要设置器,这应该可以解决问题:
@FXML
private MenuController menuController;