thanks
A common mistake is that the developer forgest to call..
JFrame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE)
..before adding the WindowListener with alternate close action.
Andrew T.
Well that prevents it from closing when the user chooses No when the
dialog appears but now it won't close at all even when they choose Yes.
I have to resort to File->Exit for it to close (that eventually calls
system.exit(0).
Previously I had JFrame.setDefaultCloseOperation(EXIT_ON_CLOSE) near the
end of my main() and I have my windowListener within a class that is
coded outside of main(). The windowListener is just using the
windowadapter as an anonymous class if that matters.
<sscce>
import java.awt.event.*;
import javax.swing.*;
public class CheckClose {
public static void main(String[] args) {
final JFrame f = new JFrame("Confirm Close");
final JLabel check = new JLabel("Really close?");
f.setDefaultCloseOperation(
JFrame.DO_NOTHING_ON_CLOSE );
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
if ( JOptionPane.YES_OPTION==
JOptionPane.showConfirmDialog(f,check) ) {
// do clean-up
System.exit(0);
}
}
public void windowClosed(WindowEvent we) {}
public void windowDeactivated(WindowEvent we) {}
public void windowOpened(WindowEvent we) {}
});
f.setSize(new java.awt.Dimension(300,40));
f.setVisible(true);
}
}</sscce>
Does this work as you expect it to?
What are you doing different?
Andrew T.
Well as I briefly mentioned last time, I define my class outside of main
and then create the instance inside of main. As you can see I do have a
componentListener on it but I guess I wasn't being consistent because my
anonymous windowListener was within my class definition.
public class LDAPMgr extends JFrame
implements ActionListener, ChangeListener {
/* global variables */
public LDAPMgr() {
super();
ldapEnv = new Hashtable<Object,Object>();
GridBagLayout framegridbag = new GridBagLayout();
GridBagConstraints framegbc = new GridBagConstraints();
setLayout(framegridbag);
setTitle(version);
/* create gui elements */
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
/*ask for confirmation before exiting */
int answer = JOptionPane.showConfirmDialog(null,
"Do you really want to quit?",
"Application Closing...",
JOptionPane.YES_NO_OPTION);
if (answer == 1)
return;
try {
ldapUtility.disconnect();
} catch (NullPointerException Ex) {
// if null connection just exit w/no error mesg
return;
} catch (Exception Ex) {
JOptionPane.showMessageDialog(null,
"Disconnection failed!\n" + Ex.getMessage(),
"Connection",JOptionPane.ERROR_MESSAGE);
}
System.exit(0);
}
}
);
/* misc. other methods defined */
}
}
public static void main(String[] args) {
final int MIN_WIDTH = 1003;
final int MIN_HEIGHT = 800;
LDAPMgr LDAP = new LDAPMgr();
LDAP.addComponentListener(
new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
int width = LDAP.getWidth();
int height = LDAP.getHeight();
boolean resize = false;
if (width < MIN_WIDTH) {
resize = true;
width = MIN_WIDTH;
}
if (height < MIN_HEIGHT) {
resize = true;
height = MIN_HEIGHT;
}
if (resize)
LDAP.setSize(new Dimension(width, height));
}
}
);
LDAP.setLocation(200,100);
LDAP.pack();
LDAP.setDefaultCloseOperation(EXIT_ON_CLOSE);
LDAP.setVisible(true);
}
There must be something wrong with this design somewhere so let me know
what you find. I already tried to put the windowListener in the same
place as the componentListener (within main()) but it didn't help and I
remembered to change the defaultCloseOperation before I did that. The
code above is what I currently have right now which doesn't work (it is
exiting on both Yes and No confirmation answers).
thanks
Brandon
That would be a problem...
Andrew T.
If I remove that line and do nothing else it still closes if I choose No
for the confirmation dialog. If I put
setDefaultCloseOperation(EXIT_ON_CLOSE); as the first line in the
windowAdapter method then the app doesn't close at all whether I choose
yes or no for the confirmation dialog.
Brandon
It closes, but it does not exit. Check with a process watcher to see if
you have Java processes still running (but invisible). The default
action is to simply close the window, not exit the JVM. So, what you
want to do is not remove the:
LDAP.setDefaultCloseOperation(EXIT_ON_CLOSE);
but change it to:
LDAP.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
as explained already by Andrew.
Note that changing this property of the window while it is already in a
closing state is not going to have the desired effect. Simply code the
necessary actions into your listener, as illustrated below.
e.g.
in the constructor:
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
boolean reallyClose = . . . // ask your user if they are sure
if (reallyClose) {
// disconnect
System.exit(0);
} else {
// do nothing, the window won't close
}
}
}
Regards,
Rogan
(I read that four times without understanding it, then I
realised I could probably understand the code faster..)
Here is a cut-down version of the code you posted
that does work, note the comments.
<sscce>
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class LDAPMgr extends JFrame {
public LDAPMgr() {
super();
setTitle("LDAPMgr");
/* create gui elements */
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
/*ask for confirmation before exiting */
int answer = JOptionPane.showConfirmDialog(null,
"Do you really want to quit?",
"Application Closing...",
JOptionPane.YES_NO_OPTION);
if (answer == 1)
return;
try {
//ldapUtility.disconnect();
} catch (NullPointerException Ex) {
// if null connection just exit w/no error mesg
/**** never ignore excpetions when code is
working in unexpected ways ****/
// a 'return' at this point
// is *not* what is needed!
return;
} catch (Exception Ex) {
JOptionPane.showMessageDialog(null,
"Disconnection failed!\n" + Ex.getMessage(),
"Connection",JOptionPane.ERROR_MESSAGE);
}
System.exit(0);
}
});
}
public static void main(String[] args) {
LDAPMgr LDAP = new LDAPMgr();
LDAP.setLocation(200,100);
LDAP.pack();
LDAP.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
LDAP.setVisible(true);
}
}
</sscce>
I hope you can figure what you're doing wrong from the
changed example, because..
Andrew T.
Yeah I'm an idiot. Since I technically didn't need a connection
established to test this my connection was null which meant I was
hitting my nullPointerException situation above where I was simply
returning from the windowClosing() method. I'll kick myself for that later.
Forgot to tell you thanks Andrew. Thanks :)
> Forgot to tell you thanks Andrew. Thanks :)
:-) Glad you sorted it.