【问题标题】:JavaFX - controller initialize method gives null pointer exceptionJavaFX - 控制器初始化方法给出空指针异常
【发布时间】:2016-09-23 16:51:59
【问题描述】:

我最近开始使用 JavaFX,但我遇到了控制器问题。

我的问题是这样的: 1)我在 project.startup 中有 fxml 文件,它的名称是 loginTab.fxml 2)这个窗口的控制器在project.startup.controllers中,叫做LoginTabController

当我想在控制器的初始化方法中为 Button 设置禁用属性(或向 Toggle Group 添加侦听器)时,我遇到了空指针异常。堆栈跟踪显示在 initialize() 的开头是空指针。

下面我将介绍导致这种可怕情况的代码。事实上,我一直在寻找一些解决方案,但我找不到任何东西。

我也检查了名字是否拼写正确,但不幸的是它是正确的。

1) 第一个代码示例是我加载页面的方式:

 try{
     FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/project/startup/loginTab.fxml"));
     Parent root = fxmlLoader.load();
     Stage stage = new Stage();
     stage.initModality(Modality.APPLICATION_MODAL);
     stage.initStyle(StageStyle.DECORATED);
     stage.setTitle("System Main Menu");
     stage.setScene(new Scene(root));  
     stage.show();
 } catch(Exception ex){
     ex.printStackTrace();
 }

2) 我的页面元素

 <GridPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="projectgotham.startup.controllers.LoginTabController" prefHeight="200" prefWidth="500" alignment="center" hgap="20" vgap="20">
    <fx:define>
        <ToggleGroup fx:id = "typeOfLogin"/>
    </fx:define>
    <VBox spacing="5" GridPane.columnIndex="0" GridPane.rowIndex="0">
        <children>
            <Label>Choose type of login</Label>
            <RadioButton text="Face" toggleGroup="$typeOfLogin" selected = "true" userData = "Face"/>
            <RadioButton text="Fingerprint" toggleGroup="$typeOfLogin" userData = "Fingerprint"/>
            <RadioButton text="Face and Fingerprint" toggleGroup="$typeOfLogin" userData = "Face and Fingerprint"/> 
            <RadioButton text="Admin" toggleGroup="$typeOfLogin" userData = "Admin"/>
        </children>
    </VBox>
    <VBox spacing="15" GridPane.columnIndex="0" GridPane.rowIndex="1">
        <children>
            <Label>Current login progress</Label>
            <ProgressBar fx:id = "loginProgressBar" progress="0.30"/>
        </children>
    </VBox> 
    <VBox spacing="20" GridPane.columnIndex="0" GridPane.rowIndex="2">
        <children>
            <Button text="Invoke Login Action" onAction="#handleLoginAction"/>
            <Button fx:id="closeSystemBtn" text="Close System" onAction="#closeSystem"/>
        </children>
    </VBox>
    <VBox spacing="5" GridPane.columnIndex="10" GridPane.rowIndex="0">
        <children>
            <Label>Last loaded image</Label>
            <ImageView fx:id="currentImageViewer" fitHeight="150" fitWidth="200" pickOnBounds="true" preserveRatio="true" visible="true">
            </ImageView>
        </children>
    </VBox>
    <VBox spacing="15" GridPane.columnIndex="10" GridPane.rowIndex="1">
        <children>
            <Button fx:id = "testButton" text="Took a photo" onAction="#testThing"/>
            <Button text="Load a fingerprint image"/>
        </children>
    </VBox>
</GridPane>

3) 我的控制器类

public class LoginTabController implements Initializable {

    /**
     * Initializes the controller class.
     */

    @FXML
    private ToggleGroup typeOfLogin;

    @FXML
    private Button closeSystemBtn;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        closeSystemBtn.setDisable(true);
    }   


    @FXML
    protected void handleLoginAction(ActionEvent event){

        try{
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/projectgotham/startup/LoginIdentification.fxml"));
            Parent root = fxmlLoader.load();
            Stage stage = new Stage();
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.initStyle(StageStyle.DECORATED);
            stage.setTitle("Finish login action");
            stage.setScene(new Scene(root));  
            stage.show();
        } catch(Exception ex){
            ex.printStackTrace();
            Logger.getRootLogger().error("Can't handle action connected with login : " + ex.getMessage());
        }
    }

    @FXML
    protected void closeSystem(ActionEvent event){
        Stage closeStage = (Stage) closeSystemBtn.getScene().getWindow();
        closeStage.close();
    }

    @FXML
    protected void testThing(ActionEvent event){
        typeOfLogin.selectedToggleProperty().addListener(new ChangeListener<Toggle>(){
            @Override
            public void changed(ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) {
                System.out.println(typeOfLogin.getSelectedToggle().getUserData().toString());
            }

        });

    }

}

如果你能帮我解决这个空指针异常,我会很高兴...

编辑:

堆栈跟踪:

at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.access$2700(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$IncludeElement.constructValue(FXMLLoader.java:1143)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:746)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at projectgotham.startup.Startup$2.handle(Startup.java:60)
at projectgotham.startup.Startup$2.handle(Startup.java:55)
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.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.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.Node.fireEvent(Node.java:8413)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
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.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:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:380)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:294)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:416)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:415)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at projectgotham.startup.controllers.LoginTabController.initialize(LoginTabController.java:45)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
... 57 more

【问题讨论】:

  • 哪个空指针异常?你能edit你的问题包括堆栈跟踪吗?
  • 而Startup.java的第60行是Parent root = fxmlLoader.load();,LoginTabController.java的第45行是closeSystemBtn.setDisable(true);,你贴的FXML是loginTab.fxml,对吗?
  • 如果你评论或删除closeSystemBtn.setDisable(true);并再次运行它,你仍然会出现异常吗?
  • James_D 是的,Tomasz Mularczyk 不,我没有得到这个例外。
  • 显然closeSystemBtn 为空,尽管它不应该是因为fx:id 是正确的并且您有@FXML 注释。我认为接下来我会尝试清理和重建您的项目(有关如何依赖于您的 IDE 的详细信息)。这是为了确保您的 FXML 的最新版本已部署到构建目录。 (而且,你知道,确保 FXML 被保存,等等......)

标签: javafx


【解决方案1】:

如果您使用 Eclipse.With Eclipse,我会添加此答案 您使用 SceneBuilder 保存的文件的差异不是 同步。

因此,每次使用 SceneBuilder 保存 fxml 文件时,您必须在 Tab 中重新打开它。我的意思是:

1)

假设您在当前工作的项目中打开了 4 个选项卡。如果其中一个选项卡是对 fxml 文件的引用,那么每次您从 @987654326 保存 fxml 文件时@go 选择另一个选项卡,然后再次选择引用 FXML 文件的选项卡。

2)

如果在引用 FXML 文件的项目中未打开任何选项卡,则进入项目并将 FXML 文件打开到新选项卡并执行 1。

示例图片

终于

每次保存 FXML 时都必须执行 1 或 2->1。那就是 Eclipse :)

【讨论】:

  • 我记得我也必须这样做。
猜你喜欢
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-22
  • 2013-04-08
  • 2011-06-03
  • 2012-02-25
  • 1970-01-01
相关资源
最近更新 更多