How to run a function after Stage.show()?
Asked Answered
E

2

5

I'm struggling with a problem where one chunk of code runs before it's initialized.

@FXML
public void Start(int pesel) throws IOException {
    klientPesel = pesel;
    root = FXMLLoader.load(getClass().getClassLoader().getResource("klientScene.fxml"));
    Main.mainStage.setTitle("Agencja Ubezpieczniowa - Agent");
    Scene scene = new Scene(root,800,600);
    Main.mainStage.setScene(scene);
    Main.mainStage.show();
    obtainKlient();
    setKlientLabels();
}

The problem is that I have a variable @FXML private VBox KlientInfoVBOX; and it's not initialized before setKlientLabels() runs. How do I make sure that setKlientLabels() will run after Main.mainStage.show();?

Maybe stacktrace will help to resolve the problem

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at app.KlientSearchController.setKlientLabels(KlientSearchController.java:69)
    at app.KlientSearchController.Start(KlientSearchController.java:51)
    at app.UserSceneController.StartKlientSearch(UserSceneController.java:87)
    at app.UserSceneController.lambda$wyszukajKlienta$0(UserSceneController.java:70)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Node.fireEvent(Node.java:8411)
    at javafx.scene.control.Button.fire(Button.java:185)
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:352)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:388)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:937)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:745)

If I remove setKlientLabels() from the code to run there are no exceptions, everything runs smoothly.

Engel answered 3/2, 2017 at 15:46 Comment(2)
Look about 'Task java8' on Google, it allows you to launch things into a new Thread, so the code after is executedBlotto
The variable is initialized in the controller, not in the current object.Ringmaster
E
6

You need to set onShowingProperty () of your Stage. When the stage shows, the onShowingProperty () will be fired. To set onShowingProperty () simply use setOnShowing () method.

Main.mainStage.setOnShowing(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent event) {
        setKlientLabels();
    }
});
Main.mainStage.show();
Epicenter answered 3/2, 2017 at 16:46 Comment(2)
'setKlientLabels()' never fires now.Engel
Use Main.mainStage.setOnShown(...). if you want to run your function after the window is showing on the screen. This occurs after setOnShow() is called.Parole
C
1

The Main.mainStage.setOnShowing() solution did not work for me in JavaFX 11, but putting this in the main application class did:

@Override
public void start(Stage stage) {
    stage.addEventFilter(WindowEvent.WINDOW_SHOWN,
        new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent event) {
                log.info("Stage shown and {} total windows existing",
Window.getWindows().size()");
            }
        }
    );
}

or this simpler lambda expression equivalent:

stage.setOnShown((event) -> {
    log.info("Stage shown and {} total windows existing",
Window.getWindows().size());
});

This works for running code after any JavaFX stage/window including the primary stage.

Congressman answered 11/7, 2021 at 1:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.