我在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?
答案 0 :(得分:1)
在
Application.launch(View.class)
正在创建一个View的新实例,默认情况下它对事件处理程序具有空值,并且与您自己创建的View类不同。此外,如果您注意到View类的init()方法只调用一次。这是由Application.launch方法调用的。
我建议将View和Application逻辑拆分为不同的类。即不要从Application
扩展视图,创建另一个扩展Application的类MainApp。
答案 1 :(得分:0)
你设置字段了吗?
firstpar