I am seeing the following code in a Swing demo application:
WindowListener wndCloser = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
addWindowListener(wndCloser);
Why would you use this code to close the application? What would happen without it, and/or are there other (shorter) options to do this?
Why would you use this code to close the application?
As TimH said, you can log information, write out properties, or do any other clean up you want to do before exiting your Swing application.
Here's how the window closing code is normally used.
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
WindowListener wndCloser = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
exitProcedure();
}
};
frame.addWindowListener(wndCloser);
public void exitProcedure() {
frame.dispose();
System.exit(0);
}
Because exitProcedure is a separate method, you can execute it from a JMenuItem action listener, like "Exit".
What would happen without it, and/or are there other (shorter) options to do this?
A shorter option is
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
If you don't specify any default close operation, your Swing application continues to run after you close the JFrame. You wind up with dozens of running applications, doing nothing.
You can use it to log some infos like this:
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
log.info("Programm exit.");
System.exit(0);
super.windowClosed(e);
}
});
A shorter version would be:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Related
Here is a piece of code that I wrote but the close button on the top of the application doesn't work please help
Code:
import java.awt.*;
import java.awt.event.*;
public class App extends Frame implements MouseMotionListener {
App() {
addMouseMotionListener(this);
setSize(200, 200);
setVisible(true);
}
public void mouseDragged(MouseEvent e) {
Graphics g = getGraphics();
g.setColor(Color.RED);
g.fillRect(e.getX(), e.getY(),10, 10);
}
public void mouseMoved(MouseEvent e) {
}
public static void main(String[] args)throws Exception {
App a = new App();
}
}
Image:
You need to add Listener and call dispose while initializing your applet.
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
You need to add above line of code inside the constructor.
Try it with that little code:
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
System.exit(0);
}
});
You have to insert it in "App()". It will close the program "System.exit(0);"
when you press the close button.
im not using AWT often but heres my Solution :)
addWindowListener(new WindowAdapter(){
#Override
public void windowClosing(WindowEvent we){
System.exit(0);
}
});
Add a new WindowAdapter to your App Constructor and call system.exit(0) on the Window Close Event
You can use WindowContants on JFrame#setDefaultCloseOperation to achieve the desired action. This allows you to dispose the frame, entirely terminate the application and a few more with a single line in the constructor:
this.setDefaultCloseOperation(WindowContants.DISPOSE_ON_CLOSE);
will dispose the frame containing the app. This is sufficient to terminate the program you presented.
This approach doesn't allow handling any events though, but simply closes the frame.
I added a method to my network chat system to connect to another server at the same time as having another connection open. The way I set it up works, except it's not an independent instance of the system. When I close the main window, it closes all the other ones too. Is there any way I can open up a completely new instance of the login window?
Here's the code I am using:
public void actionPerformed(ActionEvent e) {
String[] input = null;
Login.main(input);
}
Solution with good practice provided by #HovercraftFullOfEels in comments.
To cover your use-case only:
You can maintain the list of created Windows(JFrame).
Don't exit on close instead dispose.
Remove the Windows from the list on closing.
If no window present in the list then exit the system.
here is some sudo code:
final List<JFrame> jframeList = new ArrayList<JFrame>();
JFrame jFrame = new JFrame();
jframeList.add(jFrame);
jFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jFrame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
JFrame jframe = (JFrame) e.getSource();
jframeList.remove(jframe);
if (jframeList.isEmpty()) {
System.exit(0);
}
}
});
Below is 2 simple java ui application, I found if the current IME is google pinyin When I click the right-upper close button of this Frame in Windows 7 and Windows XP OS, the frame can be closed but the EDT thread doesn't terminate.
the google pinyin IME download address is http://dl.google.com/pinyin/v2/GooglePinyinInstaller.exe.
And recently I found this situation also occurs when using Baidu Pinyin IME(another chinese input method). Diffrently, it occurs only when using swing, randomly(the EDT thread can't terminate for a period of time, and become normal later).
I've read a article blaming the same problem similar to me long ago, and the author didn't come out with a solution too. I thought this is a bug in Google IME.
I know most people view this question may not be Chinese and may be unable to install these 2 IME and try my samples, but it's just too ridiculous for me, how can these two things have relations??? do anybody have some idea to explain it based on your knowledge? I'll appreciate very much!
// AWT
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
final Frame frame = new Frame("test");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
frame.dispose();
}
});
frame.setSize(400, 400);
frame.setVisible(true);
}
});
Below is Swing
// Swing
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("swing");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}
});
As #MadProgrammer mentioned. I changed my code, using System.exit(0) in AWT and frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) in swing, the result is I can't close the frame, when I click the close button, nothing happens.
You should try using an exit listener, for example:
this.addWindowListener(new MyExitListener());
And the exit listener class:
public class MyExitListener extends WindowAdapter {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
This is what I usually do, and it always works.
Is it possible to disable JFrame close operation?
EDIT.
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(
new WindowAdapter() {
#Override
public void windowClosing(final WindowEvent e) {
}
});
And this code doesn't solve the problem.
EDIT
Is it possible to consume WindowClosing event?
I don't get how can I employ this code:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
to close the program with the x button.
You need the line
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Because the default behaviour for the JFrame when you press the X button is the equivalent to
frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
So almost all the times you'll need to add that line manually when creating your JFrame
I am currently referring to constants in WindowConstants like WindowConstants.EXIT_ON_CLOSE instead of the same constants declared directly in JFrame as the prior reflect better the intent.
If you don't have it, the JFrame will just be disposed. The frame will close, but the app will continue to run.
Calling setDefaultCloseOperation(EXIT_ON_CLOSE) does exactly this. It causes the application to exit when the application receives a close window event from the operating system. Pressing the close (X) button on your window causes the operating system to generate a close window event and send it to your Java application. The close window event is processed by the AWT event loop in your Java application which will exit the application in response to the event.
If you do not call this method the AWT event loop may not exit the application in response to the close window event but leave it running in the background.
I spent quite a bit of time spelunking through the internet for an elegant solution to this. As is usually the case, I found a lot of conflicting information.
I finally ended with:
Do not use EXIT_ON_CLOSE as this can leave resources behind;
Do use something like the following in the JFrame initialization:
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
The real discovery was how to actually dispatch a window message to the JFrame. As an example, as part of your JMenuItem for exiting the application, use the following, where the function getFrame() returns a reference to the JFrame:
public class AppMenuFileExit extends JMenuItem implements ActionListener
{
// do your normal menu item code here
#Override
public void actionPerformed(ActionEvent e)
{
WindowEvent we;
we = new WindowEvent((Window) App.getFrame(), WindowEvent.WINDOW_CLOSING);
App.getFrame().dispatchEvent(we);
}
}
JFrame is a subclass of Window so may be cast to Window for this purpose.
And, have the following in your JFrame class to handle Window messages:
public class AppFrame extends JFrame implements WindowListener
{
// Do all the things you need to for the class
#Override
public void windowOpened(WindowEvent e)
{}
#Override
public void windowClosing(WindowEvent e)
{/* can do cleanup here if necessary */}
#Override
public void windowClosed(WindowEvent e)
{
dispose();
System.exit(0);
}
#Override
public void windowActivated(WindowEvent e)
{}
#Override
public void windowDeactivated(WindowEvent e)
{}
#Override
public void windowDeiconified(WindowEvent e)
{}
#Override
public void windowIconified(WindowEvent e)
{}
}
If you're using a Frame (Class Extends Frame) you'll not get the
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
If you don't extend JFrame and use JFrame itself in variable, you can use:
frame.dispose();
System.exit(0);
The following code works for me:
System.exit(home.EXIT_ON_CLOSE);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this worked for me in case of Class Extends Frame