Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OnViewRemoved method is not invoked on Window closed #591

Open
piterso opened this issue May 7, 2019 · 3 comments
Open

OnViewRemoved method is not invoked on Window closed #591

piterso opened this issue May 7, 2019 · 3 comments

Comments

@piterso
Copy link

piterso commented May 7, 2019

When i open new Window from my "Main Application Window" after closing new Window method onViewRemoved in my ViewModel is not invoked.
I use also SpringBoot in my project and i try using @PreDetroy on both @component scopes (prototype and singleton) - won't help. @PreDestroy is only invoked for singleton components and after whole application is closed but i want to listen for event when one of the windows in my application is closed.

This is the code that opens new window

Parent parent = FluentViewLoader.fxmlView(TestView.class).load().getView();
Stage stage = new Stage();
stage.setTitle("Test");
stage.setScene(new Scene(parent));
stage.show();

I got ViewModel for TestView it looks like this:

@Component
@Scope("prototype")
@Slf4j
public class TestViewModel implements ViewModel, SceneLifecycle {

    public void initialize() {
        
    }

    @Override
    public void onViewAdded() {
        log.debug("View added to application");
    }

    @Override
    public void onViewRemoved() {
        log.debug("View removed from the application");
    }
}

After closing new Window based on TestView method onViewRemoved on TestViewModel is not invoked. It's pretty important for me to actually make it work.

I figure out that i can set on stage listener on close request like that:

stage.setOnCloseRequest(windowEvent -> {
            // .. some code
        });

I manage to make that work in that way:

ViewTuple<TestView, TestViewModel> viewTuple = FluentViewLoader.fxmlView(TestView.class).load();
TestViewModel viewModel = viewTuple.getViewModel();

Stage stage = new Stage();
stage.setTitle("Test");
stage.setScene(new Scene(viewTuple.getView()));
stage.setOnCloseRequest(windowEvent -> viewModel.stop());
stage.show();

is this the best way for doing this? onViewRemoved won't be invoked?

Do you have anny suggestions?

@manuel-mauky
Copy link
Collaborator

The onViewRemoved method is listening to when the View is removed from the JavaFX scene-graph. Basically we use a listener on the sceneProperty of Node.
For some reason this property isn't automatically reset to null when the window is closed.

I managed to get it working with this code:

stage.setOnCloseRequest(windowEvent -> {
	stage.getScene().setRoot(new VBox());
});

This explicitly changes the root-node of the scene so that the old root-node (your Window view) is removed from the scene. Maybe it's a good idea to wrap the setRoot call in a Platform.runLater because I don't know if there are any timing problems when you remove the root node before the window is actually closed as the callback is on "close request".

@piterso
Copy link
Author

piterso commented May 14, 2019

Thanks for your answer.
Is your solution better than my code? Do my code can cause some problems?

@manuel-mauky
Copy link
Collaborator

No, your code also works fine. The advantage of your code is that you don't depend on strange behavior of JavaFX (like not resetting the scene). The disadvantage is that your ViewModel has to explicitly provide the stop method and you have to invoke this method manually in your app class which introduces a dependency form the app class to this specific viewModel.
If later in time you implement another ViewModel which needs the same logic then you would also have to adjust your app class again.

Other then that I don't see any disadvantages in your code. Both solutions are trade-offs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants