所以我尝试使用WINDOW_SHOWN如下代码处理来自控制器的事件:
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    initializeDatePickers();
    System.out.println("payer number in initialize: " + payerNumber);
    URL location = getClass().getResource("/createUser.fxml");
    FXMLLoader loader = new FXMLLoader();
    try {
        Parent root = (Parent) loader.load(location.openStream());
        root.getScene().getWindow().setOnShown(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent event) {
                System.out.println("ONSHOWN");
            }
        });
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)
但我所得到的只是无休止的循环和程序崩溃。下面的代码也不起作用,它返回 NullPointerException:
@FXML private AnchorPane createUserDialog; //my root pane
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    createUserDialog.getScene().getWindow().addEventHandler(WindowEvent.WINDOW_SHOWN, 
      new EventHandler<WindowEvent>() {
        @Override
        public void handle(WindowEvent window) {
            System.out.println("ONSHOWN");
        }
    });
}
Run Code Online (Sandbox Code Playgroud)
实现 WindowEvent 接口根本不起作用,不知道为什么。那么,我该如何处理这个事件呢?为什么我会遇到 NullPointerException?在文档中说,initialize()仅在根窗格完全处理后调用。
当执行initialize()方法时,根窗格已完全构建,但不会添加到场景或窗口中。(initialize() 方法是作为 FXMLLoader 的 load() 方法执行的一部分而执行的;检查调用该方法的代码,您将看到您将根添加到场景中,然后将其放置在窗口中。)因此在 intialize() 执行过程中,root.getScene() 将返回 null。
您可以使用 Binding 来检查窗口何时更改并向其附加侦听器:
final EventHandler<WindowEvent> shownHandler = new EventHandler<WindowEvent>() {
  @Override
  public void handle(WindowEvent event) {
    System.out.println("Shown");
  }
};
Bindings.<Window>select(createUserDialog.sceneProperty(), "window").addListener(new ChangeListener<Window>() {
    @Override
    public void changed(ObservableValue<? extends Window> observable,
            Window oldValue, Window newValue) {
        if (oldValue != null) {
            oldValue.removeEventHandler(WindowEvent.WINDOW_SHOWN, shownHandler);
        }
        if (newValue != null) {
            newValue.addEventHandler(WindowEvent.WINDOW_SHOWN, shownHandler);
        }
    }
});
Run Code Online (Sandbox Code Playgroud)
此代码假设根仅添加到一个窗口;万一您在应用程序生命周期中将根从一个窗口取出并将其放入另一个窗口中,则需要从旧窗口中删除侦听器。如果您需要这个,我会更新代码,但这会使代码变得更加复杂。