Я создаю небольшую программу в JavaFX и имею кнопку, которую мне нужно назначить EventHandler. Я создаю и назначаю эту кнопку в методе init() класса View (класс, который расширяет Application).Метод инициализации JavaFX init() в значение null
Button ok = new Button(" OK ");
ok.setOnAction(this.eventHandler);
В идеале я хотел бы передать эту EventHandler в том, когда я построить вид объекта, но у меня были некоторые трудности делают это, так я решил сам просто используя простой метод установки.
public void setEventHandler(EventHandler<ActionEvent> eventHandler) {
this.eventHandler = eventHandler;
}
Чтобы начать все с, я бегу несколько строк кода в основной метод моего класса контроллера:
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);
, один из которых в моем основном методе контроллера, один в верхней части моего метода 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
Интересно, добавив следующую строку в моей инициализации () удаляет исключение нулевого указателя, и мое приложение работает.
public void init() {
eventHandler = new Controller.HandleOk(this);
// ~~ other stuff ~~
}
В идеале я хотел бы мой контроллер, чтобы передать в HandleOk на мой взгляд, и не мой взгляд, чтобы захватить HandleOk от моего контроллера. Я могу только заключить, что когда JavaFX загружает класс, расширяющий приложение, он сбрасывает все инициализированные поля, что приводит к ситуации, когда вы можете инициализировать поля только в методе init(). Как я могу передать HandleOk в представление из внешнего источника?
Не "javafx.application.Application.launch (View.class);" создать собственный экземпляр View? Это означало бы все, что вы делали до того, как это будет бессмысленно, поскольку экземпляр, который отображается, не является созданным вами экземпляром. – MadProgrammer
Документация подтверждает ваш ответ, поэтому теперь я знаю, почему поле, похоже, сбрасывается. Запуск - это метод void и, однако, не возвращает ссылку на экземпляр, поэтому я все еще теряюсь в том, как проходить в HandleOk извне. –