31

I want to add a button (JButton) at the bottom of a JDialog which should close the JDialog when pressed. The problem is I don't know what to write in the ActionListener of that button. I don't want the button to exit the program, just close the dialog.

The JDialog is created by explicitly calling one of JDialog's constructors, not by calling one of the methods from JOptionPane.

I was extremely surprised that I was unable to find an answer to this using Google. I expected that a problem that is so often encoutered would be widely covered on a lot of programming sites. Pretty weird that it is not.

tshepang
  • 12,111
  • 21
  • 91
  • 136
SoboLAN
  • 313
  • 1
  • 3
  • 4
  • Well, I never used a JDialog before today. And I did look at that javadoc a few dozen times (I needed to see what methods it contains). But I didn't see anything about closing it. – SoboLAN Aug 06 '11 at 22:46
  • 1
    @SoboLAN two methods: `dispose()` & `setVisible(false)` – Eng.Fouad Aug 07 '11 at 00:36

5 Answers5

53
import java.awt.event.*;
import javax.swing.*;

public class YourDialog extends JDialog implements ActionListener {

  JButton button;

  public YourDialog() {
     button = new JButton("Close");
     button.addActionListener(this);
     add(button);
     pack();
     setVisible(true);
  }

  public void actionPerformed(ActionEvent e) {
      dispose();
  }
}
  • close only dialolg using dispose() method parent frame not closed. reason that JVM not terminated.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
Mohammed Aslam
  • 995
  • 9
  • 14
8

You can have the ActionListener dispatch a WindowEvent.WINDOW_CLOSING, as shown here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • 3
    +1, dispatching the event to the window allows any WindowListener code to be executed. For what its worth you can also check out the `ExitAction` class found in [Closing an Application](http://tips4java.wordpress.com/2009/05/01/closing-an-application/). The action is a little more general in that it can be used with any frame or dialog. – camickr Aug 07 '11 at 02:41
  • 1
    @camickr: `ExitAction` looks like a good way to ensure that all exits pass through the `WindowListener`. – trashgod Aug 07 '11 at 03:00
6

In the actionPerformed() method of ActionListener you'll want something like:

dialog.setVisible(false);

If you want to get rid of the dialog permanently (free it from memory) then you would also call:

dialog.dispose(); 

...where dialog is the name of your dialog. If dialog is a local variable, you'll need to make it final to access it in this way (or just make sure it's "effectively final" from Java 8 onwards).

If you're adding the button as part of a subclass of JDialog (i.e. if you've got class MyDialog extends JDialog and you're adding the action listener in MyDialog) you'll want:

MyDialog.this.setVisible(false);
Michael Berry
  • 70,193
  • 21
  • 157
  • 216
  • I did this when I created the JDialog: dialog.SetDefaultCloseOperation (JDialog.DISPOSE_ON_CLOSE);. In the ActionListener I called these 2 methods: dialog.setVisible (false); dialog.dispatchEvent (new WindowEvent (dialog, WindowEvent.WINDOW_CLOSING);. The JDialog does indeed close but the way I did it is correct ? Thank you for your (surprisingly fast) answer, btw. – SoboLAN Aug 06 '11 at 22:26
  • @berry120 - Surely the JDialog, it's layout and components will continue to exist in memory using this method? I imagine you could get yourself into a serious mess doing this regularly. – Rudi Kershaw Oct 22 '13 at 11:44
  • @RudiKershaw It would, yes - obviously whether you dispose of it comes down to whether you're reusing the same dialog later or creating them as you need them. – Michael Berry Oct 22 '13 at 12:56
  • @berry120 +1 for the `MyDialog.this`, but I am not sure how does that notation work. I understand that `MyDialog` is an static call to the class but how does it "know" that `this` is the reference that contains `Button`? – toto_tico Feb 06 '16 at 19:20
2

In addition to other answers, you can set it as the default button for the dialog root pane:

JButton myButton = new JButton("Close");
myButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        dispose(); // Or whatever else
        setVisible(false);
    }
});
getRootPane().setDefaultButton(myButton);

That way, its ActionListener will be called whenever Enter is pressed.

Matthieu
  • 2,736
  • 4
  • 57
  • 87
0

I have done this slightly differently and it serves the purpose. I have several classes. They extend JPanel, serve different purposes and use JDialogs to get users' inputs.

A typical class would contain necessary fields, save and cancel buttons.

public class EnterpriseGUI extends javax.swing.JPanel {...} would look like this:

JPanel class in designer mode

Class EnterpriseGUI has a private variable jdialog and a method to set jdialog. Also ActionEvent for 'save' button and 'cancel' button.

private JDialog jdialog;
public void setJDialog(JDialog jdialog) {
    this.jdialog = jdialog;
}
private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {                                        
    // Do your stuff..
    jdialog.dispose();
} 
private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {                                          
    // Discard your stuff..
    jdialog.dispose();
} 

Finally, I create an instance of EnterpriseGUI from any other class as needed and embed it into JDialog.

Class OtherClass{
private JDialog dialog;
private EnterpriseGUI = new enterprisegui();
    private void button1ActionPerformed(java.awt.event.ActionEvent evt) {                                             
        this.dialog = new JDialog(this, "My dialog", true);
        this.dialog.setResizable(false);
        enterprisegui.setJDialog(dialog);
        this.dialog.getContentPane().add(enterprisegui);
        this.dialog.pack();

        Dimension Size = Toolkit.getDefaultToolkit().getScreenSize();
        this.dialog.setLocation(new Double((Size.getWidth()/2) - 
                (dialog.getWidth()/2)).intValue(), new Double((Size.getHeight()/2) - 
                        (dialog.getHeight()/2)).intValue());
        this.dialog.setVisible(true);

    }  
}
Max von Hippel
  • 2,856
  • 3
  • 29
  • 46
Gaurang
  • 67
  • 8