问题描述
我已经为每个文件声明了两个fxml文件和一个控制器:
rootlayoutcontroller 是 rootlayout.fxml
和$ b $的控制器b overviewcontroller 是 overview.fxml 的控制器
I have declared two fxml files and a controller for each one:rootlayoutcontroller is a controller for rootlayout.fxmlandoverviewcontroller is a controller for overview.fxml
rootlayout有菜单栏,文件打开项目,而overviewcontroller有一个绘制按钮。
rootlayout has menu bar with file open item, and overviewcontroller has a Draw button.
我有另一个名为DataStructure的类。我想打开一个文件并将路径发送到overviewcontroller。然后,当我单击Draw时,DartaStructure的构造函数将被实例化,路径为参数。但是当我单击打开时,在文件选择器打开对话框中,程序会在 handleOpen()
方法中抛出一个nullpointer。
有时候我找不到Source!
I have another class called DataStructure. I want to open a file and send the path to overviewcontroller. Then when I click Draw the constructor of DartaStructure shall get instantiated, with the path as parameter. But as soon as I click open, on file chooser open dialog, the program throws an nullpointer for in handleOpen()
method.Sometimes I get Source not found!
在一个主类中,我在rootlayout中包含概述并显示阶段。
In a main class I wrap overview in rootlayout and show the stage.
RootLayoutController:
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:
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:
This is 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()
如果在<$ c之前调用它,将返回 null
$ c> load()方法已被调用(因为如果它没有加载FXML文件,它不知道控制器是什么)。
FXMLLoader.getController()
will return null
if you call it before the load()
method has been called (because if it hasn't loaded the FXML file, it doesn't know what the controller is).
但这仍然不会做你想要的。您希望引用与UI 中显示的FMXL文件的根相关联的控制器实例。无论是通过从另一个 FXMLLoader
获取它还是通过直接实例化它来实现它都没有帮助。
But this is still not going to do what you want. You want a reference to the controller instance that is associated with the root of the FMXL file that is displayed in the UI. It doesn't help to just get an arbitrary controller instance, whether you do it by getting it from another FXMLLoader
or by instantiating it directly.
您想要的控制器实例是您可以通过在 showOverview()中调用
loader.getController()
获得的控制器实例 Main
类中的/ code>方法。如果你想让控制器相互通信,你需要安排 RootLayoutController
实例来引用那个 OverViewController
实例。
The controller instance you want is the one you can get by calling loader.getController()
in the showOverview()
method in your Main
class. If you want the controllers to communicate with each other, you need to arrange for the RootLayoutController
instance to have a reference to that OverViewController
instance.
最好不要让控制器彼此直接访问,而是让它们与共享数据模型中的数据进行通信。 有一个简单的例子这种方法。
It might be better not to have the controllers have direct access to each other, but to let them communicate with data in a shared data model. This question has a simple example of this approach.
这篇关于Loader实例化在JavaFX中抛出nullpointer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!