【问题标题】:JavaFX Object is always null after launchJavaFX 对象在启动后始终为空
【发布时间】:2014-12-01 18:59:17
【问题描述】:

我正在尝试使用 JavaFX 创建一个应用程序。但是JavaFX Application并不是Application的主入口。

我正在使用Main-Class、Controller-Class(控制一切)和其他类,如 JavaFX Application

Main -(calls)-> Controller -(creates)-> JavaFX Application

JavaFX Application对象创建后,Controller调用了一个方法,所以JavaFX Application对象有Controller的实例

但只要我不在方法调用范围内,这个对象就始终为空。

Main

public class Main{
    public static void main(String[] args){
        Controller c = new Controller();
    }
}

Controller

public class Controller{
    private MyApplication app;

    public Controller(){

        app = new MyApplication(); //create Application
        app.setController(this); //set Controller Object
        app.startApplication(); //launch the application

    }

}

MyApplication

public class MyApplication extends Application {

    private Stage primaryStage;
    private BorderPane rootLayout;
    private Controller controller;

    @Override
    public void start(Stage primaryStage) {
        this.primaryStage = primaryStage;
        initRootLayout();
    }


    public void setController(Controller con){
        this.controller = con;
    }



    public void startApplication(String... args){
        launch(args);
    }

    public void initRootLayout(){
        System.out.println(controller==null); //returns true. But why?

        try{
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(MyApplication.class.getResource("view/RootLayout.fxml"));
            rootLayout = (BorderPane) loader.load();

            Scene scene = new Scene(rootLayout);
            primaryStage.setScene(scene);   

            primaryStage.show();
        }
        catch(IOException e){
            e.printStackTrace();
        }

    }
}

怎么回事,MyApplication 中的Controller Instance 始终为空。唯一不为空的时间是在调用setController

【问题讨论】:

  • 能否尝试在 setController 方法中打印 ("1" + this),在 initRootLayout 方法中打印 ("2" + this),因为它为 null 的可能性只有 3 种:1。 setter 稍后调用,2. 它在某个地方再次设置为 null,3. 您正在使用 MyApplication 的另一个对象。检查输出对象是否相同,第一个在第二个之前。
  • 我的猜测是,launch(args) 会创建一个新的 MyApplication
  • @EyeSpy 没错。在 JavaFX 应用程序中,Application 子类是应用程序的入口点(相当于“传统”Java 应用程序中具有 main 方法的类)。所以这种自定义引导并不真正支持。
  • @James_D 是否可以有一个“普通”的 Java Main 方法,但是在不使用应用程序的情况下创建一个 JavaFX UI?我想要一个应用程序,主要在系统托盘中运行,但有一些 UI 可以在需要时调用。

标签: java nullpointerexception javafx


【解决方案1】:

由于 JavaFX 没有系统托盘访问权限,因此您基本上需要一个 AWT 应用程序才能在系统托盘中运行。然后,我会考虑使用JFXPanel 在 Swing 中嵌入 JavaFX 方面,并基本上使其成为嵌入了一些 JavaFX 的 Swing/AWT 应用程序。

或者,您可以从 Application 子类启动所有内容,并在 start 方法中引导 AWT 部分,设置触发器以在需要时执行 JavaFX 工作。不过感觉更丑。

最后,您的方法确实失败了,因为您需要将对象传递给 JavaFX 应用程序。如果使该对象成为单例对象是有意义的,那么您可以让 JavaFX 应用程序检索它,而不是将对象传递给它。

【讨论】:

  • 谢谢。我将在网上研究一些关于 Tray+JavaFX 的方法,并使用对我和我的编码风格最自然的解决方案。
【解决方案2】:

我认为您的问题是您引用了 Controller 类的不同实例。在调用launch(args) 之后,JavaFX 会创建自己的 Application 类的私有实例。当您调用setController 时,您正在为与JavaFX 使用的类不同的实例设置控制器。解决此问题的一种方法是将控制器变量及其设置器设为静态。

【讨论】:

    猜你喜欢
    • 2016-07-23
    • 2016-06-01
    • 2015-06-04
    • 1970-01-01
    • 2017-09-12
    • 1970-01-01
    • 2018-09-19
    • 1970-01-01
    • 2019-05-27
    相关资源
    最近更新 更多