Search code examples
javaswingjoptionpanecustom-component

Customise `JOptionPane.YES_NO_OPTION`


Developing a swing application where I need to redirect the user to another JFrame if he clicks the No button on a JoptionPane.showConfirmDialog. I wrote this code :

private void formWindowClosing(java.awt.event.WindowEvent evt) {                                   
    int a=JOptionPane.showConfirmDialog(this, "Did you complete your task?");
    JOptionPane.showMessageDialog(null, a);
    if(a==1){
        RedirectedForm rf=new RedirectedForm();
        rf.setVisible(true);
    }
}

But if(a==1){...} part does not seem to work. Even if I create a reference to the JFrame-RedirectedForm which I want to redirect to, the window gets disposed always. Can anybody explain the reason and suggest a solution to this?
Any help is appreciated, Thanks!!!

Providing both the java classes below :

WindowClosing.java

import javax.swing.JOptionPane;

public class WindowClosing extends javax.swing.JFrame {

public WindowClosing() {
    initComponents();
}
private void initComponents() {
    window_close_label = new javax.swing.JLabel();
    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    addWindowListener(new java.awt.event.WindowAdapter() {
        public void windowClosing(java.awt.event.WindowEvent evt) {
            formWindowClosing(evt);
        }
    });

    window_close_label.setText("Window Close Form");
    pack();
}                        

private void formWindowClosing(java.awt.event.WindowEvent evt) {                                   
    int a=JOptionPane.showConfirmDialog(this, "Did you complete your task?");
    JOptionPane.showMessageDialog(null, a);
    if(a==1){
        RedirectedForm rf=new RedirectedForm();
        rf.setVisible(true);
    }
}                                  
public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new WindowClose().setVisible(true);
        }
    });
}
private javax.swing.JLabel window_close_label;
}

RedirectedForm.java

public class RedirectedForm extends javax.swing.JFrame {
public RedirectedForm() {
    initComponents();
}

private void initComponents() {

    jLabel1 = new javax.swing.JLabel();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jLabel1.setText("You have been redirected to this Form becuse you have closed the previous one");

    pack();
}

public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new RedirectForm().setVisible(true);
        }
    });
}
private javax.swing.JLabel jLabel1;                  

}

I have edited the code once more, hope this will give a clearer idea about the problem


Solution

  • Your main problem is probably that you set

    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    

    This causes the whole application to exit when you close the frame, regardless of which option you chose in the dialog. Nevertheless, you shouldn't use multiple JFrames, but instead use CardLayout as demonstrated here:

    public class Example extends JFrame {
    
        private String redirectedForm = "RedirectedForm";
        private String windowClosing = "WindowClosing";
    
        Example() {
    
            CardLayout cl = new CardLayout();
            getContentPane().setLayout(cl);
            add(new WindowClosing(), windowClosing);
            add(new RedirectedForm(), redirectedForm);
    
            addWindowListener(new WindowAdapter() {
    
                public void windowClosing(WindowEvent evt) {
    
                    int a = JOptionPane.showConfirmDialog(Example.this, "Did you complete your task?");
                    if (a == JOptionPane.CANCEL_OPTION) {
                        return;
                    }
                    if (a == JOptionPane.NO_OPTION) {
    //                  cl.next(frame.getContentPane()); // This to show the next card
                        cl.show(getContentPane(), redirectedForm); // This is to show a specified card
                    }
                    else {
                        dispose();
                    }
                }
            });
    
            setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE );
            pack();
            setLocationRelativeTo(null);
            setVisible(true);
        }
    
        public static void main(String args[]) {
    
            new Example();
        }
    }
    
    class WindowClosing extends JPanel {
    
        public WindowClosing() {
    
            JLabel closeLabel = new JLabel("The WindowClosing panel");
            add(closeLabel);
        }
    }
    
    class RedirectedForm extends JPanel {
    
        public RedirectedForm() {
    
            JLabel label = new JLabel("You have been redirected to this Form becuse you have closed the previous one");
            add(label);
        }
    }
    

    By setting DO_NOTHING_ON_CLOSE the windowClosing event will not terminate the program. Instead you choose what do do depending on the selected option: nothing, exit, or switch panel.

    Notes:

    • Don't use the int values of static constants such as JOptionPane.NO_OPTION, just use the reference to it instead.
    • You might want to set an owner for the JOptionPane.