簡體   English   中英

啟動 JavaFX 應用程序時的內部 NPE

[英]Internal NPE when launching JavaFX Application

所以基本上我開始了一個虛擬的 JavaFX 項目只是為了為我的實際問題實現一個簡約的例子。 但現在我什至無法再運行那個簡約的項目,也沒有收到足夠的錯誤信息來實際自己用谷歌搜索出來。 所以現在,當我運行代碼時,我收到了給定的錯誤堆棧,它不會引導我到任何地方。

我正在使用 IntelliJ。 JavaFX 庫設置正確,VM 選項設置為:-- --module-path "C:\\Program Files\\Java\\javafx-sdk-11.0.2\\lib" --add-modules javafx.controls,javafx.fxml

最重要的是,當我運行代碼時,控制台中會彈出這些錯誤,但應用程序似乎仍在運行,因為我需要按下 IntelliJ 的紅色停止按鈕才能真正停止它。

有沒有人猜測,這里出了什么問題? 我沒有足夠的經驗來跟蹤這些錯誤,因為它們沒有指向我的代碼,而是指向一些 Deep Java 代碼。

例外:

Exception in thread "main" java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.NullPointerException
    at java.base/java.lang.reflect.Method.invoke(Method.java:559)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
    ... 5 more

主.java:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.io.IOException;

public class Main extends Application {

    private Stage rootStage;
    public BorderPane mainWindow;
    public AnchorPane left;
    public AnchorPane bottom;

    @Override
    public void start(Stage primaryStage) throws Exception {

        this.rootStage = primaryStage;
        loadMainWindow();

    }

    public void loadMainWindow() throws IOException {

            FXMLLoader loaderMainWindow = new FXMLLoader(Main.class.getResource("MainWindow.fxml"));
            mainWindow = loaderMainWindow.load();

            FXMLLoader loaderLeft = new FXMLLoader(Main.class.getResource("Left.fxml"));
            left = loaderLeft.load();


            mainWindow.setLeft(left);
            //mainWindow.setBottom(bottom);


        Scene scene = new Scene(mainWindow);
        rootStage.setScene(scene);
        rootStage.show();

    }

    public void main(String[] args) {
        launch(args);
    }
}

主窗口.fxml:

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

<?import javafx.scene.layout.BorderPane?>


<BorderPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.MainWindowController" />

主窗口控制器:

package sample;

import javafx.fxml.Initializable;

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



public class MainWindowController implements Initializable {

    private Main main;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {

    }

    public void setMain(Main main) {
        this.main = main;
    }
}

左.fxml:

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="400.0" prefWidth="100.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.LeftController">
   <children>
      <Button fx:id="button" layoutX="237.0" layoutY="169.0" mnemonicParsing="false" onAction="#buttonClick" text="Button" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" />
   </children>
</AnchorPane>

左控制器.java:

package sample;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;

import java.awt.event.ActionEvent;
import java.net.URL;
import java.util.ResourceBundle;

public class LeftController implements Initializable {

    @FXML
    private Button button;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {

    }

    public void buttonClick(javafx.event.ActionEvent actionEvent) {
        System.out.println("Some Stuff");
    }
}

解決方案

您得到的錯誤是由您的main(String[])方法不是static 如果您將其static則錯誤將消失。


一些解釋

JavaFX 提供了在不提供 main 方法的情況下啟動應用程序的能力,只要主類是Application的子類。 但是,開發人員仍然可以包含一個 main 方法,這意味着這個特殊的啟動功能必須優雅地處理這種情況。 換句話說,從開發人員的角度來看, Application子類中存在的顯式 main 方法必須充當Application的入口點。 盡管如此,幕后一些深層次的內部類已經成為“真正的”主類。

為此,主要方法通過Class#getMethod(String,Class...)定位(如果存在的話Class#getMethod(String,Class...) ,雖然只返回公共方法,但不區分靜態和非靜態方法。 如果找到,則使用Method#invoke(Object,Object...)反射調用主方法。 invoke的第一個參數是應該調用方法的實例; 在靜態方法的情況下,值為null 不幸的是,該代碼假定它找到的方法是靜態的,這會導致拋出NullPointerException — 您不能在null “實例”上調用實例方法。


更新:此問題已在 GitHub ( #570 ) 和隨后的 JBS ( JDK-8230119 ) 上提交 當前的想法是發出警告而不是拋出NullPointerException 但是,允許在沒有 main 方法的情況下啟動的功能可能會在未來版本中被棄用,這將影響解決此問題的方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM