Run function on JFrame close - java

void terminate() {}
protected JFrame frame = new JFrame();
How can I get frame to run the terminate function when I press the close button?
Edit: I tried to run this, but for some reason it doesn't print test (however, the program closes). Does anyone have an idea what could be the problem?
frame.addWindowListener(new WindowAdapter() {
public void WindowClosing(WindowEvent e) {
System.out.println("test");
frame.dispose();
}
});

You can use addWindowListener:
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
// call terminate
}
});
See void windowClosing(WindowEvent e) and Class WindowAdapter too.

Not only do you have to add the window listener, you have to set the default close operation to do nothing on close. This allows your code to execute.
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent event) {
exitProcedure();
}
});
Finally, you have to call System exit to actually stop your program from running.
public void exitProcedure() {
frame.dispose();
System.exit(0);
}

Frame.dispose() method does not terminate the program. To terminate the program you need to call System.exit(0) method

If you want to terminate your program after the JFrame is closed, you have to set the default close operation on your JFrame.
In your constructor of your JFrame write:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
If you just want to call a method when the window is closed and not terminate the whole program, than go with the answer of Maroun.

Related

Confirm program quit when cmd + Q is pressed

I have a program with a JFrame that I use a WindowListener to close the program with. I use the following method to prompt a message about saving changes made in the program:
public void windowClosing(WindowEvent e) {
if (condition) {
System.exit(0);
}
However, when I press cmd + Q, my program will quit without me having the option of saving. Is there a smart way to make sure that I can have a condition before I close my program regardless if I close it through the window X or through my keyboard short commands? Or do I need to create a KeyEvent for this?
You need to change the DefaultCloseOperation on JFrame and then dispose() the frame on windowClosing event (or System.exit(0) like you show above). Here is a simple working example:
JFrame f = new JFrame();
f.setPreferredSize(new Dimension(300, 300));
f.pack();
f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
f.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent we) {
if (condition) {
f.dispose();
}
}
});
f.setVisible(true);
This way all closing operation will use your condition.
However, when I press cmd + Q,
I believe that is a keystroke you enter from the command line?
If so you might be able to use addShutDownHook(...) method found in the Runtime class.

How to perform a task before a window/frame is closed?

The JFrame provides a method setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) . I want to run some code before this Frame is actually closed. How do I do that ?
JFrame frame = new JFrame();
frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
// The window is closing
}
});
Implement WindowListener and capture window closing event. Something like-
yourWindow.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
// do something here
}
});
Do this
frame.addWindowsListener(new WindowAdapter() {
public void windowClosing() {
// do your work here
frame.dispose();
}
}
Please refer WindowListener documentation

How to capture a JFrame's close button click event?

I want to call a method confirmExit() when the red close button of the title bar of a JFrame is clicked.
How can I capture that event?
I'd also like to prevent the window from closing if the user chooses not to proceed.
import javax.swing.JOptionPane;
import javax.swing.JFrame;
/*Some piece of code*/
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
if (JOptionPane.showConfirmDialog(frame,
"Are you sure you want to close this window?", "Close Window?",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION){
System.exit(0);
}
}
});
If you also want to prevent the window from closing unless the user chooses 'Yes', you can add:
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
Override windowClosing Method.
public void windowClosing(WindowEvent e)
It is invoked when a window is in the process of being closed. The close operation can be overridden at this point.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
also works. First create a JFrame called frame, then add this code underneath.
This may work:
jdialog.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.out.println("jdialog window closed event received");
}
public void windowClosing(WindowEvent e) {
System.out.println("jdialog window closing event received");
}
});
Source: https://alvinalexander.com/java/jdialog-close-closing-event
This is what I put as a menu option where I made a button on a JFrame to display another JFrame. I wanted only the new frame to be visible, and not to destroy the one behind it. I initially hid the first JFrame, while the new one became visible. Upon closing of the new JFrame, I disposed of it followed by an action of making the old one visible again.
Note: The following code expands off of Ravinda's answer and ng is a JButton:
ng.addActionListener((ActionEvent e) -> {
setVisible(false);
JFrame j = new JFrame("NAME");
j.setVisible(true);
j.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
setVisible(true);
}
});
});
Try this:
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
It will work.

wait for jdialog to close

I have a class FilePathDialog which extends JDialog and that class is being called from some class X. Here is a method in class X
projectDialog = new FilePathDialog();
projectDialog.setVisible(true);
projectDialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("Window closing");
try {
doWork();
} catch (Throwable t) {
t.printStackTrace();
}
}
public void windowClosed(WindowEvent e) {
System.out.println("Window closed");
try {
doWork();
} catch (Throwable t) {
t.printStackTrace();
}
}
});
doWork never gets called when the JDialog window closes. All I'm trying to do is wait for the JDialog to close before it proceeds in the method. I also tried using SwingWorker and Runnable but that did not help.
Again, the key is is the dialog modal or not?
If it's modal, then there's no need for a WindowListener as you will know that the dialog has been dealt with since code will resume immediately below your call to setVisible(true) on the dialog. i.e., this should work:
projectDialog = new FilePathDialog();
projectDialog.setVisible(true);
doWork(); // will not be called until the dialog is no longer visible
If on the other hand it's mode-less, then a WindowListener should work, and you've likely got another problem in code not shown here, and you'll want to post an sscce for us to analyze, run, and modify.
Edit for gpeche
Please check out this SSCCE that shows that the 3 types of default closing parameters will trigger the window listener:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DialogClosing {
private static void createAndShowGui() {
JFrame frame = new JFrame("DialogClosing");
JPanel mainPanel = new JPanel();
mainPanel.add(new JButton(new MyAction(frame, JDialog.DISPOSE_ON_CLOSE, "DISPOSE_ON_CLOSE")));
mainPanel.add(new JButton(new MyAction(frame, JDialog.HIDE_ON_CLOSE, "HIDE_ON_CLOSE")));
mainPanel.add(new JButton(new MyAction(frame, JDialog.DO_NOTHING_ON_CLOSE, "DO_NOTHING_ON_CLOSE")));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyAction extends AbstractAction {
private JDialog dialog;
private String title;
public MyAction(JFrame frame, int defaultCloseOp, final String title) {
super(title);
dialog = new JDialog(frame, title, false);
dialog.setDefaultCloseOperation(defaultCloseOp);
dialog.setPreferredSize(new Dimension(300, 200));
dialog.pack();
dialog.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
System.out.println(title + " window closed");
}
#Override
public void windowClosing(WindowEvent e) {
System.out.println(title + " window closing");
}
});
this.title = title;
}
#Override
public void actionPerformed(ActionEvent arg0) {
dialog.setVisible(true);
}
}
Javadoc for WindowListener.windowClosed():
Invoked when a window has been closed as the result of calling dispose on the window.
And for JDialog.setDefaultCloseOperation():
Sets the operation which will happen by default when the user initiates a "close" on this dialog. The possible choices are:
DO_NOTHING_ON_CLOSE - do not do anything - require the program to handle the operation in the windowClosing method of a registered WindowListener object.
HIDE_ON_CLOSE - automatically hide the dialog after invoking any registered WindowListener objects
DISPOSE_ON_CLOSE - automatically hide and dispose the dialog after invoking any registered WindowListener objects
The value is set to HIDE_ON_CLOSE by default.
That suggests that you should call projectDialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); after instantiating FilePathDialog.
answer to your question
add WindowListener to your JDialog (JDialog.DO_NOTHING_ON_CLOSE) , on windowClosing event to try to run your code, if ends with success then call dispose(), or setVisible(false)
I don't agreed with your idea, another workaround
create only one JDialog (JDialog.DO_NOTHING_ON_CLOSE) with WindowListener, and re-use that for another Action, final action will be always setVisible(false), if your code ends with success, then remove the child(s) from JDialog, your JDialog is prepared for another job

Java hide JFrame1 and JFrame2, when JFrame0 is deactivated?

is there a way to hide all the other JFrames of my application, when the user clicks out of the "mainFrame"?
I tried with this
public void windowActivated(WindowEvent we) {
frame1.setVisible(true);
frame.setVisible(true);
}
public void windowDeactivated(WindowEvent we) {
frame1.setVisible(false);
frame2.setVisible(false);
}`
but this doesn't work. All of my Windows start blinking. I cannot set JFrame2 unfocusable.
Is there any other way to do this?
Use non-modal dialogs instead and the problem is sorted by default.
import javax.swing.*;
class TestDialogMinimize {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
JFrame f = new JFrame("Has a Dialog");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(400,400);
JDialog d = new JDialog(f);
d.setSize(200,200);
f.setVisible(true);
d.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
The non-modal dialog suggestion in this answer is one way to go. See also this answer elsewhere.
If for some reason you need to continue using frames, you can minify them with
frame1.setState(Frame.ICONIFIED)
and raise them with
frame1.setState(Frame.NORMAL)
Handle these in a code block like:
frame0.addWindowStateListener(new WindowStateListener() {
#Override
public void windowStateChanged(WindowEvent e) {
// handle change
}
});
as described in this question's answers.
If you want to close all frames when the frame0 is closed, you can use:
frame0.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
to exit the program and close all frames when the frame0 is closed. If you are just hiding on close use a window listener. You can use frame1.setVisible(false) in your WindowListener.

Categories

Resources