I have an action defined in the same package as the JDialog. I want to bind the Java Dialog`s close button to this action, without using window listeners. Just set once this action to the button. Can you help me do this, please? Thank you
-
3Why dont you want to use a WindowListener? – Stefan Sep 11 '14 at 12:03
-
Because I don`t want to make the association every time the button is clicked.. I think once it is enough – Sep 11 '14 at 12:06
-
You need to add some code. You could add the listener once the dialog is created. – Stefan Sep 11 '14 at 12:08
-
2You must use window listener for this purpose. But you can write it once if the action is common and use it for all dialogs – Sergiy Medvynskyy Sep 11 '14 at 12:10
-
1If I understand you well, you could extend `JDialog` with a class and use that custom class instead, binding the code to the closing operation of your custom dialog. Or to you want to run that action only once and never again? – Jonathan Drapeau Sep 11 '14 at 13:09
2 Answers
The following code should achieve what you need using a WindowAdapter as a WindowListener. The windowClosing method is called exactly once upon pressing the close button. If you plan to add an alternative Close-Button you can always fire a windowClosing event and do not need to handle it separatly.
import java.awt.EventQueue;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JDialog;
import javax.swing.WindowConstants;
public class DummyDialog extends JDialog {
DummyDialog() {
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent arg0) {
System.out.println("Window closing");
}
});
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
DummyDialog d = new DummyDialog();
d.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}

- 135
- 7
By default Swing will use the widgets of the OS you are running on so you don't have access to the button since it is not a Swing component.
If you want to use the Swing LAF then you can access the close button and add your ActionListener to the button. The code would be:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DialogCloseAction
{
private static void createAndShowGUI()
{
JDialog.setDefaultLookAndFeelDecorated(true);
JDialog dialog = new JDialog();
dialog.setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE );
dialog.setSize(200, 200);
dialog.setLocationRelativeTo(null);
dialog.setVisible( true );
Action close = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
System.out.println("closing...");
}
};
JButton button = SwingUtils.getDescendantOfType(
JButton.class, dialog.getRootPane(), "Icon", UIManager.getIcon("InternalFrame.closeIcon"));
button.addActionListener( close );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
You will need to use Darryl's Swing Utils class to search the frame for the custom button.
Otherwise, as has already been suggested, you will need to use a WindowListener
. If you want you can check out Closing an Application which has a simple API that allows you to add an Action to the custom CloseListener
.

- 321,443
- 19
- 166
- 288