【发布时间】:2016-01-04 13:43:37
【问题描述】:
我正在 JavaFX 中创建一个小程序,并且有一个需要分配 EventHandler 的按钮。我在我的视图(扩展应用程序的类)的 init() 方法中创建并分配了这个按钮。
Button ok = new Button(" OK ");
ok.setOnAction(this.eventHandler);
理想情况下,我想在构造 View 对象时传递这个 eventHandler,但是我在这样做时遇到了一些困难,所以我决定只使用一个简单的 setter。
public void setEventHandler(EventHandler<ActionEvent> eventHandler) {
this.eventHandler = eventHandler;
}
为了开始一切,我在 Controller 类的 main 方法中运行了几行代码:
View v = new View();
v.setEventHandler(new HandleOk(v));
javafx.application.Application.launch(View.class);
其中 HandleOk 是 EventHandler。它需要对我的视图类的引用,以便它可以查询其某些字段的状态,因此是用视图构造的。运行此代码并单击 JavaFX 按钮会导致空指针异常。
然后我设置了三个System.out.format("Event handler is null: %b\n", v.eventHandler == null);,一个在我的 Controller 的 main 方法中,一个在我的 View 的 init() 方法(从 JavaFX 应用程序继承的方法)的顶部,以及在按钮的 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 传递给视图?
【问题讨论】:
-
不是“javafx.application.Application.launch(View.class);”创建自己的视图实例?这意味着您在此之前所做的任何事情都将毫无意义,因为正在显示的实例不是您创建的实例
-
文档确认了您的答案,所以现在我知道为什么该字段似乎被重置了。 Launch 是一个 void 方法,不会返回对实例的引用,所以我仍然不知道如何从外部传入 HandleOk。