简体   繁体   中英

How to set a Java Gui listener for unexpected program end

I am making a personal planning program. I utilize XML documents to store user data and login data. This does not utilize a server and all accounts created in the program are localized to the computer it is stored on (in the XML documents.)

In the login XML document, I keep track of the users that are logged in so that one user can't have two windows at the same time to prevent any conflicts with data. This feature runs smoothly and I have no problem with it.

The only thing I want to know is if there is some way to catch an unexpected shut down of a program (such as a task-manager close or a forced close when shutting down the computer) so that I can "log" the user off of the XML document. Otherwise the user would never be able to get back on after an unexpected program close without going into the XML document and deleting the username from the logged in list.

It seems a shutdown hook does not work well with the event queue for a java GUI. much like this thread I tried setting up my code exactly as shown and the shutdown hook doesn't work for me either. Are there any suggestions for ways of catching an unexpected shutdown without shutdown hooks?

this is my code:

import java.awt.EventQueue;

public class Gui {

private static Controller controller;

public static void main (String[] args) {

    controller = new Controller();

    Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                controller.saveState();
                controller.logUserOut();
            }
            });

    EventQueue.invokeLater(
            new Runnable() {
                public void run() {
                    controller.start();
                }
            });
    }
}

This is a closer look at my controller that logs the user out

public void logUserOut() {
    loginDatabase.logUserOut(username);
    saveLoginState();
}

All loginDatabase does is removes that username from the list of logged in users so that user is free to log in again

public void saveLoginState() {
    XStream xStream = new XStream(new DomDriver()); 

    OutputStream outFile;
    try {
        String filePath = "data" + File.separator + "loginDatabase.xml";
        outFile = new BufferedOutputStream(new FileOutputStream(filePath));
        xStream.toXML(loginDatabase, outFile); // This writes your state to the outputFile;
        outFile.close(); //close the writer
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

This is my process for writing on the login state xml file. I suspect it might be too long for a Shutdown Hook even if it were actually being called as I expect.

Any suggestions? I thought for a long time about possibly using simple variables to solve the problem but because I have the program set so that the user can be logged into multiple accounts, the use of variables is impossible.

Also, will the controller object contained in the scope of the shutdown hook be the same controller that is modified in the event queue scope?

The shutdown hook can be a solution here. For details see eg this answer: https://stackoverflow.com/a/2541618/2045440

[Off topic] However, if you're at risk that unexpected termination of your application can result in lost of important data, maybe it would be worth to consider the more persistent way of processing this data (autosaving, backup files etc).

I resolved the problem by checking the task manager of the operating system. It allowed me to see if the user the xml document said was logged in actually had a program open. If not then I knew there was a problem. This is a fix for my particular program but it might be a help for others as well.

The link to that thread is here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM