Search code examples
javaswingjpaneljoptionpane

Manually trigger OK_OPTION for a JOptionPane within a JPanel


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?


Solution

  • 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();
        }
    }