X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjavajs%2Fasync%2FAsyncDialog.java;fp=src%2Fjavajs%2Fasync%2FAsyncDialog.java;h=5752f4864ff1bed4ffec3853bc138adf435e02f9;hb=586ade46bdcd05ff028a1cff82c3c527326d28ec;hp=0000000000000000000000000000000000000000;hpb=adcef27f5747b4e70e89a56c3735bc3afb8ce9bf;p=jalview.git diff --git a/src/javajs/async/AsyncDialog.java b/src/javajs/async/AsyncDialog.java new file mode 100644 index 0000000..5752f48 --- /dev/null +++ b/src/javajs/async/AsyncDialog.java @@ -0,0 +1,282 @@ +package javajs.async; + +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.Icon; +import javax.swing.JOptionPane; +import javax.swing.plaf.UIResource; + +/** + * A class to manage asynchronous input, option, and confirmation dialogs. + * + * @author Bob Hanson hansonr_at_stolaf.edu + * + */ +public class AsyncDialog implements PropertyChangeListener { + +// see discussion in net.sf.j2s.core/doc/Differences.txt +// +// Confirmation dialog example. Note moving the parent component into the constructor. +// Original: +// +// private void promptQuit() { +// int sel = JOptionPane.showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION); +// switch (sel) { +// case JOptionPane.YES_OPTION: +// resultsTab.clean(); +// seqs.dispose(); +// if (fromMain) { +// System.exit(0); +// } +// break; +// } +// } +// +// revised: +// +// private void promptQuitAsync() { +// new AsyncDialog().showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION, new ActionListener() { +// +// @Override +// public void actionPerformed(ActionEvent e) { +// int sel = ((AsyncDialog)e.getSource()).getOption(); +// switch (sel) { +// case JOptionPane.YES_OPTION: +// resultsTab.clean(); +// seqs.dispose(); +// if (fromMain) { +// System.exit(0); +// } +// break; +// } +// }})); +// } + + + public AsyncDialog() { + } + + private ActionListener actionListener; + private Object choice; + private Object[] options; + private Object value; + private boolean wantsInput; + + // These options can be supplemented as desired. + + + /** + * Synchronous call; OK in JavaScript as long as we are using a JavaScript prompt() call + * + * @param frame + * @param msg + * @return + */ + @Deprecated + public static String showInputDialog(Component frame, String msg) { + return JOptionPane.showInputDialog(frame, msg); + } + + public void showInputDialog(Component frame, Object message, ActionListener a) { + setListener(a); + wantsInput = true; + process(JOptionPane.showInputDialog(frame, message)); + unsetListener(); + } + + public void showInputDialog(Component frame, Object message, String title, int messageType, Icon icon, + Object[] selectionValues, Object initialSelectionValue, ActionListener a) { + setListener(a); + wantsInput = true; + process(JOptionPane.showInputDialog(frame, message, title, messageType, icon, selectionValues, + initialSelectionValue)); + unsetListener(); + } + + public void showMessageDialog(Component frame, Object message, ActionListener a) { + setListener(a); + JOptionPane.showMessageDialog(frame, message); + unsetListener(); + if (/** @j2sNative false || */true) + process("" + message); + } + + public void showOptionDialog(Component frame, Object message, String title, int optionType, int messageType, + Icon icon, Object[] options, Object initialValue, ActionListener a) { + actionListener = a; + this.options = options; + setListener(a); + process(JOptionPane.showOptionDialog(frame, message, title, optionType, messageType, icon, options, + initialValue)); + unsetListener(); + } + + public void showConfirmDialog(Component frame, Object message, String title, ActionListener a) { + showConfirmDialog(frame, message, title, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, a); + } + + public void showConfirmDialog(Component frame, Object message, String title, int optionType, ActionListener a) { + showConfirmDialog(frame, message, title, optionType, JOptionPane.QUESTION_MESSAGE, a); + } + + public void showConfirmDialog(Component frame, Object message, String title, int optionType, int messageType, + ActionListener a) { + setListener(a); + process(JOptionPane.showConfirmDialog(frame, message, title, optionType, messageType)); + unsetListener(); + } + + /** + * retrieve selection from the ActionEvent, for which "this" is getSource() + * + * @return + */ + public Object getChoice() { + return choice; + } + + public int getOption() { + if (!(choice instanceof Integer)) { + throw new java.lang.IllegalArgumentException("AsyncDialog.getOption called for non-Integer choice"); + } + return ((Integer) choice).intValue(); + } + + /** + * A dialog option that allows for YES, NO, and CLOSE options via + * ActionListener. ActionEvent.getID() contains the reply. + * + * @param parent The parent component for the dialog + * @param message The text of the message to display + * @param title Optional title defaults to "Question" + * @param listener Handle options based on an ActionEvent + */ + public static void showYesNoAsync(Component parent, Object message, String title, ActionListener listener) { + new AsyncDialog().showConfirmDialog(parent, message, (title == null ? "Question" : title), + JOptionPane.YES_NO_OPTION, listener); + } + + /** + * A dialog option that involves just a YES follower. + * @param parent + * @param message + * @param title TODO + * @param yes + */ + public static void showYesAsync(Component parent, Object message, String title, Runnable yes) { + AsyncDialog.showYesNoAsync(parent, message, title, new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getID() == JOptionPane.YES_OPTION) { + yes.run(); + } + } + + }); + } + + /** + * A dialog option that involves just an OK follower. + * @param parent + * @param message + * @param title + * @param ok + */ + public static void showOKAsync(Component parent, Object message, String title, Runnable ok) { + new AsyncDialog().showConfirmDialog(parent, message, title, JOptionPane.OK_CANCEL_OPTION, new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getID() == JOptionPane.OK_OPTION) { + ok.run(); + } + } + + }); + } + + + private void setListener(ActionListener a) { + actionListener = a; + @SuppressWarnings("unused") + Class c = JOptionPane.class; // loads the class + /** @j2sNative c.$clazz$.listener = this */ + } + + private void unsetListener() { + /** @j2sNative javax.swing.JOptionPane.listener = null */ + } + + /** + * Switch from property change to action. + * + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + value = evt.getNewValue(); + switch (evt.getPropertyName()) { + case "inputValue": + process(value); + break; + case "value": + if (value != null && options == null && !(value instanceof Integer)) { + process(getOptionIndex(((JOptionPane) evt.getSource()).getOptions(), value)); + return; + } + if (options != null) { + int i = getOptionIndex(options, value); + value = Integer.valueOf(i >= 0 ? i : JOptionPane.CLOSED_OPTION); + } + process(value); + break; + } + } + + private int getOptionIndex(Object[] options, Object val) { + if (options != null) + for (int i = 0; i < options.length; i++) { + if (options[i] == val) + return i; + } + return -1; + } + + public Object getValue() { + if (wantsInput || options == null) + return value; + int val = ((Integer) value).intValue(); + return (val < 0 ? null : options[val]); + } + + private boolean processed; + + /** + * Return for confirm dialog. + * + * @param ret may be JavaScript NaN, testable as ret != ret or ret != - -ret + */ + private void process(int ret) { + if (ret != -(-ret) || processed) + return; + processed = true; + choice = ret; + actionListener.actionPerformed(new ActionEvent(this, ret, "SelectedOption")); + } + + private void process(Object ret) { + if (ret instanceof UIResource || processed) + return; + processed = true; + choice = ret; + actionListener.actionPerformed(new ActionEvent(this, + ret == null ? JOptionPane.CANCEL_OPTION : JOptionPane.OK_OPTION, + (ret == null ? null : ret.toString()))); + } + + +}