2014-02-06 46 views
1
處理

所以我想從我的控制器處理WINDOW_SHOWN事件與這樣的代碼:JavaFX的2窗口事件控制器

@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?在文檔中說initialize()只有在根窗格完全處理後纔會調用。

回答

4

執行initialize()方法時,根窗格是完全構建的,但不會添加到場景或窗口中。 (initialize()方法是作爲執行FXMLLoader的load()方法的一部分執行的;檢查你調用的代碼,你會看到你將一個場景添加到一個場景中,然後把它放在一個窗口中。)所以在執行intialize()時,root.getScene()將返回null。

您可以使用綁定來檢查窗口更改時,並附上監聽到它:

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); 
     } 
    } 

}); 

此代碼假定根只會被添加到一個窗口;在極少數情況下,您將root從一個窗口中取出並在應用程序生命週期中放入另一個窗口,您需要從舊窗口中刪除偵聽器。如果你需要這個,我會更新代碼,但它會使它更復雜。

+0

是的,我需要它。 – user3262222

+0

正式更新... –