启动后,JavaFX Object始终为null

时间:2014-12-01 18:59:18

标签: java nullpointerexception javafx

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

我使用的是Main - 类,Controller - 类(控制所有内容),以及其他类,例如JavaFX Application

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

创建JavaFX Application对象后,Controller会调用方法,因此JavaFX Application对象的实例为Controller

但是,只要我在方法调用之外,此对象始终为null。

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

    }
}

为什么Controller MyApplication内的实例始终为空。它唯一不为空的时间是在setController

之内

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

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