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 e.g. 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).