fiore@0: /*
fiore@0: CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
fiore@0:
fiore@0: Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
fiore@0:
fiore@0: This program is free software: you can redistribute it and/or modify
fiore@0: it under the terms of the GNU General Public License as published by
fiore@0: the Free Software Foundation, either version 3 of the License, or
fiore@0: (at your option) any later version.
fiore@0:
fiore@0: This program is distributed in the hope that it will be useful,
fiore@0: but WITHOUT ANY WARRANTY; without even the implied warranty of
fiore@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
fiore@0: GNU General Public License for more details.
fiore@0:
fiore@0: You should have received a copy of the GNU General Public License
fiore@0: along with this program. If not, see .
fiore@0: */
fiore@0:
fiore@0: package uk.ac.qmul.eecs.ccmi.gui;
fiore@0:
fiore@0: import java.awt.Color;
fiore@0: import java.awt.Component;
fiore@0: import java.awt.Frame;
fiore@0: import java.awt.GridLayout;
fiore@3: import java.awt.event.ActionEvent;
fiore@3: import java.awt.event.ActionListener;
fiore@0: import java.awt.event.InputEvent;
fiore@0: import java.awt.event.KeyEvent;
fiore@0: import java.awt.event.WindowAdapter;
fiore@0: import java.awt.event.WindowEvent;
fiore@0: import java.text.MessageFormat;
fiore@0: import java.util.LinkedHashSet;
fiore@0: import java.util.List;
fiore@0: import java.util.ResourceBundle;
fiore@0: import java.util.Set;
fiore@0:
fiore@3: import javax.swing.AbstractAction;
fiore@3: import javax.swing.JButton;
fiore@0: import javax.swing.JCheckBox;
fiore@0: import javax.swing.JComponent;
fiore@0: import javax.swing.JDialog;
fiore@0: import javax.swing.JFormattedTextField;
fiore@0: import javax.swing.JLabel;
fiore@0: import javax.swing.JOptionPane;
fiore@0: import javax.swing.JPanel;
fiore@0: import javax.swing.JProgressBar;
fiore@0: import javax.swing.JScrollPane;
fiore@0: import javax.swing.JSpinner;
fiore@0: import javax.swing.JTextArea;
fiore@0: import javax.swing.JTextField;
fiore@0: import javax.swing.KeyStroke;
fiore@0: import javax.swing.SwingWorker;
fiore@0: import javax.swing.event.ChangeEvent;
fiore@0: import javax.swing.event.ChangeListener;
fiore@0: import javax.swing.text.JTextComponent;
fiore@0:
fiore@0: import uk.ac.qmul.eecs.ccmi.sound.SoundEvent;
fiore@0: import uk.ac.qmul.eecs.ccmi.sound.SoundFactory;
fiore@3: import uk.ac.qmul.eecs.ccmi.speech.Narrator;
fiore@0: import uk.ac.qmul.eecs.ccmi.speech.NarratorFactory;
fiore@0: import uk.ac.qmul.eecs.ccmi.speech.SpeechUtilities;
fiore@0:
fiore@0: /**
fiore@0: *
fiore@3: * An option panel made out of an {@code Object} being displayed and to buttons: one for accepting and another one for
fiore@3: * cancelling the option.
fiore@3: * Furthermore, this class provides one-line calls to display accessible dialog boxes. Input by the user as well
fiore@3: * as focused components are spoken out through text to speech synthesis performed by a {@link Narrator} instance.
fiore@0: */
fiore@3: public class SpeechOptionPane {
fiore@3:
fiore@3: /**
fiore@3: * Construct a new {@code SpeechOptionPane} with no title. The title is displayed at the top of the dialog
fiore@3: * that is displayed after a call to {@code showDialog}
fiore@3: */
fiore@3: public SpeechOptionPane(){
fiore@3: this("");
fiore@3: }
fiore@3:
fiore@3: /**
fiore@3: * Construct a new {@code SpeechOptionPane} with no title. The title is displayed at the top of the dialog
fiore@3: * that is displayed after a call to {@code showDialog}
fiore@3: *
fiore@3: * @param title the String to be displayed
fiore@3: */
fiore@3: public SpeechOptionPane(String title){
fiore@3: this.title = title;
fiore@3: okButton = new JButton("OK");
fiore@3: cancelButton = new JButton("Cancel");
fiore@3: }
fiore@3:
fiore@3: /**
fiore@3: * Pops the a dialog holding this SpeechOptionPane
fiore@3: *
fiore@3: * @param parent the parent component of the dialog
fiore@5: * @param message the {@code Object} to display
fiore@3: * @return an integer indicating the option selected by the user
fiore@3: */
fiore@3: @SuppressWarnings("serial")
fiore@3: public int showDialog(Component parent,final Object message){
fiore@3: optPane = new JOptionPane();
fiore@3: optPane.setMessage(message);
fiore@3: /* Enter will entail a unique action, regardless the component that's focused */
fiore@3: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "closeDialog");
fiore@3: optPane.getActionMap().put("closeDialog", new AbstractAction(){
fiore@3: @Override
fiore@3: public void actionPerformed(ActionEvent evt) {
fiore@3: okButton.doClick();
fiore@3: }
fiore@3: });
fiore@3: optPane.setMessageType(JOptionPane.PLAIN_MESSAGE);
fiore@3: Object[] options = {
fiore@3: okButton,
fiore@3: cancelButton
fiore@3: };
fiore@3: optPane.setOptions(options);
fiore@3: /* ctrl key will hush the TTS */
fiore@3: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@3: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@3: final JDialog dialog = optPane.createDialog(parent, title);
fiore@5: dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
fiore@3: SpeechUtilities.changeTabListener(optPane,dialog);
fiore@3: /* when either button is pressed, dialog is disposed and the button itself becomes the optPane.value */
fiore@3: ActionListener buttonListener = new ActionListener(){
fiore@3: @Override
fiore@3: public void actionPerformed(ActionEvent evt) {
fiore@5: onClose(dialog,(JButton)evt.getSource());
fiore@3: }
fiore@3: };
fiore@3: okButton.addActionListener(buttonListener);
fiore@3: cancelButton.addActionListener(buttonListener);
fiore@3:
fiore@3: SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@3: dialog.setVisible(true);
fiore@3: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@3: if(okButton.equals(optPane.getValue())){
fiore@3: return OK_OPTION;
fiore@3: }else{
fiore@3: return CANCEL_OPTION;
fiore@3: }
fiore@3: }
fiore@3:
fiore@3: /**
fiore@3: * Sets the string appearing at the top of the dialog where this option pane is displayed when {@code showDialog}
fiore@3: * is called.
fiore@5: * @param title the title of this option pane
fiore@3: */
fiore@3: public void setDialogTitle(String title){
fiore@3: this.title = title;
fiore@3: }
fiore@3:
fiore@3: /**
fiore@3: * Returns the {@code JButton} that the user has to press (when the option pane is displayed after
fiore@3: * {@code showDialog} is called) in order to accept the option.
fiore@3: *
fiore@3: * @return a reference to the internal {@code JButton}
fiore@3: */
fiore@3: public JButton getOkButton(){
fiore@3: return okButton;
fiore@3: }
fiore@3:
fiore@3: /**
fiore@3: * Returns the {@code JButton} that the user has to press (when the option pane is displayed after
fiore@3: * {@code showDialog} is called) in order to reject the option.
fiore@3: *
fiore@3: * @return a reference to the internal {@code JButton}
fiore@3: */
fiore@3: public JButton getCancelButton(){
fiore@3: return cancelButton;
fiore@3: }
fiore@3:
fiore@3: /**
fiore@5: * This method is called just after the user presses either button of the dialog displayed
fiore@3: * after {@code showDialog} is called.
fiore@3: * It assign a value to the return value and it frees the dialog resources.
fiore@3: * It can be overwritten by subclasses but care should be taken of calling this class method via
fiore@3: * {@code super} in order to properly close the dialog.
fiore@3: *
fiore@3: * @param dialog the dialog displayed after {@code showDialog} is called.
fiore@3: * @param source the button that triggered the closing of {@code dialog}
fiore@3: */
fiore@5: protected void onClose(JDialog dialog, JButton source){
fiore@3: optPane.setValue(source);
fiore@3: dialog.dispose();
fiore@3: }
fiore@3:
fiore@3: private String title;
fiore@3: private JOptionPane optPane;
fiore@3: private JButton okButton;
fiore@3: private JButton cancelButton;
fiore@3:
fiore@3:
fiore@3: /* -------- STATIC METHODS ----------- */
fiore@0:
fiore@5: /**
fiore@5: * Shows a dialog with a text area requesting input for the user.
fiore@5: *
fiore@5: * @param parentComponent the parent {@code Component} for the dialog
fiore@5: * @param message a displayed in the dialog, such text is also uttered by the {@code Narrator}
fiore@5: * @param text the initial text the text area contains when the dialog is displayed
fiore@5: *
fiore@5: * @return the new text entered by the user
fiore@5: */
fiore@5: public static String showTextAreaDialog(Component parentComponent, String message, String text){
fiore@0: JTextArea textArea = new JTextArea(NOTES_TEXT_AREA_ROW_SIZE,NOTES_TEXT_AREA_COL_SIZE);
fiore@5: textArea.setText(text);
fiore@0: NarratorFactory.getInstance().speak(message);
fiore@0: return textComponentDialog(parentComponent, message, textArea);
fiore@0: }
fiore@0:
fiore@5: /**
fiore@5: * Shows a dialog with a text field requesting input from the user
fiore@5: *
fiore@5: * @param parentComponent the parent {@code Component} for the dialog
fiore@5: * @param message a message displayed in the dialog, such text is also uttered by the {@code Narrator}
fiore@5: * @param initialSelectionValue the initial text the text field contains when the dialog is displayed
fiore@5: *
fiore@5: * @return the text entered by the user
fiore@5: */
fiore@0: public static String showInputDialog(Component parentComponent, String message, String initialSelectionValue){
fiore@0: final JTextField textField = new JTextField(initialSelectionValue);
fiore@0: textField.selectAll();
fiore@0: NarratorFactory.getInstance().speak(message);
fiore@0: return textComponentDialog(parentComponent, message, textField);
fiore@0: }
fiore@0:
fiore@0: private static String textComponentDialog(Component parentComponent, String message, final JTextComponent textComponent){
fiore@0: Object componentToDisplay = textComponent;
fiore@0: if(textComponent instanceof JTextArea)
fiore@0: componentToDisplay = new JScrollPane(textComponent);
fiore@0:
fiore@0: Object[] displayObjects = { new JLabel(message), componentToDisplay };
fiore@0: final JOptionPane optPane = new JOptionPane();
fiore@0: optPane.setMessage(displayObjects);
fiore@0: optPane.setMessageType(QUESTION_MESSAGE);
fiore@0: optPane.setOptionType(OK_CANCEL_OPTION);
fiore@0: /* ctrl key will hush the TTS */
fiore@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@0: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@0:
fiore@0: final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.input"));
fiore@0: if(textComponent instanceof JTextArea)
fiore@0: dialog.setResizable(true);
fiore@0: dialog.addWindowFocusListener(new WindowAdapter(){
fiore@0: @Override
fiore@0: public void windowGainedFocus(WindowEvent e) {
fiore@0: textComponent.requestFocusInWindow();
fiore@0: }
fiore@0: });
fiore@0:
fiore@0: SpeechUtilities.changeTabListener(optPane,dialog);
fiore@0: textComponent.addKeyListener(SpeechUtilities.getSpeechKeyListener(true));
fiore@0: textComponent.setEditable(true);
fiore@0: // start the editing sound
fiore@0: SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@0: dialog.setVisible(true);
fiore@5: dialog.dispose();
fiore@0: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@0:
fiore@0: if(optPane.getValue() == null)//window closed
fiore@0: return null;
fiore@0: else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel
fiore@0: return null;
fiore@0: else{ // pressed on OK
fiore@0: return textComponent.getText().trim();
fiore@0: }
fiore@0: }
fiore@0:
fiore@5: /**
fiore@5: * Shows a dialog with a {@code JComboBox} requesting selection from the user
fiore@5: *
fiore@5: * @param parentComponent the parent {@code Component} for the dialog
fiore@5: * @param message a message displayed in the dialog, such text is also uttered by the {@code Narrator}
fiore@5: * @param options options for the {@code JComboBox}
fiore@5: * @param initialValue the options value selected when the dialog is shown
fiore@5: * @return the option selected by the user
fiore@5: */
fiore@0: public static Object showSelectionDialog(Component parentComponent, String message, Object[] options, Object initialValue){
fiore@0: final LoopComboBox comboBox = new LoopComboBox(options);
fiore@0: comboBox.setSelectedItem(initialValue);
fiore@0: Object[] displayObjects = { new JLabel(message), comboBox };
fiore@0: JOptionPane optPane = new JOptionPane();
fiore@0: optPane.setMessage(displayObjects);
fiore@0: optPane.setMessageType(QUESTION_MESSAGE);
fiore@0: optPane.setOptionType(OK_CANCEL_OPTION);
fiore@0: /* ctrl key will hush the TTS */
fiore@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@0: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@0:
fiore@0: NarratorFactory.getInstance().speak(message+", "+SpeechUtilities.getComponentSpeech(comboBox));
fiore@0: final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.select"));
fiore@0: dialog.addWindowFocusListener(new WindowAdapter(){
fiore@0: @Override
fiore@0: public void windowGainedFocus(WindowEvent e) {
fiore@0: comboBox.requestFocusInWindow();
fiore@0: }
fiore@0: });
fiore@0:
fiore@0: comboBox.addItemListener(SpeechUtilities.getSpeechComboBoxItemListener());
fiore@0:
fiore@0: SpeechUtilities.changeTabListener(optPane,dialog);
fiore@0: // start the editing sound
fiore@0: SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@0: dialog.setVisible(true);
fiore@5: dialog.dispose();
fiore@0: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@0: if(optPane.getValue() == null)//window closed
fiore@0: return null;
fiore@0: else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel )//pressed on cancel
fiore@0: return null;
fiore@0: else{ // pressed on OK
fiore@0: return comboBox.getSelectedItem();
fiore@0: }
fiore@0: }
fiore@0:
fiore@5: /**
fiore@5: * Shows the dialog with a {@code JSpinner} requesting the selection of the speech rate
fiore@5: * of the main voice of the {@code Narrator}
fiore@5: *
fiore@5: * @param parentComponent the parent {@code Component} for the dialog
fiore@5: * @param message a message displayed in the dialog, such text is also uttered by the {@code Narrator}
fiore@5: * @param value the initial value
fiore@5: * @param min the minimum value of the spinner
fiore@5: * @param max the maximum value of the spinner
fiore@5: * @return the selected integer value or {@code null} if the user cancels the dialog
fiore@5: */
fiore@0: public static Integer showNarratorRateDialog(Component parentComponent, String message, int value, int min, int max){
fiore@0: NarratorFactory.getInstance().speak(message);
fiore@0: final JSpinner spinner = new JSpinner(new LoopSpinnerNumberModel(value,min,max));
fiore@0: JFormattedTextField tf = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
fiore@0: tf.setEditable(false);
fiore@0: tf.setFocusable(false);
fiore@0: tf.setBackground(Color.white);
fiore@0:
fiore@0: Object[] displayObjects = { new JLabel(message), spinner};
fiore@0: final JOptionPane optPane = new JOptionPane();
fiore@0: optPane.setMessage(displayObjects);
fiore@0: optPane.setMessageType(QUESTION_MESSAGE);
fiore@0: optPane.setOptionType(OK_CANCEL_OPTION);
fiore@0: /* ctrl key will hush the TTS */
fiore@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@0: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@0:
fiore@0: final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.input"));
fiore@0: SpeechUtilities.changeTabListener(optPane,dialog);
fiore@0:
fiore@0: dialog.addWindowFocusListener(new WindowAdapter(){
fiore@0: @Override
fiore@0: public void windowGainedFocus(WindowEvent e) {
fiore@0: spinner.requestFocusInWindow();
fiore@0: }
fiore@0: });
fiore@0: spinner.addChangeListener(new ChangeListener(){
fiore@0: @Override
fiore@0: public void stateChanged(ChangeEvent evt) {
fiore@0: JSpinner s = (JSpinner)(evt.getSource());
fiore@0: NarratorFactory.getInstance().setRate((Integer)s.getValue());
fiore@0: NarratorFactory.getInstance().speak(s.getValue().toString());
fiore@0: }
fiore@0: });
fiore@0: // start the editing sound
fiore@0: SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@0: dialog.setVisible(true);
fiore@5: dialog.dispose();
fiore@0: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@0:
fiore@0: /* set the speech rate back to the value passed as argument */
fiore@0: NarratorFactory.getInstance().setRate(value);
fiore@0: if(optPane.getValue() == null)//window closed
fiore@0: return null;
fiore@0: else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel
fiore@0: return null;
fiore@0: else{ // pressed on OK
fiore@0: return (Integer)spinner.getValue();
fiore@0: }
fiore@0: }
fiore@0:
fiore@5: /**
fiore@5: * Brings up a dialog with selected options requesting user to confirmation.
fiore@5: *
fiore@5: * @param parentComponent the parent {@code Component} for the dialog
fiore@5: * @param message a message displayed in the dialog, such text is also uttered by the {@code Narrator}
fiore@5: * @param optionType an integer designating the options available on the dialog
fiore@5: * @return an integer indicating the option selected by the user
fiore@5: */
fiore@0: public static int showConfirmDialog(Component parentComponent, String message, int optionType){
fiore@0: NarratorFactory.getInstance().speak(message);
fiore@0: JOptionPane optPane = new JOptionPane();
fiore@0: optPane.setMessage(message);
fiore@0: optPane.setMessageType(QUESTION_MESSAGE);
fiore@0: optPane.setOptionType(optionType);
fiore@0: /* ctrl key will hush the TTS */
fiore@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@0: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@0:
fiore@0: JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.confirm"));
fiore@0: SpeechUtilities.changeTabListener(optPane,dialog);
fiore@0:
fiore@0: SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@0: dialog.setVisible(true);
fiore@5: dialog.dispose();
fiore@0: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@0:
fiore@0: if(optPane.getValue() == null)//window closed
fiore@0: return CANCEL_OPTION;
fiore@0: else
fiore@0: return ((Integer)optPane.getValue()).intValue();
fiore@0: }
fiore@0:
fiore@5: /**
fiore@5: * Displays a message to the user.
fiore@5: *
fiore@5: * @param parentComponent the parent {@code Component} for the dialog
fiore@5: * @param message the message displayed in the dialog, such text is also uttered by the {@code Narrator}
fiore@5: * @param messageType the type of message to be displayed
fiore@5: */
fiore@0: public static void showMessageDialog(Component parentComponent, String message, int messageType){
fiore@0: NarratorFactory.getInstance().speak(MessageFormat.format(resources.getString("dialog.speech_option_pane.message"), message));
fiore@0: JOptionPane optPane = new JOptionPane();
fiore@0: optPane.setMessage(message);
fiore@0: optPane.setMessageType(messageType);
fiore@0: /* ctrl key will hush the TTS */
fiore@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@0: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@0:
fiore@0: JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.confirm"));
fiore@0: SpeechUtilities.changeTabListener(optPane,dialog);
fiore@0: SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@0: dialog.setVisible(true);
fiore@5: dialog.dispose();
fiore@0: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@0: }
fiore@0:
fiore@5: /**
fiore@5: * Displays an error message to the user.
fiore@5: *
fiore@5: * @param parentComponent the parent {@code Component} for the dialog
fiore@5: * @param message the message displayed in the dialog, such text is also uttered by the {@code Narrator}
fiore@5: */
fiore@0: public static void showMessageDialog(Component parentComponent, String message){
fiore@0: showMessageDialog(parentComponent,message,ERROR_MESSAGE);
fiore@0: }
fiore@0:
fiore@5: /**
fiore@5: * Execute a ProgressDialogWorker task and
fiore@5: * shows an indeterminate progress bar dialog if the task is not completed after
fiore@5: * {@code millisToDecideToPopup}. The user can use the dialog cancel button
fiore@5: * to cancel the task.
fiore@5: *
fiore@5: * @param the result type returned by the worker
fiore@5: * @param the intermediate result type of the worker
fiore@5: * @param parentComponent the parent {@code Component} for the dialog
fiore@5: * @param message message a message displayed in the dialog, such text is also uttered by the {@code Narrator}
fiore@5: * @param worker a {@code ProgressDialogWorker} that is executed when this method is called
fiore@5: * @param millisToDecideToPopup the millisecond to let to the worker before popping the dialog up
fiore@5: * @return an integer indicating whether the task was completed or it was interrupted by the user
fiore@5: */
fiore@0: public static int showProgressDialog(Component parentComponent, String message,final ProgressDialogWorker worker, int millisToDecideToPopup){
fiore@3: JProgressBar progressBar = worker.bar;
fiore@0: Object displayObjects[] = {message, progressBar};
fiore@0: final JOptionPane optPane = new JOptionPane(displayObjects);
fiore@0: optPane.setOptionType(DEFAULT_OPTION);
fiore@0: optPane.setOptions(new Object[] {PROGRESS_DIALOG_CANCEL_OPTION});
fiore@0: /* ctrl key will hush the TTS */
fiore@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@0: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@0:
fiore@0: final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.download"));
fiore@0: SpeechUtilities.changeTabListener(optPane,dialog);
fiore@0:
fiore@0: worker.setDialog(dialog);
fiore@0: worker.execute();
fiore@0: try {
fiore@0: Thread.sleep(millisToDecideToPopup);
fiore@0: } catch (InterruptedException ie) {
fiore@0: throw new RuntimeException(ie); //should never happen
fiore@0: }
fiore@0: if(worker.isDone())
fiore@0: return OK_OPTION;
fiore@0:
fiore@0: NarratorFactory.getInstance().speak(message);
fiore@0: SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@0: dialog.setVisible(true);
fiore@0: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@0: if( optPane.getValue() == null ||
fiore@0: optPane.getValue() == PROGRESS_DIALOG_CANCEL_OPTION ||
fiore@0: Integer.valueOf(CLOSED_OPTION).equals(optPane.getValue())){
fiore@0: worker.cancel(true);
fiore@0: return CANCEL_OPTION;
fiore@0: }
fiore@0: return OK_OPTION;
fiore@0: }
fiore@0:
fiore@5: /**
fiore@5: * Shows a check box dialog to select the modifiers of a given property
fiore@5: *
fiore@5: * @param parentComponent the parent {@code Component} for the dialog
fiore@5: * @param message message a message displayed in the dialog, such text is also uttered by the {@code Narrator}
fiore@5: * @param modifierTypes the different types of modifiers that are available for a given property
fiore@5: * @param modifierIndexes the initial selection of modifiers as the dialog is shown
fiore@5: * @return a new set with the modifier indexes selected by the user
fiore@5: */
fiore@0: public static Set showModifiersDialog(Component parentComponent, String message, List modifierTypes, Set modifierIndexes){
fiore@0: JOptionPane optPane = new JOptionPane();
fiore@0:
fiore@0: JPanel checkBoxPanel = new JPanel(new GridLayout(0, 1));
fiore@0: final JCheckBox[] checkBoxes = new JCheckBox[modifierTypes.size()];
fiore@0: for(int i=0;i returnSet = new LinkedHashSet();
fiore@0: for(int i=0;i the result type returned by this {@code SwingWorker}'s {@code doInBackground} and {@code get} methods
fiore@5: * @param the type used for carrying out intermediate results by this {@code SwingWorker}'s {@code publish} and {@code process} methods
fiore@5: */
fiore@0: public static abstract class ProgressDialogWorker extends SwingWorker {
fiore@5: /**
fiore@5: * Creates a new ProgressDialogWorker
fiore@5: */
fiore@3: public ProgressDialogWorker(){
fiore@3: bar = new JProgressBar();
fiore@3: bar.setIndeterminate(true);
fiore@3: }
fiore@3:
fiore@0: private void setDialog(JDialog dialog){
fiore@0: this.dialog = dialog;
fiore@0: }
fiore@0:
fiore@0: @Override
fiore@3: protected void done() { //executed in EDT when the work is done
fiore@0: if(dialog != null)
fiore@0: dialog.dispose();
fiore@0: }
fiore@0:
fiore@0: private JDialog dialog;
fiore@5: private JProgressBar bar;
fiore@0: }
fiore@0:
fiore@0:
fiore@0: }