Manually trigger OK_OPTION for a JOptionPane within a JPanel

73 views Asked by At

I've got some utility code that presents a JList inside a JPanel that is used inside a JOptionPane.showOptionDialog, similar to this:

SelectionPanel<T> panel = new SelectionPanel<>(allValues, initiallySelectedElement, multipleSelection);
int action = JOptionPane.showOptionDialog(parent, panel, title, JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null);
if (action == JOptionPane.OK_OPTION) {
    // Do stuff
}

This works well, but I've had a feature request to be able to double click in the list to add the clicked element. The panel has no knowledge of being wrapped in a JOptionPane, and ideally I would like to keep it that way.

I've found that I can close the dialog using the following code:

@Override
public void mouseClicked(MouseEvent e) {
    if (e.getClickCount() == 2 && !e.isControlDown()) {
        Window w = SwingUtilities.getWindowAncestor(this);
        w.setVisible(false);
    }
}

However this closes it without action == JOptionPane.OK_OPTION being true.

Is there any generic way of signaling the OK_OPTION action and closing, from a JPanel that is oblivious to being inside a JOptionPane?

2

There are 2 answers

4
Sergiy Medvynskyy On BEST ANSWER

You should modify your mouseClicked method as following:

@Override
public void mouseClicked(MouseEvent e) {
    if (e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e) && !e.isControlDown()) {
        JOptionPane pane = (JOptionPane) SwingUtilities.getAncestorOfClass(JOptionPane.class, e.getComponent());
        pane.setValue(JOptionPane.OK_OPTION);
        Window w = SwingUtilities.getWindowAncestor(this);
        w.dispose();
    }
}
1
DevilsHnd - 退した On

The following runnable code may be another solution for you: Read the comments in code:

public class DoubleClickJListItemToExitDialog {

    
    public static void main(String[] args) {
        new DoubleClickJListItemToExitDialog().startApp(args);
    }
    
    private void startApp(String[] args) {
        // Temp OptionPane Parent...
        javax.swing.JFrame iFrame = new javax.swing.JFrame();
        iFrame.setAlwaysOnTop(true);
        iFrame.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
        iFrame.setLocationRelativeTo(null);
        
        String selectedItem = null;  // To hold the selected list item String value;
        
        
        javax.swing.JPanel panel = new javax.swing.JPanel();        // Create JPanel
        panel.setPreferredSize(new java.awt.Dimension(300, 200));   // Set its size
        
        javax.swing.JLabel msg = new javax.swing.JLabel(            // Create the dialog message
                "<html>Select an item from the list and then select the OK<br>"
                + "button.  If you like,  you can also double-click on the<br>"
                + "item in the list as well to make your selection.<br><br></html>");
        panel.add(msg);     // Add message to panel
        
        // Create a DefaultListModel
        javax.swing.DefaultListModel<String> model = new javax.swing.DefaultListModel<>();
        // Add (whatever) String elements to the Model
        for (int i = 0; i < 20; i++) {
            model.addElement("List String Item " + (i+1));
        }
        
        // Create a JList and add the DefaultListModel to it.
        javax.swing.JList<String> list = new javax.swing.JList<>(model);
        /* Add a MouseListener to the JList so to pick up Double-Clicks 
           within the mouseClicked event:             */
        list.addMouseListener(new java.awt.event.MouseListener() {
            @Override
            public void mouseClicked(java.awt.event.MouseEvent e) {
                // Was the left mouse button clicked twice
                if (e.getClickCount() == 2 && javax.swing.SwingUtilities.isLeftMouseButton(e)) {
                    // Get the OptionPane...
                    javax.swing.JOptionPane pane = (javax.swing.JOptionPane) 
                            javax.swing.SwingUtilities.getAncestorOfClass(
                                    javax.swing.JOptionPane.class, e.getComponent());
                    // Fire the OK Option button
                    pane.setValue(javax.swing.JOptionPane.OK_OPTION);
                }
            }

            @Override
            public void mousePressed(java.awt.event.MouseEvent e) {
                // Not in use here.
            }

            @Override
            public void mouseReleased(java.awt.event.MouseEvent e) {
                // Not in use here.
            }

            @Override
            public void mouseEntered(java.awt.event.MouseEvent e) {
                // Not in use here.
            }

            @Override
            public void mouseExited(java.awt.event.MouseEvent e) {
                // Not in use here.
            }
        });
        
        // Create a JScrollPane and add the JList to it.
        javax.swing.JScrollPane sp = new javax.swing.JScrollPane(list);
        // Set the desired JScrollPane Size
        sp.setPreferredSize(new java.awt.Dimension(180,120));
        // Add the JScrollPane to the JPanel
        panel.add(sp);
        
        /* Display the JOptionPane Option Dialog using the temp JFrame as parent 
           and the newly created JPanel as its content, the desired title, the
           desired dialog buttons (OK and Cancel), as a Plain Message dialog (no
           icon image).        */
        int res = javax.swing.JOptionPane.showOptionDialog(iFrame, panel, 
                "Select From List:", javax.swing.JOptionPane.OK_CANCEL_OPTION, 
                javax.swing.JOptionPane.PLAIN_MESSAGE, null, null, null);
        
        // If the dialog's OK button was selected....
        if (res == javax.swing.JOptionPane.OK_OPTION) {
            // Get the selected JList element and store in `selectedItem`:
            selectedItem = list.getSelectedValue();
            // Open a messge dialog to display the selected JList item:
            javax.swing.JOptionPane.showMessageDialog(iFrame, 
                    "<html>Selected List Item Was:<br><br><center><font size='5' color=blue><b>" 
                    + selectedItem + "</b></font></center><br></html>", "Your Selection", 
                    javax.swing.JOptionPane.INFORMATION_MESSAGE);
        }
        iFrame.dispose();  // Dispose of the temp JFrame Parent.
    }
}