penny
penny

Reputation: 457

How to force-close a window in Java?

I'm looking to force-close a Java window even if a function is currently running - is there a way to do this? I have some functions that take quite a while in certain conditions (eg. running from a CD or another non-local location) and I want to be able to force-stop those functions and completely exit the program. Is this possible? And how can I go about doing it?

My code for exiting is below:

this.addWindowListener(new java.awt.event.WindowAdapter() {
    @Override
    public void windowClosing(java.awt.event.WindowEvent windowEvent) {
        if (closeApplication()) {
            System.exit(0);
        }
    }
});

And the closeApplication() function:

private boolean closeApplication() {
    final JFrame temp = this;
    int exitDialogResult = JOptionPane.showConfirmDialog(temp, 
            "Are you sure you want to exit?", "Really Closing?", 
            JOptionPane.YES_NO_OPTION,
            JOptionPane.QUESTION_MESSAGE);
    if (exitDialogResult == JOptionPane.YES_OPTION) {
            //code here to stop various processes               
            return true;
        }
    else {
        return false;
    }
}

Quick edit to clarify: when my program is executing a long-running function and I attempt to close the window, the window listener doesn't even register the click.

Upvotes: 0

Views: 1590

Answers (2)

Stefan Dollase
Stefan Dollase

Reputation: 4620

It seems like you are executing your long-running operations in the event dispatch thread. This is the thread which is used by the GUI to trigger all events. Thus, if you block this thread, your GUI is blocked. The close operation of a JFrame is one of these operations. This is the reason why it is not triggered while a long-running operation is executed in the GUI thread.

To fix this, you should think about what the long-running operation is doing. In any case, you should move it to a background thread:

  • Does it execute an operation which can be canceled at any time, without bad things happening? In this case, you can put the operation in a daemon thread. This tells the JVM, that this thread can be terminated at any time. It should not keep the JVM alive. An example for this is an operation which requests information from a web API.

  • else If bad things happen when you terminate the long-running operation at any point, then you should put the operation in a non-daemon thread. In this case, it is also a bad idea to use System.exit to shutdown your application, since this will also just kill the non-daemon threads. You need to implement a mechanism which terminates the background thread gracefully, or waits for it to finish. This can sometimes be difficult, but it is necessary. An example for this type of long-running operation is to write to a file: If you just terminate this operation, then the file will be corrupted.

See also What is Daemon thread in Java?

If you want to use an ExecutorService for your long-running operations, then you might be interested in the method ExecutorService::shutdown:

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.

Upvotes: 1

Branislav Lazic
Branislav Lazic

Reputation: 14806

The problem you are facing is obvious: Your applications is getting "frozen" during long running background task because it executes on event dispatch thread. Use SwingWorker. That way, your GUI will remain responsive while your long running task runs on background thread. You could use System.exit() for termination, but safest way would be to wait until your long running task is done.

Upvotes: 3

Related Questions