簡體   English   中英

控制器中的JavaFX 2 Window事件處理

[英]JavaFX 2 Window event handling in controllers

所以我正在嘗試使用以下代碼從控制器處理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();
    }

}

但是我所得到的只是無休止的循環和程序崩潰。 下面的代碼也不起作用,它返回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");
        }
    });

}

實現WindowEvent接口根本行不通,不知道為什么。 那么,我該如何處理此事件? 以及為什么我有NullPointerException? 在docs中表示只有在根窗格完全處理后才調用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);
        }
    }

});

此代碼假定僅將根添加到一個窗口中。 在極少數情況下,如果您在應用程序生命周期中將根從一個窗口中移出,然后又將其放置在另一個窗口中,則需要從舊窗口中刪除偵聽器。 如果需要,我將更新代碼,但這會使它更加復雜。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM