JOptionPane.showMessageDialog wait until OK is clicked?

43,718

Solution 1

The JOptionPane creates a modal dialog and so the line beyond it will by design not be called until the dialog has been dealt with (either one of the buttons have been pushed or the close menu button has been pressed).

More important, you shouldn't be using a KeyListener for this sort of thing. If you want to have a JTextField listen for press of the enter key, add an ActionListener to it.

Solution 2

An easy work around to suite your needs is the use of showConfirmDialog(...), over showMessageDialog(), this lets you take the input from the user and then proceed likewise. Do have a look at this example program, for clarification :-)

import javax.swing.*;

public class JOptionExample
{
    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                int selection = JOptionPane.showConfirmDialog(
                                null
                        , "No active shares found on this IP!"
                        , "Selection : "
                        , JOptionPane.OK_CANCEL_OPTION
                        , JOptionPane.INFORMATION_MESSAGE);
                System.out.println("I be written" +
                     " after you close, the JOptionPane");      
                if (selection == JOptionPane.OK_OPTION)
                {
                    // Code to use when OK is PRESSED.
                    System.out.println("Selected Option is OK : " + selection);
                }
                else if (selection == JOptionPane.CANCEL_OPTION)
                {
                    // Code to use when CANCEL is PRESSED.
                    System.out.println("Selected Option Is CANCEL : " + selection);
                }
            }           
        });
    }
}

Solution 3

You can get acces to the OK button if you create optionpanel and custom dialog. Here's an example of this kind of implementation:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author OZBORN
 */
public class TestyDialog {
    static JFrame okno;
    static JPanel panel;
    /**
     * @param args the command line arguments
     */

    public static void main(String[] args) {
        zrobOkno();
        JButton przycisk =new JButton("Dialog");
        przycisk.setSize(200,200);
        panel.add(przycisk,BorderLayout.CENTER);
        panel.setCursor(null);
        BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
        przycisk.setCursor(Toolkit.getDefaultToolkit().createCustomCursor(
                            cursorImg, new Point(0, 0), "blank cursor"));
        final JOptionPane optionPane = new JOptionPane(
                "U can close this dialog\n"
                + "by pressing ok button, close frame button or by clicking outside of the dialog box.\n"
                +"Every time there will be action defined in the windowLostFocus function"
                + "Do you understand?",
                JOptionPane.INFORMATION_MESSAGE,
                JOptionPane.DEFAULT_OPTION);

        System.out.println(optionPane.getComponentCount());
        przycisk.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                final JFrame aa=new JFrame();
                final JDialog dialog = new JDialog(aa,"Click a button",false);
                ((JButton)((JPanel)optionPane.getComponents()[1]).getComponent(0)).addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        aa.dispose();
                    }
                });
                dialog.setContentPane(optionPane);
                dialog.pack();

                dialog.addWindowFocusListener(new WindowFocusListener() {
                    @Override
                    public void windowLostFocus(WindowEvent e) {
                        System.out.println("Zamykam");        
                        aa.dispose();
                    }
                    @Override public void windowGainedFocus(WindowEvent e) {}
                });

                dialog.setVisible(true);    
            }
        });
    }
    public static void zrobOkno(){
        okno=new JFrame("Testy okno");
        okno.setLocationRelativeTo(null);
        okno.setSize(200,200);
        okno.setPreferredSize(new Dimension(200,200));
        okno.setVisible(true);
        okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        panel=new JPanel();
        panel.setPreferredSize(new Dimension(200,200));
        panel.setLayout(new BorderLayout());
        okno.add(panel);
    }
}
Share:
43,718
swiftcode
Author by

swiftcode

Software engineer, mostly focusing on the awesome iOS world of development.

Updated on April 29, 2020

Comments

  • swiftcode
    swiftcode about 4 years

    This might be a very simple thing that I'm overlooking, but I just can't seem to figure it out.

    I have the following method that updates a JTable:

    class TableModel extends AbstractTableModel {    
            public void updateTable() {
                try {
                    // update table here
                 ...
        } catch (NullPointerException npe) {
                    isOpenDialog = true;
                    JOptionPane.showMessageDialog(null, "No active shares found on this IP!");
                    isOpenDialog = false;
                }
            }
        }
    

    However, I don't want isOpenDialog boolean to be set to false until the OK button on the message dialog is pressed, because if a user presses enter it will activate a KeyListener event on a textfield and it triggers that entire block of code again if it's set to false.

    Part of the KeyListener code is shown below:

    public class KeyReleased implements KeyListener {
            ...
    
        @Override
        public void keyReleased(KeyEvent ke) {
            if(txtIPField.getText().matches(IPADDRESS_PATTERN)) {
                validIP = true;
            } else {
                validIP = false;
            }
    
            if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
                if (validIP && !isOpenDialog) {
                    updateTable();
                }
            }
        }
    }
    

    Does JOptionPane.showMessageDialog() have some sort of mechanism that prevents executing the next line until the OK button is pressed? Thank you.

  • Christoph Walesch
    Christoph Walesch almost 12 years
    Swing operations (such as opening a dialog) should happen in the EventDispatchThread
  • Hovercraft Full Of Eels
    Hovercraft Full Of Eels almost 12 years
    Agree with noise: This kind of code doesn't belong in a Swing application as it completely ignores Swing threading rules.
  • Kumar Vivek Mitra
    Kumar Vivek Mitra almost 12 years
    Even i agree that Swing operation must happen in Event Dispatcher Thread, as main() method in swing application schedules the construction of the GUI in the Event Dispatcher Thread and quits. but Rules described in books are for the ideal world, and sometimes one needs to be a rebel to get the work done.
  • ryvantage
    ryvantage almost 11 years
    Your ideology is flawed, @KumarVivekMitra.