2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
24 import java.awt.Component;
25 import java.awt.Dialog.ModalityType;
26 import java.awt.HeadlessException;
27 import java.awt.Window;
28 import java.awt.event.ActionEvent;
29 import java.awt.event.ActionListener;
30 import java.beans.PropertyChangeEvent;
31 import java.beans.PropertyChangeListener;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.HashMap;
35 import java.util.List;
37 import java.util.concurrent.Callable;
38 import java.util.concurrent.Executors;
40 import javax.swing.Icon;
41 import javax.swing.JButton;
42 import javax.swing.JDialog;
43 import javax.swing.JFrame;
44 import javax.swing.JInternalFrame;
45 import javax.swing.JOptionPane;
46 import javax.swing.JPanel;
47 import javax.swing.SwingUtilities;
48 import javax.swing.UIManager;
50 import jalview.util.Platform;
51 import jalview.util.dialogrunner.DialogRunnerI;
53 public class JvOptionPane extends JOptionPane
54 implements DialogRunnerI, PropertyChangeListener
56 private static final long serialVersionUID = -3019167117756785229L;
58 private static Object mockResponse = JOptionPane.CANCEL_OPTION;
60 private static boolean interactiveMode = true;
62 private Component parentComponent;
64 private Map<Object, Callable<Void>> callbacks = new HashMap<>();
67 * JalviewJS reports user choice in the dialog as the selected
68 * option (text); this list allows conversion to index (int)
70 List<Object> ourOptions;
72 public JvOptionPane(final Component parent)
74 this.parentComponent = Platform.isJS() ? this : parent;
77 public static int showConfirmDialog(Component parentComponent,
78 Object message) throws HeadlessException
80 // only called by test
81 return isInteractiveMode()
82 ? JOptionPane.showConfirmDialog(parentComponent, message)
83 : (int) getMockResponse();
87 * Message, title, optionType
89 * @param parentComponent
94 * @throws HeadlessException
96 public static int showConfirmDialog(Component parentComponent,
97 Object message, String title, int optionType)
98 throws HeadlessException
100 if (!isInteractiveMode())
102 return (int) getMockResponse();
106 case JOptionPane.YES_NO_CANCEL_OPTION:
107 // FeatureRenderer amendFeatures ?? TODO ??
112 case JOptionPane.YES_NO_OPTION:
113 // PromptUserConfig usage stats
114 // for now treated as "OK CANCEL"
116 case JOptionPane.OK_CANCEL_OPTION:
117 // will fall back to simple HTML
118 return JOptionPane.showConfirmDialog(parentComponent, message, title,
124 * Adds a message type. Fallback is to just add it in the beginning.
126 * @param parentComponent
132 * @throws HeadlessException
134 public static int showConfirmDialog(Component parentComponent,
135 Object message, String title, int optionType, int messageType)
136 throws HeadlessException
138 // JalviewServicesChanged
139 // PromptUserConfig raiseDialog
140 return isInteractiveMode()
141 ? JOptionPane.showConfirmDialog(parentComponent, message, title,
142 optionType, messageType)
143 : (int) getMockResponse();
149 * @param parentComponent
156 * @throws HeadlessException
158 public static int showConfirmDialog(Component parentComponent,
159 Object message, String title, int optionType, int messageType,
160 Icon icon) throws HeadlessException
162 // JvOptionPaneTest only
163 return isInteractiveMode()
164 ? JOptionPane.showConfirmDialog(parentComponent, message, title,
165 optionType, messageType, icon)
166 : (int) getMockResponse();
170 * Internal version "OK"
172 * @param parentComponent
176 public static int showInternalConfirmDialog(Component parentComponent,
179 // JvOptionPaneTest only;
180 return isInteractiveMode()
181 ? JOptionPane.showInternalConfirmDialog(parentComponent,
183 : (int) getMockResponse();
187 * Internal version -- changed to standard version for now
189 * @param parentComponent
195 public static int showInternalConfirmDialog(Component parentComponent,
196 String message, String title, int optionType)
198 if (!isInteractiveMode())
200 return (int) getMockResponse();
204 case JOptionPane.YES_NO_CANCEL_OPTION:
205 // ColourMenuHelper.addMenuItmers.offerRemoval TODO
206 case JOptionPane.YES_NO_OPTION:
207 // UserDefinedColoursSave -- relevant? TODO
210 case JOptionPane.OK_CANCEL_OPTION:
212 // EditNameDialog --- uses panel for messsage TODO
214 // Desktop.inputURLMenuItem
216 return JOptionPane.showConfirmDialog(parentComponent, message, title,
223 * @param parentComponent
230 public static int showInternalConfirmDialog(Component parentComponent,
231 Object message, String title, int optionType, int messageType)
233 if (!isInteractiveMode())
235 return (int) getMockResponse();
239 case JOptionPane.YES_NO_CANCEL_OPTION:
240 case JOptionPane.YES_NO_OPTION:
241 // UserQuestionanaireCheck
245 case JOptionPane.OK_CANCEL_OPTION:
246 // will fall back to simple HTML
247 return JOptionPane.showConfirmDialog(parentComponent, message, title,
248 optionType, messageType);
253 * adds icon; no longer internal
255 * @param parentComponent
263 public static int showInternalConfirmDialog(Component parentComponent,
264 Object message, String title, int optionType, int messageType,
267 if (!isInteractiveMode())
269 return (int) getMockResponse();
273 case JOptionPane.YES_NO_CANCEL_OPTION:
274 case JOptionPane.YES_NO_OPTION:
277 case JOptionPane.OK_CANCEL_OPTION:
278 // Preferences editLink/newLink
279 return JOptionPane.showConfirmDialog(parentComponent, message, title,
280 optionType, messageType, icon);
286 * custom options full-featured
288 * @param parentComponent
295 * @param initialValue
297 * @throws HeadlessException
299 public static int showOptionDialog(Component parentComponent,
300 String message, String title, int optionType, int messageType,
301 Icon icon, Object[] options, Object initialValue)
302 throws HeadlessException
304 if (!isInteractiveMode())
306 return (int) getMockResponse();
312 // 1) AlignViewport for openLinkedAlignment
314 // Show a dialog with the option to open and link (cDNA <-> protein) as a
316 // alignment, either as a standalone alignment or in a split frame. Returns
317 // true if the new alignment was opened, false if not, because the user
318 // declined the offer.
320 // 2) UserDefinedColors warning about saving over a name already defined
322 return JOptionPane.showOptionDialog(parentComponent, message, title,
323 optionType, messageType, icon, options, initialValue);
330 * @throws HeadlessException
332 public static void showMessageDialog(Component parentComponent,
333 String message) throws HeadlessException
335 if (!isInteractiveMode())
337 outputMessage(message);
343 JOptionPane.showMessageDialog(parentComponent, message);
347 * OK with message, title, and type
349 * @param parentComponent
353 * @throws HeadlessException
355 public static void showMessageDialog(Component parentComponent,
356 String message, String title, int messageType)
357 throws HeadlessException
359 // 30 implementations -- all just fine.
361 if (!isInteractiveMode())
363 outputMessage(message);
367 JOptionPane.showMessageDialog(parentComponent,
368 getPrefix(messageType) + message, title, messageType);
372 * adds title and icon
374 * @param parentComponent
379 * @throws HeadlessException
381 public static void showMessageDialog(Component parentComponent,
382 String message, String title, int messageType, Icon icon)
383 throws HeadlessException
388 if (!isInteractiveMode())
390 outputMessage(message);
394 JOptionPane.showMessageDialog(parentComponent, message, title,
402 public static void showInternalMessageDialog(Component parentComponent,
406 // WsPreferences only
408 if (!isInteractiveMode())
410 outputMessage(message);
414 JOptionPane.showMessageDialog(parentComponent, message);
418 * Adds title and messageType
420 * @param parentComponent
425 public static void showInternalMessageDialog(Component parentComponent,
426 String message, String title, int messageType)
431 if (!isInteractiveMode())
433 outputMessage(message);
437 JOptionPane.showMessageDialog(parentComponent,
438 getPrefix(messageType) + message, title, messageType);
443 * @param parentComponent
449 public static void showInternalMessageDialog(Component parentComponent,
450 Object message, String title, int messageType, Icon icon)
455 if (!isInteractiveMode())
457 outputMessage(message);
461 JOptionPane.showMessageDialog(parentComponent, message, title,
469 * @throws HeadlessException
471 public static String showInputDialog(Object message)
472 throws HeadlessException
476 if (!isInteractiveMode())
478 return getMockResponse().toString();
481 return JOptionPane.showInputDialog(message);
485 * adds inital selection value
488 * @param initialSelectionValue
491 public static String showInputDialog(String message,
492 String initialSelectionValue)
494 if (!isInteractiveMode())
496 return getMockResponse().toString();
499 // AnnotationPanel character option
501 return JOptionPane.showInputDialog(message, initialSelectionValue);
505 * adds inital selection value
508 * @param initialSelectionValue
511 public static String showInputDialog(Object message,
512 Object initialSelectionValue)
514 if (!isInteractiveMode())
516 return getMockResponse().toString();
519 // AnnotationPanel character option
521 return JOptionPane.showInputDialog(message, initialSelectionValue);
527 * @param parentComponent
530 * @throws HeadlessException
532 public static String showInputDialog(Component parentComponent,
533 String message) throws HeadlessException
537 return isInteractiveMode()
538 ? JOptionPane.showInputDialog(parentComponent, message)
539 : getMockResponse().toString();
543 * input with initial selection
545 * @param parentComponent
547 * @param initialSelectionValue
550 public static String showInputDialog(Component parentComponent,
551 String message, String initialSelectionValue)
556 return isInteractiveMode()
557 ? JOptionPane.showInputDialog(parentComponent, message,
558 initialSelectionValue)
559 : getMockResponse().toString();
563 * input with initial selection
565 * @param parentComponent
567 * @param initialSelectionValue
570 public static String showInputDialog(Component parentComponent,
571 Object message, Object initialSelectionValue)
576 return isInteractiveMode()
577 ? JOptionPane.showInputDialog(parentComponent, message,
578 initialSelectionValue)
579 : getMockResponse().toString();
584 * @param parentComponent
589 * @throws HeadlessException
591 public static String showInputDialog(Component parentComponent,
592 String message, String title, int messageType)
593 throws HeadlessException
598 return isInteractiveMode()
599 ? JOptionPane.showInputDialog(parentComponent, message, title,
601 : getMockResponse().toString();
605 * Customized input option
607 * @param parentComponent
612 * @param selectionValues
613 * @param initialSelectionValue
615 * @throws HeadlessException
617 public static Object showInputDialog(Component parentComponent,
618 Object message, String title, int messageType, Icon icon,
619 Object[] selectionValues, Object initialSelectionValue)
620 throws HeadlessException
625 return isInteractiveMode()
626 ? JOptionPane.showInputDialog(parentComponent, message, title,
627 messageType, icon, selectionValues,
628 initialSelectionValue)
629 : getMockResponse().toString();
635 * @param parentComponent
639 public static String showInternalInputDialog(Component parentComponent,
644 return isInteractiveMode()
645 ? JOptionPane.showInternalInputDialog(parentComponent, message)
646 : getMockResponse().toString();
650 * internal with title and messageType
652 * @param parentComponent
658 public static String showInternalInputDialog(Component parentComponent,
659 String message, String title, int messageType)
662 // AlignFrame tabbedPane_mousePressed
664 return isInteractiveMode()
665 ? JOptionPane.showInternalInputDialog(parentComponent,
666 getPrefix(messageType) + message, title, messageType)
667 : getMockResponse().toString();
671 * customized internal
673 * @param parentComponent
678 * @param selectionValues
679 * @param initialSelectionValue
682 public static Object showInternalInputDialog(Component parentComponent,
683 String message, String title, int messageType, Icon icon,
684 Object[] selectionValues, Object initialSelectionValue)
688 return isInteractiveMode()
689 ? JOptionPane.showInternalInputDialog(parentComponent, message,
690 title, messageType, icon, selectionValues,
691 initialSelectionValue)
692 : getMockResponse().toString();
695 ///////////// end of options ///////////////
697 private static void outputMessage(Object message)
699 System.out.println(">>> JOption Message : " + message.toString());
702 public static Object getMockResponse()
707 public static void setMockResponse(Object mockOption)
709 JvOptionPane.mockResponse = mockOption;
712 public static void resetMock()
714 setMockResponse(JOptionPane.CANCEL_OPTION);
715 setInteractiveMode(true);
718 public static boolean isInteractiveMode()
720 return interactiveMode;
723 public static void setInteractiveMode(boolean interactive)
725 JvOptionPane.interactiveMode = interactive;
728 private static String getPrefix(int messageType)
737 case JOptionPane.WARNING_MESSAGE:
738 prefix = "WARNING! ";
740 case JOptionPane.ERROR_MESSAGE:
751 * create a new option dialog that can be used to register responses - along
752 * lines of showOptionDialog
757 * @param defaultOption
758 * @param plainMessage
764 public static JvOptionPane newOptionDialog()
766 return new JvOptionPane(null);
769 public static JvOptionPane newOptionDialog(Component parentComponent)
771 return new JvOptionPane(parentComponent);
774 public void showDialog(String message, String title, int optionType,
775 int messageType, Icon icon, Object[] options, Object initialValue)
777 showDialog(message, title, optionType, messageType, icon, options,
781 public void showDialog(Object message, String title, int optionType,
782 int messageType, Icon icon, Object[] options, Object initialValue,
785 showDialog(message, title, optionType, messageType, icon, options,
786 initialValue, modal, null);
789 public void showDialog(Object message, String title, int optionType,
790 int messageType, Icon icon, Object[] options, Object initialValue,
791 boolean modal, JButton[] buttons)
793 if (!isInteractiveMode())
795 handleResponse(getMockResponse());
801 // 1) AlignViewport for openLinkedAlignment
803 // Show a dialog with the option to open and link (cDNA <-> protein) as a
805 // alignment, either as a standalone alignment or in a split frame. Returns
806 // true if the new alignment was opened, false if not, because the user
807 // declined the offer.
809 // 2) UserDefinedColors warning about saving over a name already defined
812 ourOptions = Arrays.asList(options);
816 boolean useButtons = false;
817 Object initialValueButton = null;
818 NOTNULL: if (buttons != null)
820 if (buttons.length != options.length)
822 jalview.bin.Console.error(
823 "Supplied buttons array not the same length as supplied options array.");
826 int[] buttonActions = { JOptionPane.YES_OPTION,
827 JOptionPane.NO_OPTION, JOptionPane.CANCEL_OPTION };
828 for (int i = 0; i < options.length; i++)
830 Object o = options[i];
831 jalview.bin.Console.debug(
832 "Setting button " + i + " to '" + o.toString() + "'");
833 JButton jb = buttons[i];
835 if (o.equals(initialValue))
836 initialValueButton = jb;
838 int buttonAction = buttonActions[i];
839 Callable<Void> action = callbacks.get(buttonAction);
840 jb.setText((String) o);
841 jb.addActionListener(new ActionListener()
844 public void actionPerformed(ActionEvent e)
847 Object obj = e.getSource();
848 if (obj == null || !(obj instanceof Component))
850 jalview.bin.Console.debug(
851 "Could not find Component source of event object "
855 Object joptionpaneObject = SwingUtilities.getAncestorOfClass(
856 JOptionPane.class, (Component) obj);
857 if (joptionpaneObject == null
858 || !(joptionpaneObject instanceof JOptionPane))
860 jalview.bin.Console.debug(
861 "Could not find JOptionPane ancestor of event object "
865 JOptionPane joptionpane = (JOptionPane) joptionpaneObject;
866 joptionpane.setValue(buttonAction);
868 Executors.newSingleThreadExecutor().submit(action);
869 joptionpane.transferFocusBackward();
870 joptionpane.setVisible(false);
871 // put focus and raise parent window if possible, unless cancel or
873 boolean raiseParent = (parentComponent != null);
874 if (buttonAction == JOptionPane.CANCEL_OPTION)
876 if (optionType == JOptionPane.YES_NO_OPTION
877 && buttonAction == JOptionPane.NO_OPTION)
881 parentComponent.requestFocus();
882 if (parentComponent instanceof JInternalFrame)
884 JInternalFrame jif = (JInternalFrame) parentComponent;
889 else if (parentComponent instanceof Window)
891 Window w = (Window) parentComponent;
896 joptionpane.setVisible(false);
903 // use a JOptionPane as usual
904 int response = JOptionPane.showOptionDialog(parentComponent, message,
905 title, optionType, messageType, icon,
906 useButtons ? buttons : options,
907 useButtons ? initialValueButton : initialValue);
910 * In Java, the response is returned to this thread and handled here;
911 * (for Javascript, see propertyChange)
913 if (!Platform.isJS())
920 handleResponse(response);
926 * This is java similar to the swingjs handling, with the callbacks
927 * attached to the button press of the dialog. This means we can use
928 * a non-modal JDialog for the confirmation without blocking the GUI.
931 JDialog dialog = createDialog(parentComponent, message, title,
932 optionType, messageType, icon, options, initialValue, modal,
934 jalview.bin.Console.debug("About to setVisible(true)");
935 dialog.setVisible(true);
936 jalview.bin.Console.debug("Just setVisible(true)");
940 public void showInternalDialog(JPanel mainPanel, String title,
941 int yesNoCancelOption, int questionMessage, Icon icon,
942 Object[] options, String initresponse)
944 if (!isInteractiveMode())
946 handleResponse(getMockResponse());
949 ourOptions = Arrays.asList(options);
951 if (parentComponent != this)
953 response = JOptionPane.showInternalOptionDialog(parentComponent,
954 mainPanel, title, yesNoCancelOption, questionMessage, icon,
955 options, initresponse);
959 response = JOptionPane.showOptionDialog(parentComponent, mainPanel,
960 title, yesNoCancelOption, questionMessage, icon, options,
963 if (!Platform.isJS())
970 handleResponse(response);
976 public JvOptionPane setResponseHandler(Object response, Runnable action)
978 callbacks.put(response, new Callable<Void>()
991 public JvOptionPane setResponseHandler(Object response,
992 Callable<Void> action)
994 callbacks.put(response, action);
999 * showDialogOnTop will create a dialog that (attempts to) come to top of OS
1002 public static int showDialogOnTop(String label, String actionString,
1003 int JOPTIONPANE_OPTION, int JOPTIONPANE_MESSAGETYPE)
1005 // Ensure Jalview window is brought to front (primarily for Quit
1006 // confirmation window to be visible)
1008 // This method of raising the Jalview window is broken in java
1009 // jalviewDesktop.setVisible(true);
1010 // jalviewDesktop.toFront();
1012 // A better hack which works is to create a new JFrame parent with
1013 // setAlwaysOnTop(true)
1014 JFrame dialogParent = new JFrame();
1015 dialogParent.setAlwaysOnTop(true);
1017 int answer = JOptionPane.showConfirmDialog(dialogParent, label,
1018 actionString, JOPTIONPANE_OPTION, JOPTIONPANE_MESSAGETYPE);
1020 dialogParent.setAlwaysOnTop(false);
1021 dialogParent.dispose();
1026 public void showDialogOnTopAsync(String label, String actionString,
1027 int JOPTIONPANE_OPTION, int JOPTIONPANE_MESSAGETYPE, Icon icon,
1028 Object[] options, Object initialValue, boolean modal)
1030 showDialogOnTopAsync(new JFrame(), label, actionString,
1031 JOPTIONPANE_OPTION, JOPTIONPANE_MESSAGETYPE, icon, options,
1032 initialValue, modal);
1035 public void showDialogOnTopAsync(JFrame dialogParent, Object label,
1036 String actionString, int JOPTIONPANE_OPTION,
1037 int JOPTIONPANE_MESSAGETYPE, Icon icon, Object[] options,
1038 Object initialValue, boolean modal)
1040 showDialogOnTopAsync(dialogParent, label, actionString,
1041 JOPTIONPANE_OPTION, JOPTIONPANE_MESSAGETYPE, icon, options,
1042 initialValue, modal, null);
1045 public void showDialogOnTopAsync(JFrame dialogParent, Object label,
1046 String actionString, int JOPTIONPANE_OPTION,
1047 int JOPTIONPANE_MESSAGETYPE, Icon icon, Object[] options,
1048 Object initialValue, boolean modal, JButton[] buttons)
1050 // Ensure Jalview window is brought to front (primarily for Quit
1051 // confirmation window to be visible)
1053 // This method of raising the Jalview window is broken in java
1054 // jalviewDesktop.setVisible(true);
1055 // jalviewDesktop.toFront();
1057 // A better hack which works is to create a new JFrame parent with
1058 // setAlwaysOnTop(true)
1059 dialogParent.setAlwaysOnTop(true);
1060 parentComponent = dialogParent;
1062 showDialog(label, actionString, JOPTIONPANE_OPTION,
1063 JOPTIONPANE_MESSAGETYPE, icon, options, initialValue, modal,
1066 dialogParent.setAlwaysOnTop(false);
1067 dialogParent.dispose();
1071 * JalviewJS signals option selection by a property change event for the
1072 * option e.g. "OK". This methods responds to that by running the response
1073 * action that corresponds to that option.
1078 public void propertyChange(PropertyChangeEvent evt)
1080 Object newValue = evt.getNewValue();
1081 int ourOption = ourOptions.indexOf(newValue);
1084 handleResponse(ourOption);
1089 handleResponse(newValue);
1094 public void handleResponse(Object response)
1097 * this test is for NaN in Chrome
1099 if (response != null && !response.equals(response))
1103 Callable<Void> action = callbacks.get(response);
1109 } catch (Exception e)
1111 e.printStackTrace();
1113 if (parentComponent != null)
1114 parentComponent.requestFocus();
1119 * Create a non-modal confirm dialog
1121 public JDialog createDialog(Component parentComponent, Object message,
1122 String title, int optionType, int messageType, Icon icon,
1123 Object[] options, Object initialValue, boolean modal)
1125 return createDialog(parentComponent, message, title, optionType,
1126 messageType, icon, options, initialValue, modal, null);
1129 public JDialog createDialog(Component parentComponent, Object message,
1130 String title, int optionType, int messageType, Icon icon,
1131 Object[] options, Object initialValue, boolean modal,
1134 JButton[] optionsButtons = null;
1135 Object initialValueButton = null;
1136 JOptionPane joptionpane = new JOptionPane();
1137 // Make button options
1138 int[] buttonActions = { JOptionPane.YES_OPTION, JOptionPane.NO_OPTION,
1139 JOptionPane.CANCEL_OPTION };
1141 // we need the strings to make the buttons with actionEventListener
1142 if (options == null)
1144 ArrayList<String> options_default = new ArrayList<>();
1145 options_default.add(UIManager.getString("OptionPane.yesButtonText"));
1146 if (optionType == JOptionPane.YES_NO_OPTION
1147 || optionType == JOptionPane.YES_NO_CANCEL_OPTION)
1149 options_default.add(UIManager.getString("OptionPane.noButtonText"));
1151 if (optionType == JOptionPane.YES_NO_CANCEL_OPTION)
1154 .add(UIManager.getString("OptionPane.cancelButtonText"));
1156 options = options_default.toArray();
1158 if (!Platform.isJS()) // JalviewJS already uses callback, don't need to
1161 if (((optionType == JOptionPane.YES_OPTION
1162 || optionType == JOptionPane.NO_OPTION
1163 || optionType == JOptionPane.CANCEL_OPTION
1164 || optionType == JOptionPane.OK_OPTION
1165 || optionType == JOptionPane.DEFAULT_OPTION)
1166 && options.length < 1)
1167 || ((optionType == JOptionPane.YES_NO_OPTION
1168 || optionType == JOptionPane.OK_CANCEL_OPTION)
1169 && options.length < 2)
1170 || (optionType == JOptionPane.YES_NO_CANCEL_OPTION
1171 && options.length < 3))
1174 .debug("JvOptionPane: not enough options for dialog type");
1176 optionsButtons = new JButton[options.length];
1177 for (int i = 0; i < options.length && i < 3; i++)
1179 Object o = options[i];
1180 int buttonAction = buttonActions[i];
1181 Callable<Void> action = callbacks.get(buttonAction);
1183 if (buttons != null && buttons.length > i && buttons[i] != null)
1191 jb.setText((String) o);
1192 jb.addActionListener(new ActionListener()
1195 public void actionPerformed(ActionEvent e)
1197 joptionpane.setValue(buttonAction);
1199 Executors.newSingleThreadExecutor().submit(action);
1200 // joptionpane.transferFocusBackward();
1201 joptionpane.transferFocusBackward();
1202 joptionpane.setVisible(false);
1203 // put focus and raise parent window if possible, unless cancel
1205 boolean raiseParent = (parentComponent != null);
1206 if (buttonAction == JOptionPane.CANCEL_OPTION)
1207 raiseParent = false;
1208 if (optionType == JOptionPane.YES_NO_OPTION
1209 && buttonAction == JOptionPane.NO_OPTION)
1210 raiseParent = false;
1213 parentComponent.requestFocus();
1214 if (parentComponent instanceof JInternalFrame)
1216 JInternalFrame jif = (JInternalFrame) parentComponent;
1221 else if (parentComponent instanceof Window)
1223 Window w = (Window) parentComponent;
1228 joptionpane.setVisible(false);
1231 optionsButtons[i] = jb;
1232 if (o.equals(initialValue))
1233 initialValueButton = jb;
1236 joptionpane.setMessage(message);
1237 joptionpane.setMessageType(messageType);
1238 joptionpane.setOptionType(optionType);
1239 joptionpane.setIcon(icon);
1240 joptionpane.setOptions(Platform.isJS() ? options : optionsButtons);
1241 joptionpane.setInitialValue(
1242 Platform.isJS() ? initialValue : initialValueButton);
1244 JDialog dialog = joptionpane.createDialog(parentComponent, title);
1245 dialog.setModalityType(
1246 modal ? ModalityType.APPLICATION_MODAL : ModalityType.MODELESS);
1247 dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
1252 * Utility to programmatically click a button on a JOptionPane (as a JFrame)
1254 * returns true if button was found
1256 public static boolean clickButton(JFrame frame, int buttonType)