JavaFX init()方法将字段重置为null

时间:2016-01-04 05:10:29

标签: java javafx

我在JavaFX中创建一个小程序,并且有一个我需要分配一个EventHandler的Button。我在我的View(扩展Application的类)init()方法中创建并分配了这个按钮。

Button ok = new Button("   OK   ");
ok.setOnAction(this.eventHandler);

理想情况下,我想在构建View对象时传递这个eventHandler,但是我在这方面遇到了一些困难,所以我决定只使用一个简单的setter。

public void setEventHandler(EventHandler<ActionEvent> eventHandler) {
 this.eventHandler = eventHandler;
}

为了解决所有问题,我在Controller类的主要方法中运行了几行代码:

View v = new View();
v.setEventHandler(new HandleOk(v));
javafx.application.Application.launch(View.class);

HandleOk是EventHandler的地方。它需要对我的视图类的引用,以便它可以查询其某些字段的状态,因此使用View构造。运行此代码并单击JavaFX按钮会导致空指针异常。

然后我设置了三个System.out.format("Event handler is null: %b\n", v.eventHandler == null);,一个在我的Controller主要方法中,一个在我的View的init()方法(从JavaFX Application继承的方法)的顶部,并且在按钮的setOnAction方法中。因此如下:

public class Controller {
  //~~ other stuff ~~
  public static void main(String[] args) {
    View v = new View();
    v.setEventHandler(new HandleOk(v));
    System.out.format("Event handler is null: %b\n", v.eventHandler == null);
    javafx.application.Application.launch(View.class);
  }
 //~~ other stuff ~~
}

public class View extends Application {
  EventHandler<ActionEvent> eventHandler;

  public void setEventHandler(EventHandler<ActionEvent> eventHandler) {
    System.out.println("Event Handler set");
    this.eventHandler = eventHandler;
  }

  @Override
  public void init() {
    System.out.format("Event Handler in init() is null: %b\n", eventHandler == null);
  //  ~~ other stuff ~~
    Button ok = new Button("   OK   ");
    ok.setOnAction((ActionEvent) -> {
      System.out.format("Event Handler in button is null: %b", this.eventHandler == null));
      if (!(this.eventHandler == null) {
        this.eventHandler.handle(ActionEvent);
      }
    });
 //   ~~ other stuff ~~
  }

运行它并单击我的javaFX应用程序中的按钮会导致以下内容被打印到控制台:

Event Handler set
Event Handler is null: false
Event Handler in init() is null: true
Event Handler in button is null: true

有趣的是,在我的init()方法中添加以下行会删除空指针异常,并且我的应用程序可以正常工作。

public void init() {
  eventHandler = new Controller.HandleOk(this);
 // ~~  other stuff ~~
}

理想情况下,我希望我的控制器将HandleOk传递给我的视图,而不是我的视图必须从控制器中获取HandleOk。我只能得出结论,当JavaFX加载一个扩展应用程序的类时,它会重置已初始化的任何字段,从而导致您只能初始化init()方法中的字段。如何从外部源将HandleOk传递给View?

2 个答案:

答案 0 :(得分:1)

Application.launch(View.class)

正在创建一个View的新实例,默认情况下它对事件处理程序具有空值,并且与您自己创建的View类不同。此外,如果您注意到View类的init()方法只调用一次。这是由Application.launch方法调用的。

我建议将View和Application逻辑拆分为不同的类。即不要从Application扩展视图,创建另一个扩展Application的类MainApp。

答案 1 :(得分:0)

设置字段了吗?

firstpar