How do you close a java application from the code?
You call System.exit:
System.exit(0);
I believe that by most standards, System.exit() is a not very OOP way of closing applications, I've always been told that the proper way is to return from main. This is somewhat a bit of a pain and requires a good design but I do believe its the "proper" way to exit
If you're terminating a Swing app, I would do an EXIT_ON_CLOSE
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
before System.exit(0). This is better since you can write a Window Listener to make some cleaning operations before actually leaving the app.
That window listener allows you to exit the app from the code:
public void windowClosing(WindowEvent e) {
displayMessage("WindowListener method called: windowClosing.");
//A pause so user can see the message before
//the window actually closes.
ActionListener task = new ActionListener() {
boolean alreadyDisposed = false;
public void actionPerformed(ActionEvent e) {
if (frame.isDisplayable()) {
alreadyDisposed = true;
frame.dispose();
}
}
};
Timer timer = new Timer(500, task); //fire every half second
timer.setInitialDelay(2000); //first delay 2 seconds
timer.setRepeats(false);
timer.start();
}
public void windowClosed(WindowEvent e) {
//This will only be seen on standard output.
displayMessage("WindowListener method called: windowClosed.");
}
If you're running an application, System.exit will work.
System.exit(int);
In an applet, however, you'll have to do something along the lines of applet.getAppletContext().showDocument("landingpage.html"); because of browser permissions. It won't just let you close the browser window.
You use System.exit(int), where a value of 0 means the application closed successfully and any other value typically means something was wrong. Usually you just see a return value of 1 along with a message printed to sysout or syserr if the application did not close successfully.
Everything is fine, application shut down correctly:
System.exit(0)
Something went wrong, application did not shut down correctly:
System.err.println("some meaningful message"); System.exit(1)
Related
Currently I have a live active while loop running and it does what I want my only problem is closing the frame (exit the app) while the while loop is still active.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
I tried using the if statement to terminate the loop
if (frame.getDefaultCloseOperation() == 3){
running = false;
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
Unfortunately as soon as the app runs automatically gets set to 3 emmidiately and there for this process does not work.
How can I set running = false; by clicking on the frame to be closed.
I want to simply close the app by just clicking on X in the connour, is that possible when having a active loop running?
There are several ways to achieve what you want.
Run the loop in a daemon thread. Such a thread won't stop the application from stopping. Just be careful when you call swing code from such a thread.
This question explains how to show a confirm dialog when the user tries to close the window: Java - Message when closing JFrame Window
Instead of the dialog, just put running = false; in there.
Note: If you run your loop in the Swing thread, then Swing can't respond to the event. Use solution #1 in this case.
just set frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); in your declaration it will close the loop automatically
You are setting the default close operation.
however in your code this
if (frame.getDefaultCloseOperation() == 3){
only checks if the close operation is still set to JFrame.EXIT_ON_CLOSE
what you want is to respond to the close event.
I suspect you need this answer
when you set up your frame, add some code to the initialization block
addWindowListener(this);
and then implement the onclosing window listener int he same class:
public void windowClosing(WindowEvent event) {
running = false;
}
remove frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);, add windows listener and close application manually.
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
running = false;
}
#Override
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
There is a java swing application that I need to automate one of the functions of. It's quite simple - the user clicks a button in the swing application and starts an action.
I made a small java application that includes the java swing application as a .jar and calls the action behind the button (read).
The problem is - in case of an exception, the swing .jar shows JOptionPane, which halts the automated execution. Is it possible to somehow override this behavior without altering the original jar?
Application structure:
Main.java
import com.swingapp.ui
public static void main(String[] args){
Swingapp.read();
}
Then the read() function in the Swingapp library:
public void read(){
try{
//do a bunch of stuff...
} catch (Exception ex){
JOptionPane.showMessageDialog(null, ex.getMessage()); // In case of an exception, the swing application will show a message dialog. This halts the automated execution of my java task, I'd like to just skip this
}
When exception happens in above application, user is expected to click "OK". But running this as automated task, nobody there to click okay
Since a JOptionPane gains focus as soon as it opens (I think the most right button gets the focus, but it does not matter in your case) you can do the following:
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent arg0) {
Component c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
while(c != null) {
if (c instanceof JOptionPane) {
try {
new Robot().keyPress(KeyEvent.VK_ENTER);
} catch (AWTException e) {
e.printStackTrace();
break;
}
}
c = c.getParent();
}
}
}, AWTEvent.FOCUS_EVENT_MASK);
It will traverse up to see if anything in the current hierarchy is an instance of JOptionPane. If so -> simulate that the user pressed Enter (Return) which will close the dialog even if the focus is in an input field.
I have following solution for you. You need to registrate a listener to monitor all window events. Use Toolkit.getDefaultToolkit().addAWTEventListener(). If you get a window opened event, try to check whether the window is a JDialog and whether the dialog's contentPane contains an instance of JOptionPane. If yes you need traverse the component tree, find the first button and click it.
I'm creating an application in which I test a certain number of interface features, and when an error occurs I would like an error message to show.
Then the application should take a screenshot of the entire screen, and finally the error message closes without any help from the user.
To this end, I tried to use JDialog as below:
JOptionPane pane = new JOptionPane("Error message", JOptionPane.INFORMATION_MESSAGE);
JDialog dialog = pane.createDialog("Error");
dialog.addWindowListener(null);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
Application.takeScreenshot();
dialog.setVisible(false);
I was wondering if there is a specific method to close it. I looked up the documentation and I can't seem to find it. I tried to find a relevant question on SO, but couldn't find one that addresses my problem.
I wonder if there is a way to get the window handle, and then close it using that, or simply send a "CLOSE" or "Press_ok" event to the window?
Edit: It seems to me as if the code entirely stops running when the messagebox shows, as if there was a Thread.sleep() until window is closed manually by the user.
If possible, a code sample would be helpful.
Thanks
Try to use ScheduledExecutorService. Something like:
JDialog dialog = pane.createDialog("Error");
dialog.addWindowListener(null);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
ScheduledExecutorService sch = Executors.newSingleThreadScheduledExecutor();
sch.schedule(new Runnable() {
public void run() {
dialog.setVisible(false);
dialog.dispose();
}
}, 10, TimeUnit.SECONDS);
dialog.setVisible(true);
[EDIT]
Regards to camickr comment, the documentation does not mention that a ScheduledExedcutorService executes on the Event Dispatch Thread. So better to use swing.Timer
JDialog dialog = pane.createDialog("Error");
dialog.addWindowListener(null);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
Timer timer = new Timer(10000, new ActionListener() { // 10 sec
public void actionPerformed(ActionEvent e) {
dialog.setVisible(false);
dialog.dispose();
}
});
timer.start();
dialog.setVisible(true);
I've managed to fix it. It seems that by default, JDialog is Modal, meaning that it interrupts everything else until it's closed by the user. To fix this, I used the method:
dialog.setModalityType(Dialog.ModalityType.MODELESS);
When this is active, a simple .setVisible(false); is enough.
Anyways thanks for the help sorry for creating an unecessary question but I had been at it for hours until i found it. Hope it can help others.
I currently have a simple problem with LWJGL right now. If I were to run my game, it does actually run everything correctly and it appears to close out correctly, but when I look inside my Task Manager, I notice that my game is taking up 25% CPU after I close it (about 2-3% when it's actually running) and I'm thinking that I may have missed something when ending the application.
My main function code:
public static void main(String[] args){
try {
init();
}catch(LWJGLException e){
System.out.println("LWJGLException\n");
e.printStackTrace();
}
try{
gameLoop();
}catch(Exception ex){
ex.printStackTrace();
}finally{
cleanup();
}
}
cleanup:
public static void cleanup(){
System.out.println("Running cleanup code.");
Display.destroy();
System.exit(0);
}
It does actually manage to read "Running cleanup code." My problem is that I don't know if there is something else I need to do to clear out all of the processes. This game is also using a single thread.
There is nothing wrong with your code at all, I think. If your problem is what I think it is you wouldn't be able to immediately fix it.
Here are some basic questions you should ask your self. What OS are you using? What is your Java version and/or LWJGL version? (Updating them might help) Have you ever heard of/or played a game called Minecraft? If you are using Linux and seen this when closing Minecraft then that could be the problem you're having.
I have had the same problem on 64-bit windows. App haven't closed when Runtime Exception (or any other uncaught exception) occured. Probably reason was throwing an exception in an independent thread which effected in closing display window, but all other threads were still working. I came up with brute force solution: overriding Thread method.
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException (Thread thread, final Throwable ex) {
ex.printStackTrace();
Display.destroy();
System.exit(0);
}});
new LwjglApplication(new StartScreen(application), cfg);
I developed one swing application but each time you run application new window is opened.
I want that if one window is already opened other not allow to open.
Here is an example of a Java Single Application Instance:
A single instance application is one that only allows for 1 of the application to run no matter how many times the user tries to launch.
See also: A shorter example that does not notify the running instance.
The application tries to open a Socket on a specific port. In case another instance of your application is already running, opening the Socket fails.
This should already be sufficient for you, so you would not have to use the part of the code used to register new applications to the first one started.
Using a Socket has one great advantage compared to writing some sort of flag to the filesystem/registry/whatever:
It is removed even if your application crashes.
It actually sounds like you only want one application open at a time. In which case why not take out a file lock or similar when the application runs, and check that on start up. The headache (of course) is clearing up that lock in the event that your program doesn't exit cleanly.
My preferred solution is, as Peter Lang linked to, to use Sockets. When your app starts you can start a server socket listening for incoming connections on localhost (plus port of your choice). Before this happens in your code though you can try and make a connection to the server socket and if it is successful you know there is another instance already open, so you can quit the current instance with an appropriate message.
In your server socket implementation you can also add functionality that on receiving an incoming connection you actually force the current instance of the app to the foreground.
Do you mean run the GUI like a Singleton?, I have done this in the past by making a Static private "view manager" such that it is null and not created or visible until the first time the gui is created, after that just as with a classic singleton, the GUI is set to visible when the app is run again... I have a couple of Frameworks that follow this design--In these frameworks the GUI is not "primary" there are also command line and the like interfaces so the GUI is summoned via the command line...
public class Samp {
JFrame f=new JFrame();
File ff=new File("D:\\a.txt");
FileWriter fw;
public Samp() {
f.setBounds(0, 0, 200, 200);
try {
Scanner sc=new Scanner(ff);
if(!sc.hasNext()) {
fw=new FileWriter(ff);
fw.write("Running");
fw.close();
} else {
System.exit(0);
}
} catch(Exception e) {
System.out.println(e.getMessage());
}
WindowListener wndCloser = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
Scanner sc = new Scanner(ff);
if(sc.hasNext()) {
fw=new FileWriter(ff);
fw.write("");
fw.close();
}
} catch (Exception ex) { }
}
};
f.setVisible(true);
f.addWindowListener(wndCloser);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String args[]) {
new Samp();
}
}
Use Singletone Pattern as shown in the example!