启动JavaFX应用程序时使用内部NPE [英] Internal NPE when launching JavaFX Application

查看:68
本文介绍了启动JavaFX应用程序时使用内部NPE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,基本上,我开始了一个虚拟JavaFX项目,只是为了实现针对我的实际问题的一个简单示例.但是现在我什至无法运行该简约项目,并且没有收到足够的错误信息来亲自搜索它.因此,现在,当我运行代码时,我收到给定的错误堆栈,该错误堆栈不会带我到任何地方.

So basically I began a dummy JavaFX project just to achieve a minimalistic example for my actual problem. But now I am not even able to run that minimalistic project anymore and do not receive enough error information to actually google it myself out. So right now, when I run the code, I receive the given error stack, which does not lead me anywhere.

我正在使用IntelliJ.JavaFX库设置正确,VM选项设置为:-模块路径"C:\ Program Files \ Java \ javafx-sdk-11.0.2 \ lib" --add-modules javafx.controls,javafx.fxml

I am using IntelliJ. JavaFX libraries are set correctly and VM Options set to: --module-path "C:\Program Files\Java\javafx-sdk-11.0.2\lib" --add-modules javafx.controls,javafx.fxml

最重要的是,当我运行代码时,这些错误会在控制台中弹出,但该应用程序似乎仍在运行,因为我需要按下IntelliJ的红色停止按钮才能真正停止它.

On top, when I run the code, those errors pop up in console, but the application seems to still be running, because I need to press the Red Stop Button of IntelliJ to actually stop it.

有人猜到这里出了什么问题吗?我没有足够的经验来应对这些错误,因为这些错误不是指向我的代码,而是指向某些Deep Java代码.

Has anyone some guess, what goes wrong here? I am not experienced enough to follow those errors, since they do not point into my code, but rather into some Deep Java code.

例外:

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

Main.java:

Main.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);
    }
}

MainWindow.fxml:

MainWindow.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" />

MainWindowController:

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;
    }
}

Left.fxml:

Left.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>

LeftController.java:

LeftController.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 ,则该错误将消失.

Solution

The error you're getting is caused by your main(String[]) method not being static. If you make it static then the error will go away.

只要主类是 Application 的子类,JavaFX便可以在不提供main方法的情况下启动应用程序.但是,开发人员仍可以包括main方法,这意味着特殊启动功能具有优雅地处理这种情况.换句话说,从开发者的角度来看,存在于 Application 子类中的显式main方法必须像应用程序的入口点一样工作.尽管如此,在幕后,一些深层的内部阶级已经成为真正的"主要阶级.

JavaFX offers the ability to launch applications without providing a main method, so long as the main class is a subclass of Application. However, developers can still include a main method which means this special launch functionality has to handle that situation gracefully. In other words, an explicit main method present in the Application subclass must act like the entry point of the application from the developer's point of view. Nonetheless, behind the scenes some deep internal class has become the "real" main class.

为此,通过

To do this, the main method is located—if present at all—via Class#getMethod(String,Class...) which, while only returning public methods, doesn't distinguish between static and non-static methods. If found, Method#invoke(Object,Object...) is used to invoke the main method reflectively. The first argument of invoke is the instance that the method should be invoked on; in the case of static methods the value is null. Unfortunately, the code assumes the method it found is static which causes a NullPointerException to be thrown—you can't call an instance method on a null "instance".

更新:该问题已在GitHub上提交( JDK-8230119 ).当前的想法是发出警告,而不是抛出 NullPointerException .但是,在将来的发行版中可能会弃用允许不使用主要方法启动的功能,这将影响解决此问题的方式.

Update: This issue has been submitted on GitHub (#570) and subsequently JBS (JDK-8230119). The current idea is to emit a warning rather than throw the NullPointerException. However, the functionality that allows launching without a main method may be deprecated in a future release, which will affect how this issue is addressed.

这篇关于启动JavaFX应用程序时使用内部NPE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆