我已经声明了两个FXML文件,并为每一个控制器: rootlayoutcontroller 是控制器的一个 rootlayout.fxml 和 overviewcontroller 是控制器的一个 overview.fxml
rootlayout具有带有文件打开项的菜单栏,而总览控制器具有Draw按钮。
我还有另一个叫做DataStructure的类。我想打开一个文件并将路径发送到Overviewcontroller。然后,当我单击Draw时,将实例化DartaStructure的构造函数,并将路径作为参数。但是,一旦我单击“打开”,在文件选择器打开对话框中,程序就会为in handleOpen()方法抛出一个空指针。有时我找不到源!
handleOpen()
在主类中,我将概述包装在rootlayout中并显示该阶段。
RootLayoutController:
public class RootLayoutController { private final Model model; public RootLayoutController(Model model){ this.model = model; } /** * Opens a FileChooser to let the user select a .z3lgm file to load. */ @FXML private void handleOpen() { FileChooser fileChooser = new FileChooser(); // Set extension filter FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter( "3lgm2 files (*.z3lgm)", "*z3lgm"); fileChooser.getExtensionFilters().add(extFilter); // Show open file dialog File file = fileChooser.showOpenDialog(main.getPrimaryStage()); if (file != null) { path = file.toString(); model.setText(path);//error } } }
OverViewController:
public class OverViewController implements Initializable { private final Model model; public OverViewController(Model model){ this.model = model; } public void treeTableDraw(ActionEvent event) { String p = model.getText(); new Controller(p); drawTable(); numberOfFunctions = dc.getFuncAll().size(); numberOfOrganizations = dc.getSortedAssignedOrg().size(); funcLabel.setText(numberOfFunctions + ""); orgLabel.setText(numberOfOrganizations + ""); btnDraw.setDisable(true); } }
错误堆栈:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1770) at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1653) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49) at javafx.event.Event.fireEvent(Event.java:198) at javafx.scene.control.MenuItem.fire(MenuItem.java:462) at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1405) at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren$341(ContextMenuContent.java:1358) at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer$$Lambda$326/15872584.handle(Unknown Source) at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) at javafx.event.Event.fireEvent(Event.java:198) at javafx.scene.Scene$MouseHandler.process(Scene.java:3758) at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3486) at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762) at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2495) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:350) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$350(GlassViewEventHandler.java:385) at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$209/5704663.get(Unknown Source) at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:404) at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:384) at com.sun.glass.ui.View.handleMouseEvent(View.java:555) at com.sun.glass.ui.View.notifyMouse(View.java:927) at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method) at com.sun.glass.ui.gtk.GtkApplication.lambda$null$48(GtkApplication.java:139) at com.sun.glass.ui.gtk.GtkApplication$$Lambda$41/19140780.run(Unknown Source) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71) at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275) at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1767) ... 46 more Caused by: java.lang.NullPointerException at view.RootLayoutController.handleOpen(RootLayoutController.java:174) ... 56 more
主类:
public class Main extends Application { private Stage primaryStage; private BorderPane rootLayout; private Model model = new Model; // private ObservableList<DataConstructor> treeTableData = // FXCollections.observableArrayList(); @Override public void start(Stage primaryStage) { this.primaryStage = primaryStage; this.primaryStage.setTitle("IT-Saturation"); initRootLayout(); showOverView(); } private void showOverView() { try { FXMLLoader loader = new FXMLLoader(); loader.setLocation(Main.class.getResource("/view/OverView.fxml")); loader.setController(new OverViewController(model)); // Parent firstUI = loader.load(); AnchorPane overView = (AnchorPane) loader.load(); rootLayout.setCenter(overView); // OverViewController controller = loader.getController(); // controller.setMainApp(this); } catch (IOException e) { e.printStackTrace(); } } private void initRootLayout() { try { FXMLLoader loader = new FXMLLoader(); loader.setLocation(Main.class.getResource("/view/RootLayout.fxml")); loader.setController(new RootLayoutController(model)); rootLayout = (BorderPane) loader.load(); // show scene containing the root layout Scene scene = new Scene(rootLayout); scene.getStylesheets().add( getClass().getResource("application.css").toExternalForm()); primaryStage.setScene(scene); // gives controller access to main RootLayoutController controller = loader.getController(); controller.setMainApp(this); primaryStage.show(); } catch (IOException e) { e.printStackTrace(); } } /** * Returns the main stage. * * @return primaryStage */ public Stage getPrimaryStage() { return primaryStage; } public static void main(String[] args) { launch(args); } public void showMostComputerizedStatistics() { try { // Load the fxml file and create a new stage for the popup. FXMLLoader loader = new FXMLLoader(); loader.setLocation(Main.class .getResource("view/BirthdayStatistics.fxml")); AnchorPane page = (AnchorPane) loader.load(); Stage dialogStage = new Stage(); dialogStage.setTitle("Birthday Statistics"); dialogStage.initModality(Modality.WINDOW_MODAL); dialogStage.initOwner(primaryStage); Scene scene = new Scene(page); dialogStage.setScene(scene); // Set the persons into the controller. MostComputerizedController controller = loader.getController(); dialogStage.show(); } catch (IOException e) { e.printStackTrace(); } } }
这是RootLayout fxml:
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.input.*?> <?import javafx.scene.control.*?> <?import java.lang.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.layout.BorderPane?> <BorderPane prefHeight="500.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" > <top> <MenuBar BorderPane.alignment="CENTER"> <menus> <Menu text="_File"> <items> <MenuItem onAction="#handleOpen" text="_Open" /> <MenuItem mnemonicParsing="false" onAction="#handleExportPic" text="Export as picture" /> <MenuItem mnemonicParsing="false" text=" Save as" /> <MenuItem mnemonicParsing="false" onAction="#doPrint" text="Print" /> <MenuItem onAction="#handleExit" text="E_xit"> <accelerator> <KeyCodeCombination alt="UP" code="X" control="DOWN" meta="UP" shift="UP" shortcut="UP" /> </accelerator></MenuItem> </items> </Menu> <Menu mnemonicParsing="false" onAction="#handleMostComputerizedStatistics" text="Statistics"> <items> <MenuItem mnemonicParsing="false" onAction="#handleMostComputerizedStatistics" text="Show Statistics" /> </items> </Menu> <Menu mnemonicParsing="false" text="Help"> <items> <MenuItem mnemonicParsing="false" text="About" /> </items> </Menu> </menus> </MenuBar> </top> </BorderPane>
这是概述fxml:
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.text.*?> <?import javafx.scene.control.*?> <?import java.lang.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.layout.AnchorPane?> <AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" > <children> <SplitPane dividerPositions="0.2391304347826087" layoutX="62.0" layoutY="52.0" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <items> <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" SplitPane.resizableWithParent="false"> <children> <Button fx:id="btnDraw" layoutX="24.0" layoutY="297.0" mnemonicParsing="false" onAction="#treeTableDraw" text="Draw" AnchorPane.leftAnchor="22.0" AnchorPane.rightAnchor="36.0" /> <Label fx:id="funcLabel" layoutX="24.0" layoutY="155.0" opacity="0.72" prefHeight="15.0" prefWidth="38.0" text="0" AnchorPane.bottomAnchor="190.0" AnchorPane.leftAnchor="24.0" AnchorPane.rightAnchor="77.0"> <font> <Font size="10.0" /> </font></Label> <Label fx:id="orgLabel" layoutX="17.0" layoutY="219.0" opacity="0.72" prefHeight="14.0" prefWidth="38.0" text="0" AnchorPane.bottomAnchor="165.0" AnchorPane.leftAnchor="24.0" AnchorPane.rightAnchor="84.0" AnchorPane.topAnchor="219.0"> <font> <Font size="10.0" /> </font></Label> <Label layoutX="63.0" layoutY="155.0" text="Functions" AnchorPane.bottomAnchor="190.0"> <font> <Font size="11.0" /> </font> </Label> <Label layoutX="56.0" layoutY="219.0" text="Organizations" AnchorPane.bottomAnchor="165.0" AnchorPane.topAnchor="213.0"> <font> <Font size="10.0" /> </font> </Label> <Button fx:id="btnReset" layoutX="21.0" layoutY="345.0" mnemonicParsing="false" onAction="#treeTableReset" onKeyPressed="#treeTableReset" prefHeight="25.0" prefWidth="81.0" text="Reset" AnchorPane.leftAnchor="22.0" AnchorPane.rightAnchor="36.0" /> </children></AnchorPane> <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" SplitPane.resizableWithParent="false"> <children> <ScrollPane fx:id="scrollPane" prefHeight="398.0" prefWidth="480.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <content> <TreeTableView fx:id="treeTable" editable="true" prefHeight="375.0" prefWidth="246.0" /> </content> </ScrollPane> </children></AnchorPane> </items> </SplitPane> </children> </AnchorPane>
FXMLLoader.getController()``null如果在调用该load()方法之前调用它,它将返回(因为如果尚未加载FXML文件,则它不知道控制器是什么)。
FXMLLoader.getController()``null
load()
但这仍然不会做您想要的。您需要引用 与UI中显示 的FMXL文件的根相关联的控制器实例。无论是通过从另一个FXMLLoader实例获取实例还是直接实例化实例实例,都无法获得任意控制器实例。
FXMLLoader
所需的控制器实例是可以通过调用类loader.getController()中的showOverview()方法获得的Main。如果您希望控制器之间相互通信,则需要安排RootLayoutController实例具有对该实例的引用OverViewController。
loader.getController()
showOverview()
Main
RootLayoutController
OverViewController
最好不要让控制器直接相互访问,而要让它们与共享数据模型中的数据通信。