Loader实例化在JavaFX中抛出nullpointer

时间:2015-03-16 20:42:20

标签: java javafx loader

我已经为每个文件声明了两个fxml文件和一个控制器: rootlayoutcontroller rootlayout.fxml 的控制器 和 overviewcontroller overview.fxml

的控制器

rootlayout有菜单栏,文件打开项目,而overviewcontroller有一个绘图按钮。

我有另一个名为DataStructure的类。我想打开一个文件并将路径发送到overviewcontroller。然后,当我单击Draw时,DartaStructure的构造函数将被实例化,路径为参数。但是一旦我单击打开,在文件选择器打开对话框上,程序就会在handleOpen()方法中抛出一个nullpointer。 有时我找不到Source!

在主类中,我在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:

&#13;
&#13;
<?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>
&#13;
&#13;
&#13;

这是概述fxml:

&#13;
&#13;
<?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>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

如果您在调用FXMLLoader.getController()方法之前调用它,那么

null将返回load()(因为如果它没有加载FXML文件,则它不会被&#t;}知道控制器是什么。)

但这仍然不会做你想要的。您希望引用与UI 中显示的FMXL文件的根相关联的控制器实例。无论是通过从另一个FXMLLoader获取它还是直接实例化它,都无法获得任意控制器实例。

您想要的控制器实例是您可以通过loader.getController()showOverview()方法中的Main调用RootLayoutController获得的控制器实例。如果您希望控制器相互通信,则需要安排OverViewController实例引用该{{1}}实例。

最好不要让控制器彼此直接访问,而是让它们与共享数据模型中的数据进行通信。 This question有一个简单的例子。