I would like to save the programs settings every time the user exits the program. So I need a way to call a function when the user quits the program. How do I do that?
I am using Java 1.5.
You can add a shutdown hook to your application by doing the following:
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
// what you want to do
}
}));
This is basically equivalent to having a try {} finally {} block around your entire program, and basically encompasses what's in the finally block.
Please note the caveats though!
Adding a shutdown hook addShutdownHook(java.lang.Thread) is probably what you look for. There are problems with that approach, though:
you will lose the changes if the program aborts in an uncontrolled way (i.e. if it is killed)
you will lose the changes if there are errors (permission denied, disk full, network errors)
So it might be better to save settings immediately (possibly in an extra thread, to avoid waiting times).
Are you creating a stand alone GUI app (i.e. Swing)?
If so, you should consider how you are providing options to your users how to exit the application.
Namely, if there is going to be a File menu, I would expect that there will be an "Exit" menu item.
Also, if the user closes the last window in the app, I would also expect it to exit the application.
In both cases, it should call code that handles saving the user's preferences.
Using Runtime.getRuntime().addShutdownHook() is certainly a way to do this - but if you are writing Swing applications, I strongly recommend that you take a look at JSR 296 (Swing Application Framework)
Here's a good article on the basics: http://java.sun.com/developer/technicalArticles/javase/swingappfr/.
The JSR reference implementation provides the kind of features that you are looking for at a higher level of abstraction than adding shutdown hooks.
Here is the reference implementation: https://appframework.dev.java.net/
Related
I'm fairly new to java and I was creating a program which would run indefinitely. Currently, the way I have the program set up is calling a certain method which would perform a task then call another method in the same class, this method would perform a task then call the initial method. This process would repeat indefinitely until I stop the compiler.
My problem is when I try to create a GUI to make my program more user friendly, once I press the initial start button this infinite loop will not allow me to perform any other actions -- including stopping the program.
There has to be another way to do this?
I apologize if this method is extremely sloppy, I sort of taught myself java from videos and looking at other programs and don't entirely understand it yet.
You'll need to run your task in a new thread, and have your GUI stuff in another thread.
Actually, if you keep working on this problem, you'll eventually invent event driven programming. Lots of GUI based software, like Android, use this paradigm.
There are several solutions. The first that comes to mind is that you could put whatever method needs to run forever in its own thread, and have a different thread listen for user input. This might introduce difficulties in getting the threads to interact with each other, but it would allow you to do this.
Alternatively, add a method that checks for user input and handles it inside the infinite loop of your program. something like below
while(true){
//do stuff
checkForUserInput();
//do other stuff
}
To solve this problem, you need to run your UI in another thread.
Many programs are based on an infinite loop (servers that keep waiting for a new user to connect for example) and your problem isn't there.
Managing the CPU time (or the core) allocated to your infinite loop and the one allocated to take care of your UI interactions is the job of the operating system, not yours : that's why your UI should run in a separate thread than your actual code.
Depending on the GUI library (Swing, ...) you're using there may be different ways to do it and the way to implement it is well answered on Stack Overflow
I have a client/server question that i am trying to figure out the best solution for.
If a client ever gets disconnected from the server, for any reason, i would like a way for the input output thread to alert the gui thread that something went wrong, and thus have the gui thread print an error and gracefully handle it (probably drop back out to the login gui). After the initial gui thread is created, the client could change to any number of guis, depending on what he is doing, so I am thinking i need a way to dynamically see what gui is currently being run.
The way that i was thinking of doing this so far:
1) Create an object that creates and shows every gui. So instead of calling invokeLater...SomeGui.CreateAndShoGui()... we would have this object be responsible for doing that, ie GuiObject.showSomeGui();
2) Have each gui implement an interface, which will insure there is a method that, when called, will gracefully shutdown this gui when we have lost connection to the server.
3) Have a thread that monitors the IO thread and the gui object. If something goes wrong on the IO thread, the IO thread will close down and notify the monitoring thread that we have lost connection the server. The monitoring thread could then alert any open guis (from the gui object) that we have lost connection and that it needs to shut down.
I have just started thinking about this, and so far this is the best solution i have come up with. Does this seem like a reasonable solution that wont add too much complexity to the code? Or can anyone recommend a solution that would be simpler for people reading the code to understand?
Thanks
EDIT:
The other option i am toying with is having an object on the IO thread, that also gets passed to each new gui as it is opened. This object will give the currently opened guis reference back to the io thread, so that the io thread can alert it if something goes wrong. I am leaning against this solution though, because it seems like it would be easier to read if you had one object that was dedicated to get this working (like the above solution), instead of passing some obscure object to each gui.
Let me just go through each of your ideas:
1) Bad idea - you are tying your whole application together through a single object. This makes maintainability difficult and is the antithesis of modularity.
2) This is the way to go IMHO. Since it seems that each gui has unique logic in a failure scenario then it stands to reason that the object that best understands what to do would be the gui object itself.
Another version of this idea would be to create an adapter for each gui to put this failure logic into. The advantage would be you have one less dependency between your application framework and your gui. The disadvantage is that this is an extra layer of complexity. If your gui is already pretty coupled to your application then I would choose the interface method. If you want to reuse your guis in another application then the adapter way could help facilitate that.
3) This complements #2 nicely. So let me get this straight - you would have 3 threads: the IO thread, the monitor thread, and the UI thread. I don't know if you need the monitor thread. From what you were saying the IO thread would be able to detect a connection problem by itself (probably because some form of IOException was caught). When a connection problem is discovered the IO thread is not busy since it is just going to shut itself down soon so it might as well just have the responsibility of notifying the guis that there was a problem. The guis should have their interface method called on the UI thread anyways so the IO thread is just calling a bunch of invokeLater() calls (or asyncExec() calls for SWT) and then the IO thread can just shut itself down.
4) (Your Edit) You are basically describing the Visitor pattern. I do not think this is a good solution because the call is from the IO thread to the gui and not the other way around. I am not sure how passing a visitor object around will help in this case.
One final thought. If you make your interface generic (not gui specific) then you can apply this pattern to other resources. For instance you may want to flush your user credentials when you lose connection (since you talked about going to the login screen again). That isn't really gui logic and should not be done from a gui class.
Edit: I would use an event model. Let's say you create a interface like this:
public interface ConnectionFailureListener {
void handleConnectionFailure(); // Add an event object if you need it
}
You could then have registration methods in some object (maybe the Runnable for the IO thread or somewhere else that is convenient for you). These methods would be pretty standard:
public void addConnectionFailureListener(ConnectionFailureListener l) {}
public void removeConnectionFailureListener(ConnectionFailureListener l) {}
When you show a gui on the screen you would add it to your registration object and when you close the gui you would remove it from the registration object. You can add other types of objects as needed - for example when you log in you can add a listener for your credential system and remove it again when log out is processed.
This way when you have a failure condition you simply loop through the currently registered listeners and the listener does its thing.
What's the best way to quit a Java application with code?
You can use System.exit() for this purpose.
According to oracle's Java 8 documentation:
public static void exit(int status)
Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination.
This method calls the exit method in class Runtime. This method never returns normally.
The call System.exit(n) is effectively equivalent to the call:
Runtime.getRuntime().exit(n)
System.exit(0);
The "0" lets whomever called your program know that everything went OK. If, however, you are quitting due to an error, you should System.exit(1);, or with another non-zero number corresponding to the specific error.
Also, as others have mentioned, clean up first! That involves closing files and other open resources.
System.exit(int i) is to be used, but I would include it inside a more generic shutdown() method, where you would include "cleanup" steps as well, closing socket connections, file descriptors, then exiting with System.exit(x).
System.exit() is usually not the best way, but it depends on your application.
The usual way of ending an application is by exiting the main() method. This does not work when there are other non-deamon threads running, as is usual for applications with a graphical user interface (AWT, Swing etc.). For these applications, you either find a way to end the GUI event loop (don't know if that is possible with the AWT or Swing), or invoke System.exit().
Using dispose(); is a very effective way for closing your programs.
I found that using System.exit(x) resets the interactions pane and supposing you need some of the information there it all disappears.
I agree with Jon, have your application react to something and call System.exit().
Be sure that:
you use the appropriate exit value. 0 is normal exit, anything else indicates there was an error
you close all input and output streams. Files, network connections, etc.
you log or print a reason for exiting especially if its because of an error
The answer is System.exit(), but not a good thing to do as this aborts the program. Any cleaning up, destroy that you intend to do will not happen.
There's two simple answers to the question.
This is the "Professional way":
//This just terminates the program.
System.exit(0);
This is a more clumsier way:
//This just terminates the program, just like System.exit(0).
return;
Runtime.getCurrentRumtime().halt(0);
System.exit() will do what you want. But in most situations, you probably want to exit a thread, and leave the main thread alive. By doing that, you can terminate a task, but also keep the ability to start another task without restarting the app.
System.exit(ABORT);
Quit's the process immediately.
This should do it in the correct way:
mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
mainFrame.addWindowListener(new WindowListener() {
#Override
public void windowClosing(WindowEvent e) {
if (doQuestion("Really want to exit?")) {
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.dispose();
}
}
Normally in a C or C++ program there's a main loop/function, usually int main (). Is there a similar function that I can use in android Java development?
As far as an Android program is concerned there is no main().
There is a UI loop that the OS runs that makes calls to methods you define or override in your program. These methods are likely called from/defined in onCreate(), onStart(), onResume(), onReStart(), onPause(), onStop(), or onDestroy(). All these methods may be overriden in your program.
The fundamental issue is that the OS is designed to run in a resource constrained environment. Your program needs to be prepared to be halted and even completely stopped whenever the OS needs more memory (this is a multitasking OS). In order to handle that your program needs to have some of all of the functions listed above.
The Activity lifecycle describes this best (your program is one or more Activities, think of an Activity as a screen).
Bottom line: Your program 'starts' at onCreate() through onResume() but the OS is running the loop. Your program provides callbacks to the OS to handle whatever the OS sends to it. If you put a long loop at any point in your program it will appear to freeze because the OS (specifically the UI thread) is unable to get a slice of time. Use a thread for long loops.
In Android environment, there is no main(). The OS relies on the manifest file to find out the entry point, an activity in most case, into your application.
You should read http://developer.android.com/guide/topics/fundamentals.html for more detail.
According to:
http://developer.android.com/guide/tutorials/hello-world.html
The application class must support a method for each activity that the Application
supports. In the general case, the onCreate is probably equivalent to the main/top
function for your needs.
Maybe it's possible by creating a timer and execute custom functions at every tick, reset the timer when it's at a specific time
The above answers provide a "why" as to there's no "main loop" on Android (which is important to understand). I'll offer a solution to the implied question, instead, as many visitors here will be looking for exactly that.
I believe the appropriate thing to do, here, would be to create an AsyncTask which operates as your "main loop". Or better yet, design your main loop to run as a java.util.concurrent future, which can be started and ended during lifecycle events (like rotation!), using signaling (keep your data separate). The AsyncTask API is deprecated, because it was complex, and handling it properly amounted to writing code that would, effectively, operate as an AsyncTask which cleaned up when the next problematic lifecycle event transpired.
Keep in mind that this will be a separate thread from the UI, and, as such, will be required to respond in short order to UI thread events, like "onPause" and "onDestroy". If your app does not respond within a certain period of time (~5 secs, iirc) to these events, or user input events, it will be killed by the OS. It's really prudent, for a real-time app, to be able to fully respond to these events in under 1 sec, even on the lowest-end device. You can use synchronization primitives to notify other threads that their response is pending, and they can use them to signal when they are finished (or simply end, in the case of a future).
I've been trying to learn about applets by studying the code for the "Welcome to HotJava" applet. I decompiled the *.class file using the Windows version of Jad, and I see the following lines of code
public void init() {
// Skip some lines...
addMouseListener(this);
}
public void destroy()
{
removeMouseListener(this);
}
Is the destroy method really necessary here? Why does the applet need to remove itself as a mouse listener if it's just about to end?
The destroy() method cleans up resources so they can be released. When the whole JVM will be shutting down, it's not as critical to release all resources before shutting down, but it's always a good idea to do The Right Thing even when it is not strictly necessary.
Depending on the threading model, if you leave yourself as a mouse listener, then you will still be notified if mouse events occur. If there are multiple Applets in the same JVM and only one Applet is ending, then you can leave threads in a funny state if you leave a listener to which no action will be taken. It's possible that you can lock up the other Applets by doing so.
EDIT:
By threads in a funny state, I mean (for example) if a listener whose Applet thread has stopped is queuing messages to a queue that no-one is reading from, then eventually the queue will fill up and the dispatch thread will block. (In more detail, let's assume the listener does nothing but queue the message and that there is a thread in the Applet -- now stopped -- that reads from this queue. Once the queue fills, it will block!)
With a mouse listener, specifically, you may well be safe, assuming when the Applet quits it is no longer visible and can no longer receive mouse events. With a different sort of listener, however, you could get into trouble. Always doing the right thing, even when it is not truly necessary, gets you in the habit so you don't forget to do the right thing when it's actually critical. :)
The destroy() is critical if you want to leave any "evidence" that your applet had ever run...
For example, you could send all your state information to a file or a server for subsequent use, or let the server know that you are disconnecting.
Imagine that you had a chat application...
Its useful in releasing resources that exist outside the context of the applet. Lets say you have acquired a resource from a foreign server side application, like a license. Or perhaps you need to notify some server side resource that the application has shutdown for statistics or some other reason.
Well, not in this particular case. However, it's good practise to remove mouse (and other) listeners in java - not doing so can result in unfortunate memory leaks.
And it's also good practise for your destroy() to clean up everything that init() does, even when it's unnecessary.