How can I dismiss one JOptionPane upon emergence of another JOptionPane in the GUI

JavaSa picture JavaSa · Oct 16, 2011 · Viewed 8.6k times · Source

As you have seen from my subject above,
I would like to know how can I dismiss a JOptionPane which became irrelevant because of another JOptionPane and because the user ,for some reason, didn't dismiss the first one by himself clicking ok button (for example).

I've seen some ware in other site similar question, and people suggested to do simply:

JOptionPane.getRootFrame().dispose();  

But how can I store a reference for each JOptionPane I have and to be able to dismiss only that wanted one.
Thanks

Edited:
Code example:

package Gui;

import javax.swing.JOptionPane;
import java.awt.*;

/**
 *
 * @author 
 */
public class JpanelMainView extends javax.swing.JPanel {

    /** Creates new form JpanelMainView */
    public JpanelMainView() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jButton1 = new javax.swing.JButton();

        jButton1.setText("jButton1");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(149, 149, 149)
                .addComponent(jButton1)
                .addContainerGap(178, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(77, 77, 77)
                .addComponent(jButton1)
                .addContainerGap(200, Short.MAX_VALUE))
        );
    }// </editor-fold>                        

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)                                         
    {                                             
       JOptionPane.showMessageDialog(this, "Board was sent for validation check\n Please wait...","Board Sent",JOptionPane.INFORMATION_MESSAGE);

       //Please note that this OptionPane is coming in my real program always after the first JoptionPane
       //I want that if I've reached the line in the code that need to show this second JoptionPane, I will first close the first JoptionPane
       //Else you will dismiss the last JoptionPane and then the first one and I don't want to give the user two JoptionPane to close, it's annoying.
       JOptionPane.showMessageDialog(this, "Set your move now please","Game started",JOptionPane.INFORMATION_MESSAGE);
    }                                        

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    // End of variables declaration                   

}

Answer

Hovercraft Full Of Eels picture Hovercraft Full Of Eels · Oct 17, 2011

I would recommend that you

  • create a JDialog with your JOptionPane (the JOptionPane API will show you how),
  • then use a SwingWorker for whatever background task you wish to do that should be done off of the main Swing thread, the EDT,
  • Then in the SwingWorker's done() method which is called when the background task is complete, dispose of the JDialog.
  • Then the next JOptionPane will be called immediately.

For example the following code uses a Thread.sleep(3000) for a 3 second sleep to mimic a background task that takes 3 seconds. It will then close the first dialog and show the second:

   private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
      JOptionPane messagePane = new JOptionPane(
            "Board was sent for validation check\n Please wait...",
            JOptionPane.INFORMATION_MESSAGE);
      final JDialog dialog = messagePane.createDialog(this, "Board Sent");

      new SwingWorker<Void, Void>() {

         @Override
         protected Void doInBackground() throws Exception {
            // do your background processing here
            // for instance validate your board here

            // mimics a background process that takes 3 seconds
            // you would of course delete this in your actual progam
            Thread.sleep(3000); 

            return null;
         }

         // this is called when background thread above has completed.
         protected void done() {
            dialog.dispose();
         };
      }.execute();

      dialog.setVisible(true);

      JOptionPane.showMessageDialog(this, "Set your move now please",
            "Game started", JOptionPane.INFORMATION_MESSAGE);
   }