Java - how do I prevent WindowClosing from actually closing the window - java

I seem to have the reverse problem to most people. I have the following pretty standard code to see if the user wants to do some saves before closing the window:
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent ev) {
boolean close = true;
// check some files, asking if the user wants to save
// YES and NO handle OK, but if the user hits Cancel on any file,
// I want to abort the close process
// So if any of them hit Cancel, I set "close" to false
if (close) {
frame.dispose();
System.exit(0);
}
}
});
No matter what I try, the window always closes when I come out of windowClosing. Changing WindowAdapter to WindowListener doesn't make any difference. What is weird is that the documentation explicitly says "If the program does not explicitly hide or dispose the window while processing this event, the window close operation will be cancelled," but it doesn't work that way for me. Is there some other way of handling the x on the frame? TIA

I've just tried this minimal test case:
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class Test {
public static void main(String[] args) {
final JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent ev) {
//frame.dispose();
}
});
frame.setVisible(true);
}
}
If I keep the dispose call commented, and hit the close button, the window doesn't exit. Uncomment that and hit the close button, window closes.
I'd have to guess that something is wrong in your logic to set your "close" variable. Try double checking that.

This is the key, methinks: frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); Makes the difference in the test case I cooked up.

not sure where is your problem,
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ClosingFrame extends JFrame {
private JMenuBar MenuBar = new JMenuBar();
private JFrame frame = new JFrame();
private static final long serialVersionUID = 1L;
private JMenu File = new JMenu("File");
private JMenuItem Exit = new JMenuItem("Exit");
public ClosingFrame() {
File.add(Exit);
MenuBar.add(File);
Exit.addActionListener(new ExitListener());
WindowListener exitListener = new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
int confirm = JOptionPane.showOptionDialog(frame,
"Are You Sure to Close this Application?",
"Exit Confirmation", JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null, null, null);
if (confirm == JOptionPane.YES_OPTION) {
System.exit(1);
}
}
};
frame.addWindowListener(exitListener);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setJMenuBar(MenuBar);
frame.setPreferredSize(new Dimension(400, 300));
frame.setLocation(100, 100);
frame.pack();
frame.setVisible(true);
}
private class ExitListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
int confirm = JOptionPane.showOptionDialog(frame,
"Are You Sure to Close this Application?",
"Exit Confirmation", JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null, null, null);
if (confirm == JOptionPane.YES_OPTION) {
System.exit(1);
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ClosingFrame cf = new ClosingFrame();
}
});
}
}

For the handling of this thing do:
if the user selects yes then use setDefaultCloseOperation(DISPOSE_ON_CLOSE); within the curly braces of that if else
if a cancel is selected then use setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
Consider example:
int safe = JOptionPane.showConfirmDialog(null, "titleDetails!", "title!!", JOptionPane.YES_NO_CANCEL_OPTION);
if(safe == JOptionPane.YES_OPTION){
setDefaultCloseOperation(DISPOSE_ON_CLOSE);//yes
} else if (safe == JOptionPane.CANCEL_OPTION) {
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);//cancel
} else {
setDefaultCloseOperation(DISPOSE_ON_CLOSE);//no
}

To solve the same problem I tried the very first answer of this article.
As separate application it works, but not in my case.
Maybe difference is in JFrame(in answer) and FrameView (my case).
public class MyApp extends SingleFrameApplication { // application class of my project
...
protected static MyView mainForm; // main form of application
...
}
public class MyView extends FrameView {
...
//Adding this listener solves the problem.
MyApp.getInstance().addExitListener(new ExitListener() {
#Override
public boolean canExit(EventObject event) {
boolean res = false;
int reply = JOptionPane.showConfirmDialog(null,
"Are You sure?", "", JOptionPane.YES_NO_OPTION);
if (reply == JOptionPane.YES_OPTION) {
res = true;
}
return res;
}
#Override
public void willExit(EventObject event) {
}
});
...
}

Not sure where your problem is, but this works for me!
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
int res=JOptionPane.showConfirmDialog(null,
"Do you want to exit.?");
if(res==JOptionPane.YES_OPTION){
Cal.this.dispose();
}
}
});

setDefaultCloseOperation() method helps in the problem .https://chortle.ccsu.edu/java5/Notes/chap56/ch56_9.html
view this link

Related

How to prevent that closing a JDialog closes the entire application

I have a main(screen) gui window and need to open a few "multi input" windows (jdialog or when not possible jframe), for example to add preferences (4 textfields with 2 filechoosers and 2 radiobuttons).
When pressing OK/Cancel in these JDialogs (or JFrames), my entire application closes.
I don't want that. How can I prevent that?
First try: I tried the intelliJ option "New -> Create Dialog class", which gives me a JDialog with OK/Cancel button. Pressing one of the buttons closes the JDialog and my entire application.
Second try: I wrote a class "by hand" which creates a JDialog (and also tried JFrame). Again: Pressing one of the buttons closes the JDialog and my entire application.
I removed "dispose()" and "setVisible(false)" options from theJDialog (JFrame), but still my entire application is closed.
main class method
public class mainScreen {
// Menu action listener (only relevant options)
class MenuActionListener implements ActionListener {
// menuListener
public void actionPerformed(ActionEvent ev) {
//myVariables myVars = new myVariables();
String[] dummy = null;
System.out.println("Selected: " + ev.getActionCommand());
switch(ev.getActionCommand()) {
case "Preferences":
showPreferencesDialog();
case "Exit":
System.exit(0);
break;
}
// method that opens the external class (see below in following code block)
private void showPreferencesDialog() {
prefJDialog myprefs = new prefJDialog(prefsPanel);
myprefs.showDialog();
boolean okPressed = myprefs.isOkPressed();
if (okPressed) {
JOptionPane.showMessageDialog(mainScreen.this.rootPanel,"OK pressed","About jExifToolGUI",JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(mainScreen.this.rootPanel,"Cancel pressed","About jExifToolGUI",JOptionPane.INFORMATION_MESSAGE);
}
}
// This is the class which is mention in the manifest
public mainScreen(JFrame frame) {
boolean preferences = false;
Preferences prefs = Preferences.userRoot();
createmyMenuBar(frame);
groupRadiobuttonsandListen();
fileNamesTableListener();
try {
myUtils.DisplayLogo(mainScreen.this.iconLabel);
} catch(IOException ex) {
System.out.println("Error reading Logo");
}
preferences = check_preferences();
if (!preferences) {
myUtils.checkExifTool(mainScreen.this.rootPanel);
}
programButtonListeners();
}
// main method in my main class for my project
public static void main(String[] args) {
JFrame frame = new JFrame("jExifToolGUI");
frame.setContentPane(new mainScreen(frame).rootPanel);
//frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
The JDialog class/method that is called from the main class
package org.hvdw.jexiftoolgui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class prefJDialog extends JDialog {
private JButton okButton;
private JButton cancelButton;
private JPanel prefsPanel;
private boolean okPressed;
public prefJDialog(JPanel prefsPanel) {
super(JOptionPane.getFrameForComponent(prefsPanel), true);
this.prefsPanel = prefsPanel;
setTitle("Preferences");
initDialog();
}
public void showDialog() {
setSize(800, 768);
double x = getParent().getBounds().getCenterX();
double y = getParent().getBounds().getCenterY();
setLocation((int) x - getWidth() / 2, (int) y - getHeight() / 2);
setVisible(true);
}
private void initDialog() {
JPanel pane = new JPanel();
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));
add(pane);
pane.add(Box.createVerticalGlue());
FlowLayout l = new FlowLayout(FlowLayout.RIGHT);
JPanel buttonsPane = new JPanel(l);
okButton = new JButton("Save"); //$NON-NLS-1$
buttonsPane.add(okButton);
pane.getRootPane().setDefaultButton(okButton);
cancelButton = new JButton("CANCEL"); //$NON-NLS-1$
buttonsPane.add(cancelButton);
buttonsPane.setMaximumSize(new Dimension(Short.MAX_VALUE, (int) l.preferredLayoutSize(buttonsPane).getHeight()));
pane.add(buttonsPane);
addListeners();
}
private void addListeners() {
okButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//saveProperties();
setVisible(false);
okPressed = true;
//close();
// dispose();
}
});
cancelButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
//dispose();
//close();
okPressed = false;
}
});
}
public boolean isOkPressed() {
return okPressed;
}
/*public void close() {
WindowEvent winClosingEvent = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(winClosingEvent);
}*/
}
So how do I prevent that upon clicking OK or Cancel in the JDialog, the entire application closes. That needs to stay open until the user clicks the "window close" X in the top-right, or from the menu "File -> Exit"
I have searched Google for several days, but can't find a solution (and one same question without answer).
Edit:
After Patrick's answer I changed the close method to
public void close() {
this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
}
And removed the /* and */.
I also activated the close(); in the listeners again, but it doesn't make a difference. My main app is still closed.
switch(ev.getActionCommand()) {
case "Preferences":
showPreferencesDialog();
case "Exit":
System.exit(0);
break;
And the problem is that you don't have a break statement in your switch case so the code falls through to the "Exit" logic and does a System.exit(0)
This is why we need a proper "MCVE" with every question. When you post random pieces of code we can't see the entire logic flow.

JFrame closing on dialog

public static int clickOnExit() {
int dialogButton=JOptionPane.YES_NO_OPTION;
JOptionPane.showConfirmDialog(null, sharedConstants.exitMessage,"Confirm",dialogButton);
if(dialogButton == JOptionPane.YES_OPTION){return JFrame.EXIT_ON_CLOSE;}
else{return JFrame.DO_NOTHING_ON_CLOSE;}
}
for confirm(YES) it works, but i am not sure if cancel option is solved properly. i just want to cancel JOptionPane and keep frame opened.
You need to do three things:
Set your main application frame to do nothing on close.
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
Register a WindowListener that listens to the windowClosing event.
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
maybeExit(); // Will not return if user clicks yes.
super.windowClosing(e);
}
});
Write code to conditionally call System.exit if the user confirms they wish to exit the application.
private void maybeExit() {
int yesNo = JOptionPane.showConfirmDialog(this, "Are you sure you wish to exit?", "Confirm", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (yesNo == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
Some suggestions were useful. I solved it in this way:
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
if (HandlingDialogBox.clickOnExit(frame) == 0) {
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
} else {
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
}
}
});
}
AND
public static int clickOnExit(final JFrame frame) {
return JOptionPane.showConfirmDialog(frame,sharedConstants.exitMessage,"Confirm",
JOptionPane.YES_NO_OPTION);
}
Sorry for bit messy parenthesis use, will clean that up later ...

Some problems to inconify a JFrame window when the user click on the X button in this specific case, some ideas?

I have the following problem: I am working on a Java Swing application that show me a JFrame. What I have to do is that when the user click on the X button the window have to be iconified and not close (it is a requirement requested by the client)
My architecture is pretty complicated and it work in this way:
I have a class named GUI that is something like this:
public class GUI extends SingleFrameApplication implements PropertyChangeListener {
private MainFrame mainFrame = null;
#Override
public void propertyChange(PropertyChangeEvent arg0) {
showMainFrame();
}
private void showMainFrame() {
mainFrame = new MainFrame(settings, tasksSettings, logAppender);
// I add a PropertyChangeListener to the created MainFrame object:
mainFrame.addPropertyChangeListener(this);
//mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
mainFrame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
logger.info("Minimize the MainFrameWindows instead close it");
((MainFrame)e.getSource()).setState(MainFrame.ICONIFIED);
logger.info("EVENTO ICONIZZAZIONE: " + e.getSource().toString());
}
});
WindowListener exitListener = new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.out.println("GUI SingleFrameApplication --> windowClosing");
mainFrame.OnWindowClose();
shutdown();
// mainFrame.setVisible(false);
/*int confirm = JOptionPane.showOptionDialog(frame,
"Are You Sure to Close this Application?",
"Exit Confirmation", JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null, null, null);
if (confirm == JOptionPane.YES_OPTION) {
System.exit(1);
}*/
}
};
mainFrame.addWindowListener(exitListener);
mainFrame.setVisible(true);
}
#Override
protected void shutdown() {
System.out.println("Entered into GUI ---> shutdown()");
logger.debug("Termino l'applicazione.");
ulogger.info(com.techub.crystalice.utils.Constants.APP_TITLE + "|Arresto " + com.techub.crystalice.utils.Constants.APP_TITLE);
// FileUtils.saveGeneralLogFile(logAppender.getLogInFile());
logAppender.saveGeneralLogFile();
EventBusService.unsubscribe(this);
if (mainFrame != null)
mainFrame.setVisible(false);
}
}
So in the previous code I have declared the showMainFrame() method and in this method I add a window listener that have to iconize my MainFrame JFrame, in this way
mainFrame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
logger.info("Minimize the MainFrameWindows instead close it");
((MainFrame)e.getSource()).setState(MainFrame.ICONIFIED);
logger.info("EVENTO ICONIZZAZIONE: " + e.getSource().toString());
}
});
Then I have my MainFrame windows that extends a classic JFrame, something like this:
public class MainFrame extends JFrame {
private final ConfigHelper settings;
private final TasksSettings tasksSettings;
public MainFrame(ConfigHelper settings, TasksSettings tasksSettings, LogAppender logAppender) {
super();
this.settings = settings;
this.tasksSettings = tasksSettings;
.......................................................
.......................................................
.......................................................
DO SOME STUFF
.......................................................
.......................................................
.......................................................
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
The problem is that when I click on the X button of my MainFrane window it will be close and not iconified.
Can you help me to solve this situation and in such a way that the MainFrame window is iconified and not closed?
I think that the problem is that at the end of execution it execute the shutDown() method that execute this operation:
if (mainFrame != null)
mainFrame.setVisible(false);
so the windows is not iconified but closed\made it invisible
Some idea?
Tnx
Andrea
If I have understood correctly, you need to show an icon for the app in system tray when you hit the X button, is it true?
In this case, you have enough with the default behavior for close event (the default is hide on close, as stated in documentation).
http://docs.oracle.com/javase/tutorial/uiswing/components/frame.html
In order to manage a system tray icon, you have some hints here:
http://docs.oracle.com/javase/tutorial/uiswing/misc/systemtray.html
In the system tray, you would have the necessary code to hide or show the main window (I don't know, but maybe you don't even need a window listener at all in your JFrame)

How to stop closing JFrame form?

I want to Stop accidentally closings in my project. I'm using JFrame Form as Home page. When I click Home window's close button I put Exit cord in Yes Option. I want to stop closing when I click No Option. Is there any way. Here is my cord. I'm using netbeans 7.3
private void formWindowClosing(java.awt.event.WindowEvent evt) {
int i= JOptionPane.showConfirmDialog(null, "Are you sure to exit?");
if (i == JOptionPane.YES_OPTION) {
System.exit(0);
} else{
new Home().setVisible(true);
}
}
How about
class MyGUI extends JFrame {
public MyGUI() {
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);// <- don't close window
// when [X] is pressed
final MyGUI gui = this;
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
int i = JOptionPane.showConfirmDialog(gui,
"Are you sure to exit?", "Closing dialog",
JOptionPane.YES_NO_OPTION);
if (i == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
});
setSize(200, 200);
setVisible(true);
}
//demo
public static void main(String[] args) {
new MyGUI();
}
}
You can simply do that like this
Integer opt = JOptionPane.showConfirmDialog(null, "This application cannot continue without login to the database\n Are you sure you need to exit...?", "Application X", JOptionPane.YES_NO_OPTION);
if(opt== JOptionPane.NO_OPTION){
this.setVisible(true);
}else{
System.exit(0);
}

Java: How to cancel application exit

On one of my programs, I want a Dialog to appear when the user attempts to exit the application. The user must then choose to save some state of the program, not to save or to cancel the exit operation.
I wrote this in an attempt to find a solution first and ony then implement it:
import javax.swing.*;
import java.awt.Dimension;
import java.awt.event.*;
class WL implements WindowListener
{
private boolean statussaved;
private JFrame tframe;
WL (JFrame frame)
{
statussaved = false;
tframe = frame;
}
#Override public void windowActivated (WindowEvent w) { }
#Override public void windowClosed (WindowEvent w) { }
#Override public void windowDeactivated (WindowEvent w) { }
#Override public void windowDeiconified (WindowEvent w) { }
#Override public void windowIconified (WindowEvent w) { }
#Override public void windowOpened (WindowEvent w) { }
#Override public void windowClosing (WindowEvent w)
{
if (statussaved)
{
return;
}
final JDialog diag = new JDialog (tframe, "Save Progress", true);
diag.setPreferredSize (new Dimension (500, 100));
diag.setResizable (false);
diag.setDefaultCloseOperation (JDialog.DISPOSE_ON_CLOSE);
JPanel notifypanel = new JPanel ();
notifypanel.add (new JLabel ("Do you want to save the current status ?"));
JButton yesbutton = new JButton ("Yes");
JButton nobutton = new JButton ("No");
JButton cancelbutton = new JButton ("Cancel");
yesbutton.addActionListener (new ActionListener ()
{
#Override public void actionPerformed (ActionEvent a)
{
//SAVE THE STATUS
System.out.println ("Saving status...");
statussaved = true;
diag.dispose ();
tframe.dispose ();
}
});
nobutton.addActionListener (new ActionListener ()
{
#Override public void actionPerformed (ActionEvent a)
{
//just exit/close the application
diag.dispose ();
tframe.dispose ();
}
});
cancelbutton.addActionListener (new ActionListener ()
{
#Override public void actionPerformed (ActionEvent a)
{
//DON'T EXIT !!!
diag.dispose ();
}
});
notifypanel.add (yesbutton);
notifypanel.add (nobutton);
notifypanel.add (cancelbutton);
diag.setContentPane (notifypanel);
diag.pack ();
diag.setVisible (true);
}
}
public class SaveTest
{
public static void main (String[] args)
{
SwingUtilities.invokeLater (new Runnable ()
{
#Override public void run ()
{
JFrame frame = new JFrame ("Save Test");
frame.setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener (new WL (frame));
JLabel lab = new JLabel ("just some information");
frame.setPreferredSize (new Dimension (400, 300));
frame.setResizable (false);
frame.add (lab);
frame.pack ();
frame.setVisible (true);
}
});
}
}
It compiles and runs without any change, so you can test it.
The "Yes" and "No" choices work as expected, but I have absolutely no idea what to write in the ActionListener of the "Cancel" button. What I want is, when the user clicks the "Cancel" button, the dialog dissapears, but the main window remains visible (i.e. the program keeps running).
Now, since all this is implemented in the windowClosing method, it's kind of clear that some sort of dispose signal was sent in order to destroy the JFrame. This means that there is probably no way this can be done in the current design. I don't mind reorganizing/redesigning all this to make it work. It's just... I don't know how.
Any ideas ?
Replace
mainframe.setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE);
with
mainframe.setDefaultCloseOperation (JFrame.DO_NOTHING_ON_CLOSE);
If user cancels closing - do nothing. If agrees - call dispose() manually.
Have a look at JOptionPane, which handles most of this stuff for you, e.g.
JOptionPane.showConfirmDialog(frame, "please choose one",
"information",
OptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.INFORMATION_MESSAGE);
Your DefaultCloseOperation needs to be DO_NOTHING_ON_CLOSE so that your dialog can handle things - otherwise the window will get disposed before the user can cancel it. Then you manually close the window or exit the application or whatever according to the user's choice.

Categories

Resources