关闭 JavaFX 对话框时出现空指针异常

Null Pointer Exception when closing a JavaFX Dialog

我有一个从基本阶段开始的简单程序。然后我 select 一个启动对话框的菜单项。我在对话框上有一个按钮,它只关闭当前阶段。我原以为对话框会关闭,焦点会 return 到初始阶段。但是,当我单击“创建游戏”按钮时出现空指针异常。我是 Java 的新手,可能遗漏了一些明显的东西。请帮忙。

HWFX.JAVA

package Main;

import java.util.Date;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class HWFX extends Application {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
    launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        // TODO Auto-generated method stub
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/Main.fxml"));
    Parent root = loader.load();
    MainController controller = (MainController) loader.getController();
    controller.init(primaryStage);

    Scene scene = new Scene(root,600,400);
    scene.getStylesheets().add("/fxml/styles/mainfx.css");

    primaryStage.setScene(scene);
    primaryStage.setTitle("Hello World FX");
    primaryStage.show();

    }

MainController.java

package Main;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import java.sql.*;

import javax.sql.*;

import oracle.jdbc.*;
import oracle.jdbc.pool.OracleDataSource;

public class MainController implements Initializable {

    private Stage stage;
    @FXML
    javafx.scene.layout.AnchorPane AnchorPane;
    @FXML
    javafx.scene.layout.GridPane GridPane;
    @FXML
    javafx.scene.layout.GridPane GridPaneMain;
    @FXML
    Button TestButton1;
    Button TestButton2;
    Button TestButton3;
    @FXML
    javafx.scene.control.TextField PlayerName;


    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        // TODO Auto-generated method stub

    }

    public void doExit() {
        Platform.exit();
    }

    public void openFile() {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("Open text file");     
        fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
        fileChooser.getExtensionFilters().addAll(
                new FileChooser.ExtensionFilter("Text Files","*.txt"),
                new FileChooser.ExtensionFilter("All Files","*.*")
                );
        File file = fileChooser.showOpenDialog(stage);

        if (file != null){
            System.out.println("Choosen File: " + file);
        }
    }

    public void ButtonClicked() throws SQLException {
        System.out.println("Click!");
        final TextField F1 = new TextField();
        F1.setPromptText("F1");
        F1.setPrefColumnCount(10);
        F1.getText();
//      javafx.scene.layout.GridPane.setConstraints(F1,10,10);
        GridPaneMain.add(F1, 0, 0);

        OracleDataSource ods = new OracleDataSource();

        // Set the user name, password, driver type and network protocol
        ods.setUser("ppmcdev");
        ods.setPassword("ppmc");
        ods.setURL("jdbc:oracle:thin:@172.21.51.56:1521:INAVD");
        ods.setDriverType("oci8");
        ods.setNetworkProtocol("ipc");
        ods.setTNSEntryName("INAVD");

        // Retrieve a connection
        Connection conn = ods.getConnection();
        getUserName(conn);
        // Close the connection
        conn.close();
        conn = null;
    }

      public void CreateGame(ActionEvent event) throws IOException {
          System.out.println("Create Game Menu");
          CreateGameDialogController CreateGameDialog = new CreateGameDialogController();   
          try {
              CreateGameDialog.showCreateGameDialog(stage);
          } catch (Exception e) {
              e.printStackTrace();
          }
      }

    public void init(Stage stage) {
        // TODO Auto-generated method stub
        this.stage = stage;
    }
}

Main.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.input.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import java.lang.*?>
<?import javafx.scene.image.*?>

<AnchorPane fx:id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Main.MainController">
   <children>
      <BorderPane layoutX="-2.0" layoutY="-3.0" prefHeight="400.0" prefWidth="606.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <center>
            <TextArea prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
         </center>
         <top>
            <MenuBar BorderPane.alignment="CENTER">
              <menus>
                <Menu text="_File">
                  <items>
                        <MenuItem onAction="#openFile" text="_Open">
                           <accelerator>
                              <KeyCodeCombination alt="UP" code="O" control="DOWN" meta="UP" shift="UP" shortcut="UP" />
                           </accelerator>
                        </MenuItem>
                    <MenuItem onAction="#doExit" text="E_xit">
                           <accelerator>
                              <KeyCodeCombination alt="UP" code="X" control="DOWN" meta="UP" shift="UP" shortcut="UP" />
                           </accelerator>
                        </MenuItem>
                  </items>
                </Menu>
                  <Menu text="_Game">
                    <items>
                        <MenuItem onAction="#CreateGame" text="_Create">
                           <accelerator>
                              <KeyCodeCombination alt="DOWN" code="C" control="UP" meta="UP" shift="UP" shortcut="UP" />
                           </accelerator></MenuItem>
                    </items>
                  </Menu>
              </menus>
            </MenuBar>
         </top>
         <bottom>
            <Button mnemonicParsing="false" onAction="#ButtonClicked" text="ClickMeButton" BorderPane.alignment="CENTER" />
         </bottom>
      </BorderPane>
      <GridPane id="GridPane" fx:id="GridPane" layoutX="20.0" layoutY="70.0" prefHeight="68.0" prefWidth="594.0" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="6.0">
        <columnConstraints>
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints fillHeight="false" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <padding>
            <Insets top="40.0" />
         </padding>
         <children>
            <Button id="TestButton1" alignment="TOP_LEFT" contentDisplay="BOTTOM" mnemonicParsing="false" prefHeight="22.0" prefWidth="94.0" text="Test Button 1" />
            <Button id="TestButton2" contentDisplay="BOTTOM" mnemonicParsing="false" prefHeight="25.0" prefWidth="91.0" text="Test Button 2">
               <GridPane.margin>
                  <Insets left="100.0" />
               </GridPane.margin>
            </Button>
            <Button id="addPlayer" fx:id="addPlayer" alignment="BASELINE_RIGHT" mnemonicParsing="false" onAction="#addPlayer" text="Add Player">
               <GridPane.margin>
                  <Insets left="300.0" />
               </GridPane.margin>
            </Button>
            <TextField fx:id="PlayerName" prefHeight="25.0" prefWidth="152.0" promptText="Player Name">
               <GridPane.margin>
                  <Insets left="400.0" />
               </GridPane.margin>
            </TextField>
         </children>
      </GridPane>
      <GridPane id="GridPaneMain" fx:id="GridPaneMain" gridLinesVisible="true" layoutY="29.0" prefHeight="308.0" prefWidth="600.0">
        <columnConstraints>
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
      </GridPane>
   </children>
</AnchorPane>

CreateGameDialogController.java

package Main;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

import javafx.application.Platform;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.event.ActionEvent;
import javafx.fxml.*;
import javafx.scene.layout.*;
import javafx.scene.*;

public class CreateGameDialogController implements Initializable {

    @FXML
    private javafx.scene.layout.AnchorPane AnchorPane;
    @FXML
    private javafx.scene.control.Slider NumberOfPlayers;

    private Stage myParent;
    private Stage CreateGameDialogStage;

    public void showCreateGameDialog(Stage parentStage) {
    this.myParent = parentStage;
    try {
        CreateGameDialogStage = new Stage();
        AnchorPane page = (AnchorPane) FXMLLoader.load(CreateGameDialogController.class.getResource("/fxml/CreateGameDialog.fxml"));
        Scene scene = new Scene(page);
        CreateGameDialogStage.setScene(scene);
        CreateGameDialogStage.setTitle("Create Game");
        CreateGameDialogStage.initOwner(this.myParent);
        CreateGameDialogStage.initModality(Modality.WINDOW_MODAL);
        CreateGameDialogStage.show();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    } 

    public void CreateGame(ActionEvent event) {
        try {
        System.out.println("Create Game");
        CreateGameDialogStage.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        // TODO Auto-generated method stub

    }

}

CreateGameDialog.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 id="AnchorPane" prefHeight="427.0" prefWidth="602.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Main.CreateGameDialogController">
   <children>
      <BorderPane prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <left>
            <Pane prefHeight="427.0" prefWidth="257.0" BorderPane.alignment="CENTER">
               <children>
                  <Slider id="NumberOfPlayers" fx:id="NumberOfPlayers" blockIncrement="1.0" layoutX="14.0" layoutY="42.0" majorTickUnit="1.0" max="8.0" min="3.0" minorTickCount="0" orientation="VERTICAL" prefHeight="310.0" prefWidth="14.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="1.0" />
                  <Label alignment="CENTER" contentDisplay="CENTER" prefHeight="29.0" prefWidth="257.0" text="Select the Players" textAlignment="CENTER">
                     <font>
                        <Font name="System Bold" size="14.0" />
                     </font>
                  </Label>
                  <Button id="CreateGameButton" layoutX="79.0" layoutY="388.0" mnemonicParsing="false" onAction="#CreateGame" prefHeight="25.0" prefWidth="102.0" text="Create Game" />
               </children>
            </Pane>
         </left>
         <right>
            <ScrollPane prefHeight="427.0" prefWidth="360.0" BorderPane.alignment="CENTER" />
         </right>
      </BorderPane>
   </children>
</AnchorPane>

当我点击“创建游戏”按钮时,我得到:

Create Game
java.lang.NullPointerException
    at Main.CreateGameDialogController.CreateGame(CreateGameDialogController.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.Trampoline.invoke(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(Unknown Source)
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(Unknown Source)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
    at javafx.event.Event.fireEvent(Unknown Source)
    at javafx.scene.Node.fireEvent(Unknown Source)
    at javafx.scene.control.Button.fire(Unknown Source)
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(Unknown Source)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase.handle(Unknown Source)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase.handle(Unknown Source)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
    at javafx.event.Event.fireEvent(Unknown Source)
    at javafx.scene.Scene$MouseHandler.process(Unknown Source)
    at javafx.scene.Scene$MouseHandler.access00(Unknown Source)
    at javafx.scene.Scene.impl_processMouseEvent(Unknown Source)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
    at com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
    at com.sun.glass.ui.View.notifyMouse(Unknown Source)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null1(Unknown Source)
    at com.sun.glass.ui.win.WinApplication$$Lambda/2075313.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

MainController里面,CreateGame()里面的问题在这一行:

CreateGameDialogController CreateGameDialog = new CreateGameDialogController();

当您使用 FXML 控制器时,不要使用 new 创建控制器对象,而是始终加载 FXML 并从 FXMLLoader

获取控制器

您必须尝试在 CreateGame() 中加载 CreateGameDialog.fxml 而不是在其自己的控制器中加载 FXML。

专业提示 - 在 Java

中编码时使用驼峰式大小写