Why does WindowClosing handler not execute Background Tasks before exiting program?

490 Views Asked by At
mainFrame().addWindowListener(new java.awt.event.WindowAdapter() {
    @Override
    public void windowClosing(java.awt.event.WindowEvent evt)
    {
        retrieveItems();
        closeAllConnections();
        System.exit(0);
    }
});

For the code above, retrieveItems() executes nicely but there is a Background Task called doBackup() that's inside closeAllConnections() which does not execute at all. The program just seems to skip the task. Here is a brief view of what closeAllConnections() contains;

public void closeAllConnections()
{
    boolean shouldBackup = getBackupOnCloseStatus();
    if(shouldBackup)
    {
        doBackUp();
    }
    dbManager.disconnectDB();
}

After using the Netbeans Step-Debugger, I noticed that the program execution does not even enter the doBackup() method before application exits. This is strange. I would highly appreciate any help as regards what might be causing this behaviour. Thanks good people!

Just if this piece of extra info might be helpful in finding a solution, I'm using Swing Application Framework, so the the Task doBackup() looks like the following...

@Action
public Task doBackUp()
{
    return new DoBackUpTask(getApplication());
}

private class DoBackUpTask extends org.jdesktop.application.Task<Object, Void> 
{
    private boolean done = false;

    DoBackUpTask(org.jdesktop.application.Application app) 
    {
        super(app);
        this.setMessage("Backing-up database...");
    }

    @Override 
    protected Object doInBackground() 
    {
        File destDir = new File(appManager.getBackUpDir());
        done = backUpDataBase(destDir);
        return null;
    }

    @Override 
    protected void succeeded(Object result) 
    {
        if(done)
        {
            setMessage("BackUp completed.");
        }
    }
}
2

There are 2 best solutions below

1
Lucullan On

This may not be the best answer, but I have noticed that when calling System.exit(0) sometimes it will cut everything off. I was having a problem once when calling a method that depended on results from the previous line. All should be well, but it didn't work right because it was getting to the execution of the next line before the previous line was finished. I'm sure someone can talk more about the event dispatch thread and why this seemed to happen even though everything about computer science says it shouldn't. But here's my thought: Add a boolean return value to closeAllConnections to return true when complete, then re-write your window listener like this:

    mainFrame().addWindowListener(new java.awt.event.WindowAdapter() {
    @Override
    public void windowClosing(java.awt.event.WindowEvent evt)
    {
        boolean isClosed = false;
        while(!isClosed){
            retrieveItems();
            isClosed = closeAllConnections();
        }    
        System.exit(0);
    }
});

Maybe this will help.

1
Ryan Stewart On

My guess would be that you have another WindowListener elsewhere that's calling System.exit() or else you're doing a JFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE), either of which will cause the app to terminate immediately, regardless of whatever other threads are executing.