通过MenuItem JFX加载FXML时出现空指针异常

时间:2018-03-07 18:02:10

标签: java javafx

你好,我试图通过MenuItem加载FXML,虽然我想要执行的操作已经完成但我得到一个空指针异常。这是FXML代码

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.effect.DropShadow?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="container" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="534.0" prefWidth="855.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="graphicInterface.ControllerHomePatients">
   <children>
      <MenuBar fx:id="bar" layoutX="7.0" layoutY="2.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
        <menus>
          <Menu fx:id="homeButton" mnemonicParsing="false" text="Home">
               <items>
                  <MenuItem fx:id="rHome" mnemonicParsing="false" text="Home Page" />
               </items></Menu>
          <Menu fx:id="View" mnemonicParsing="false" text="View">
               <items>
                  <MenuItem fx:id="myCalendar" mnemonicParsing="false" text="My Calendar" />
                  <MenuItem fx:id="mAppointments" mnemonicParsing="false" text="My Appointments" />
               </items>
          </Menu>
            <Menu fx:id="edit" mnemonicParsing="false" text="Edit">
              <items>
                <MenuItem fx:id="mProfile" mnemonicParsing="false" text="My profile" />
              </items>
            </Menu>
          <Menu fx:id="help" mnemonicParsing="false" text="Help" />
            <Menu fx:id="logOff" mnemonicParsing="false" onAction="#onClickLogOff" text="Close">
               <items>
                  <MenuItem fx:id="signOff" mnemonicParsing="false" onAction="#onClickLogOff" text="Sign off" />
               </items></Menu>
        </menus>
      </MenuBar>
      <AnchorPane fx:id="mContainer" layoutY="25.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="25.0">
         <children>
            <ImageView fx:id="image" fitHeight="150.0" fitWidth="118.0" layoutX="23.0" layoutY="40.0" pickOnBounds="true" preserveRatio="true">
               <image>
                  <Image url="@../images/UserProfile.png" />
               </image>
            </ImageView>
            <Label fx:id="tName" layoutX="37.0" layoutY="182.0" prefWidth="91.0" text="Name" />
            <Label fx:id="tSurname" layoutX="37.0" layoutY="220.0" prefHeight="17.0" prefWidth="91.0" text="Surname" />
            <Label fx:id="tNif" ellipsisString="" layoutX="37.0" layoutY="255.0" prefHeight="17.0" prefWidth="91.0" text="DNI" />
            <ScrollPane layoutX="210.0" layoutY="81.0" prefHeight="390.0" prefWidth="502.0">
              <content>
                <AnchorPane fx:id="appointmentView" />
              </content>
               <effect>
                  <DropShadow />
               </effect>
            </ScrollPane>
            <TextField fx:id="search" layoutX="422.0" layoutY="40.0" prefHeight="25.0" prefWidth="118.0" promptText="Search" />
            <ComboBox fx:id="orderBy" layoutX="562.0" layoutY="40.0" prefWidth="150.0" promptText="Order by:" />
            <Button fx:id="bPDF" layoutX="742.0" layoutY="81.0" mnemonicParsing="false" onAction="#onClickPdf" prefHeight="25.0" prefWidth="91.0" text="Export to PDF" />
            <Button fx:id="bPrint" layoutX="742.0" layoutY="128.0" mnemonicParsing="false" onAction="#onClickPrint" prefHeight="25.0" prefWidth="91.0" text="Print" />
         </children></AnchorPane>
   </children>
</AnchorPane>

这是fxml的控制器:

package graphicInterface;

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

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.*;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class ControllerHomePatients implements Initializable {

    @FXML
    private AnchorPane container;

    @FXML
    private MenuBar bar;

    @FXML
    private Menu homeButton;

    @FXML
    private MenuItem rHome;

    @FXML
    private Menu View;

    @FXML
    private MenuItem myCalendar;

    @FXML
    private MenuItem mAppointments;

    @FXML
    private Menu edit;

    @FXML
    private MenuItem mProfile;

    @FXML
    private Menu help;

    @FXML
    private Menu logOff;

    @FXML
    private MenuItem signOff;

    @FXML
    private AnchorPane mContainer;

    @FXML
    private ImageView image;

    @FXML
    private Label tName;

    @FXML
    private Label tSurname;

    @FXML
    private Label tNif;

    @FXML
    private AnchorPane appointmentView;

    @FXML
    private TextField search;

    @FXML
    private ComboBox<?> orderBy;

    @FXML
    private Button bPDF;

    @FXML
    private Button bPrint;

    @FXML
    void onClickPdf(ActionEvent event) {

    }

    @FXML
    void onClickPrint(ActionEvent event) {

    }

    @FXML
    void onClickLogOff(ActionEvent event) throws IOException {
        Main.patient = null;

        Parent root = FXMLLoader.load(getClass().getResource("MainView.fxml"));     
        Stage window = (Stage) ((Node) bar).getScene().getWindow();
        window.setScene(new Scene(root));
        window.show();
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        tName.setText(Main.patient.getName());
        tSurname.setText(Main.patient.getSurname());
        tNif.setText(Main.patient.getNIF());
        ObservableList list = FXCollections.observableArrayList("Alphabetically", "Date");
        orderBy.setItems(list);
    }

}

问题发生在我设置场景的行中的onClickLogOff方法中。为什么发生NullPointerException?谢谢:))

1 个答案:

答案 0 :(得分:0)

您已使用Menu MenuItem注册了处理程序:

 <Menu fx:id="logOff" mnemonicParsing="false" onAction="#onClickLogOff" text="Close">
    <items>
       <MenuItem fx:id="signOff" mnemonicParsing="false" onAction="#onClickLogOff" text="Sign off" />
    </items></Menu>

当您选择菜单项时,它会触发一个动作事件,从而导致您的处理程序被调用。这取代了场景。然后菜单触发另一个动作事件,再次调用处理程序。

由于第一次调用处理程序时,包含菜单栏的场景已从窗口中删除,因此包含菜单栏的场景现在没有窗口,所以

bar.getScene().getWindow();

返回null,

window.setScene(...);

然后抛出空指针异常。

要解决此问题,只需从onAction

中删除Menu处理程序即可
 <Menu fx:id="logOff" mnemonicParsing="false" text="Close">
    <items>
       <MenuItem fx:id="signOff" mnemonicParsing="false" onAction="#onClickLogOff" text="Sign off" />
    </items></Menu>