Properly shutting down a JME app on pressing [X]

When I press [X] on the window, the stop() method of my app does not get called. How can I hook clicking the [X] to calling the stop() method, the same way as it works with the ESC key mapping by default?

I have found a couple of topics on this here but I could not find a definitive answer there… Even if I have some threads running somewhere (which I don’t) I still want to be able to call stop() on clicking [X]. I guess that’s more Java issue than JME itself though…

Well you can register a shutdownlisterner in the Systme or Runtime (not sure wich it was)

However as your app can be killed from a taskmanager, it must be able to recover from ungracefull shutdowns.

AppState.cleanup()

Edit: you haven’t really said what you want to do with it… but the cleanup() method of an app state is the best way to detect application shutdown.

Thanks for the suggestions but I want to update the question, and that may introduce new factors. I am sorry for not giving the full info from the beginning, but I myself had got the clear vision of what is going on and what must be just recently. So:

  1. The Runtime hook does not work since the runtime is not shut down, i.e. the JVM must go on with other threads after the app window is closed. The JME app is launched from a different thread and that thread must still live after the app was closed with [X]. However, still I must somehow catch the event of the user clicking [X].

  2. I did not quite get it about the AppState. Isn’t an AppState just something inside an app? Why would it call the stop() method of the entire Application?

My scenario is this: a thread can decide to launch a JME app in a window. And it does it. After the user has finished working with the app he can close it, causing the total destruction of everything, as it would happen if the app was launched by itself. However, the JVM with the original thread must still continue to run, and be able to create the app again, and so on…

@noncom said: Thanks for the suggestions but I want to update the question, and that may introduce new factors. I am sorry for not giving the full info from the beginning, but I myself had got the clear vision of what is going on and what must be just recently. So:
  1. The Runtime hook does not work since the runtime is not shut down, i.e. the JVM must go on with other threads after the app window is closed. The JME app is launched from a different thread and that thread must still live after the app was closed with . However, still I must somehow catch the event of the user clicking .

  2. I did not quite get it about the AppState. Isn’t an AppState just something inside an app? Why would it call the stop() method of the entire Application?

My scenario is this: a thread can decide to launch a JME app in a window. And it does it. After the user has finished working with the app he can close it, causing the total destruction of everything, as it would happen if the app was launched by itself. However, the JVM with the original thread must still continue to run, and be able to create the app again, and so on…

So what exactly is the issue?

Are you keeping the original thread running? (If not then the whole app will shut down.) Nothing in JME will force the JVM closed so I don’t know what is tripping you up.

Are you having problems starting the app a second time?

Does your computer self-combust and turn into a pile of slag?

What have you tried? What is failing? etc.

See, the original question:
“How can I hook clicking the [X] to calling the stop() method, the same way as it works with the ESC key mapping by default?”

You can’t. But you don’t need to either.

You will need to explain why you think you need to so that I can show you that you can do it with an AppState or some other mechanism.

Alright, so here what happens:

  1. I have a JVM with a thread, running for a very continuous time, say, weeks.
  2. On user request that thread can launch a JME app, it creates an instance of it and holds the reference to it.
  3. The app is launched in the window mode.
  4. The user interacts with the JME app.
  5. The user finishes the interaction and closes it with the [X].
  6. Here the program must somehow know that the app was closed. I presumed that the stop() method be called but it does not.
  7. So literally I do not know if the app was shut down by the user. The stop() method which does some important cleanup is not called. And I did not find anything to make the program notice the app is closed.
    8 ) Ideally when the app is closed, the stop() method is called to release the resources. Or if that is imossible, I have to at least somehow recognize the app was closed and release them somewhere else although that’d be sad. Or manually call the stop() method which is close to ok.
  8. So what happens is that the JME window gets closed and the original thread continues to run, BUT the JME app is not destroyed completely. It still posesses all the resources it grabbed, including network ports which is unacceptable.
@noncom said: Alright, so here what happens:
  1. I have a JVM with a thread, running for a very continuous time, say, weeks.
  2. On user request that thread can launch a JME app, it creates an instance of it and holds the reference to it.
  3. The app is launched in the window mode.
  4. The user interacts with the JME app.
  5. The user finishes the interaction and closes it with the .
  6. Here the program must somehow know that the app was closed. I presumed that the stop() method be called but it does not.
  7. So literally I do not know if the app was shut down by the user. The stop() method which does some important cleanup is not called. And I did not find anything to make the program notice the app is closed.
    8 ) Ideally when the app is closed, the stop() method is called to release the resources. Or if that is imossible, I have to at least somehow recognize the app was closed and release them somewhere else although that’d be sad. Or manually call the stop() method which is close to ok.
  8. So what happens is that the JME window gets closed and the original thread continues to run, BUT the JME app is not destroyed completely. It still posesses all the resources it grabbed, including network ports which is unacceptable.

So what of this list hasn’t been addressed yet in this thread? I think all points have been explained. You don’t need to use stop, just use appState.cleanup(), stop() is only supposed to be called by users, not overridden.

Normen, ok, but what is that appState which I should call cleanup() of? Yes the app may have app states but which one is the right one? This is what I do not understand.

You override it…

Omg that all makes me feel so stupid, I just don’t get what you’re saying this time. Do I just get any AppState in my app and put the releasing code there? Reading the source of Application I see that the ContextListener cleans up the AppStateManager which in turn cleans up all the AppStates. And I assume the ContextListener gets the signal of the window being close? Am I right this time? :slight_smile:

Make your own app state. Attach it to the app state manage. When the cleanup method is called then do what you want to do.

I thought this was covered by one of the tutorials. App states that is.

Afaik you can also override destroy() from SimpleApplication. Make sure you call super though. I used that for a bit, but discarded that way of doing things.

Ok, so what puzzled me was why do I put application-wide functions into a JME AppState, even if they do not exactly belong to the JME app. And especially why do I invent an AppState for that, when there is actually no reason to put it in there. But ok, if you say that’s the way, I’ll follow…

@madjack: that’s more like what I think it should look like… but you’ve given it up… in favor of what?

@noncom said: @madjack: that's more like what I think it should look like.. but you've given it up... in favor of what?

Because when destroy() is called, it’s already too late, I can’t abort the closing by the user. The original idea was to ask the players if they wanted to save before closing, but I changed my mind on the subject. Let them close it without saving if they feel like it.

@noncom said: Ok, so what puzzled me was why do I put application-wide functions into a JME AppState, even if they do not exactly belong to the JME app. And especially why do I invent an AppState for that, when there is actually no reason to put it in there. But ok, if you say that's the way, I'll follow...

Think of it like a listener with a bunch of extra methods.