annotate java/src/uk/ac/qmul/eecs/ccmi/gui/SpeechOptionPane.java @ 4:2c67ac862920

bug fix (correct haptic painting after renaming nodes and after nodes deletion with an edge with more than 2 nodes)
author Fiore Martin <fiore@eecs.qmul.ac.uk>
date Tue, 29 May 2012 15:32:19 +0100
parents 9e67171477bc
children d66dd5880081
rev   line source
fiore@0 1 /*
fiore@0 2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
fiore@0 3
fiore@0 4 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
fiore@0 5
fiore@0 6 This program is free software: you can redistribute it and/or modify
fiore@0 7 it under the terms of the GNU General Public License as published by
fiore@0 8 the Free Software Foundation, either version 3 of the License, or
fiore@0 9 (at your option) any later version.
fiore@0 10
fiore@0 11 This program is distributed in the hope that it will be useful,
fiore@0 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
fiore@0 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
fiore@0 14 GNU General Public License for more details.
fiore@0 15
fiore@0 16 You should have received a copy of the GNU General Public License
fiore@0 17 along with this program. If not, see <http://www.gnu.org/licenses/>.
fiore@0 18 */
fiore@0 19
fiore@0 20 package uk.ac.qmul.eecs.ccmi.gui;
fiore@0 21
fiore@0 22 import java.awt.Color;
fiore@0 23 import java.awt.Component;
fiore@0 24 import java.awt.Frame;
fiore@0 25 import java.awt.GridLayout;
fiore@3 26 import java.awt.event.ActionEvent;
fiore@3 27 import java.awt.event.ActionListener;
fiore@0 28 import java.awt.event.InputEvent;
fiore@0 29 import java.awt.event.KeyEvent;
fiore@0 30 import java.awt.event.WindowAdapter;
fiore@0 31 import java.awt.event.WindowEvent;
fiore@0 32 import java.text.MessageFormat;
fiore@0 33 import java.util.LinkedHashSet;
fiore@0 34 import java.util.List;
fiore@0 35 import java.util.ResourceBundle;
fiore@0 36 import java.util.Set;
fiore@0 37
fiore@3 38 import javax.swing.AbstractAction;
fiore@3 39 import javax.swing.JButton;
fiore@0 40 import javax.swing.JCheckBox;
fiore@0 41 import javax.swing.JComponent;
fiore@0 42 import javax.swing.JDialog;
fiore@0 43 import javax.swing.JFormattedTextField;
fiore@0 44 import javax.swing.JLabel;
fiore@0 45 import javax.swing.JOptionPane;
fiore@0 46 import javax.swing.JPanel;
fiore@0 47 import javax.swing.JProgressBar;
fiore@0 48 import javax.swing.JScrollPane;
fiore@0 49 import javax.swing.JSpinner;
fiore@0 50 import javax.swing.JTextArea;
fiore@0 51 import javax.swing.JTextField;
fiore@0 52 import javax.swing.KeyStroke;
fiore@0 53 import javax.swing.SwingWorker;
fiore@0 54 import javax.swing.event.ChangeEvent;
fiore@0 55 import javax.swing.event.ChangeListener;
fiore@0 56 import javax.swing.text.JTextComponent;
fiore@0 57
fiore@0 58 import uk.ac.qmul.eecs.ccmi.sound.SoundEvent;
fiore@0 59 import uk.ac.qmul.eecs.ccmi.sound.SoundFactory;
fiore@3 60 import uk.ac.qmul.eecs.ccmi.speech.Narrator;
fiore@0 61 import uk.ac.qmul.eecs.ccmi.speech.NarratorFactory;
fiore@0 62 import uk.ac.qmul.eecs.ccmi.speech.SpeechUtilities;
fiore@0 63
fiore@0 64 /**
fiore@0 65 *
fiore@3 66 * An option panel made out of an {@code Object} being displayed and to buttons: one for accepting and another one for
fiore@3 67 * cancelling the option.
fiore@3 68 * Furthermore, this class provides one-line calls to display accessible dialog boxes. Input by the user as well
fiore@3 69 * as focused components are spoken out through text to speech synthesis performed by a {@link Narrator} instance.
fiore@3 70 *
fiore@0 71 *
fiore@0 72 */
fiore@3 73 public class SpeechOptionPane {
fiore@3 74
fiore@3 75 /**
fiore@3 76 * Construct a new {@code SpeechOptionPane} with no title. The title is displayed at the top of the dialog
fiore@3 77 * that is displayed after a call to {@code showDialog}
fiore@3 78 */
fiore@3 79 public SpeechOptionPane(){
fiore@3 80 this("");
fiore@3 81 }
fiore@3 82
fiore@3 83 /**
fiore@3 84 * Construct a new {@code SpeechOptionPane} with no title. The title is displayed at the top of the dialog
fiore@3 85 * that is displayed after a call to {@code showDialog}
fiore@3 86 *
fiore@3 87 * @param title the String to be displayed
fiore@3 88 */
fiore@3 89 public SpeechOptionPane(String title){
fiore@3 90 this.title = title;
fiore@3 91 okButton = new JButton("OK");
fiore@3 92 cancelButton = new JButton("Cancel");
fiore@3 93 }
fiore@3 94
fiore@3 95 /**
fiore@3 96 * Pops the a dialog holding this SpeechOptionPane
fiore@3 97 *
fiore@3 98 * @param parent the parent component of the dialog
fiore@3 99 * @param the {@code Object} to display
fiore@3 100 * @return an integer indicating the option selected by the user
fiore@3 101 */
fiore@3 102 @SuppressWarnings("serial")
fiore@3 103 public int showDialog(Component parent,final Object message){
fiore@3 104 optPane = new JOptionPane();
fiore@3 105 optPane.setMessage(message);
fiore@3 106 /* Enter will entail a unique action, regardless the component that's focused */
fiore@3 107 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "closeDialog");
fiore@3 108 optPane.getActionMap().put("closeDialog", new AbstractAction(){
fiore@3 109 @Override
fiore@3 110 public void actionPerformed(ActionEvent evt) {
fiore@3 111 okButton.doClick();
fiore@3 112 }
fiore@3 113 });
fiore@3 114 optPane.setMessageType(JOptionPane.PLAIN_MESSAGE);
fiore@3 115 Object[] options = {
fiore@3 116 okButton,
fiore@3 117 cancelButton
fiore@3 118 };
fiore@3 119 optPane.setOptions(options);
fiore@3 120 /* ctrl key will hush the TTS */
fiore@3 121 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@3 122 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@3 123 final JDialog dialog = optPane.createDialog(parent, title);
fiore@3 124 SpeechUtilities.changeTabListener(optPane,dialog);
fiore@3 125 /* when either button is pressed, dialog is disposed and the button itself becomes the optPane.value */
fiore@3 126 ActionListener buttonListener = new ActionListener(){
fiore@3 127 @Override
fiore@3 128 public void actionPerformed(ActionEvent evt) {
fiore@3 129 onClose(dialog,message,(JButton)evt.getSource());
fiore@3 130 }
fiore@3 131 };
fiore@3 132 okButton.addActionListener(buttonListener);
fiore@3 133 cancelButton.addActionListener(buttonListener);
fiore@3 134
fiore@3 135 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@3 136 dialog.setVisible(true);
fiore@3 137 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@3 138 dialog.dispose();
fiore@3 139 if(okButton.equals(optPane.getValue())){
fiore@3 140 return OK_OPTION;
fiore@3 141 }else{
fiore@3 142 return CANCEL_OPTION;
fiore@3 143 }
fiore@3 144 }
fiore@3 145
fiore@3 146 /**
fiore@3 147 * Sets the string appearing at the top of the dialog where this option pane is displayed when {@code showDialog}
fiore@3 148 * is called.
fiore@3 149 * @param title
fiore@3 150 */
fiore@3 151 public void setDialogTitle(String title){
fiore@3 152 this.title = title;
fiore@3 153 }
fiore@3 154
fiore@3 155 /**
fiore@3 156 * Returns the {@code JButton} that the user has to press (when the option pane is displayed after
fiore@3 157 * {@code showDialog} is called) in order to accept the option.
fiore@3 158 *
fiore@3 159 * @return a reference to the internal {@code JButton}
fiore@3 160 */
fiore@3 161 public JButton getOkButton(){
fiore@3 162 return okButton;
fiore@3 163 }
fiore@3 164
fiore@3 165 /**
fiore@3 166 * Returns the {@code JButton} that the user has to press (when the option pane is displayed after
fiore@3 167 * {@code showDialog} is called) in order to reject the option.
fiore@3 168 *
fiore@3 169 * @return a reference to the internal {@code JButton}
fiore@3 170 */
fiore@3 171 public JButton getCancelButton(){
fiore@3 172 return cancelButton;
fiore@3 173 }
fiore@3 174
fiore@3 175 /**
fiore@3 176 * This method is called just after the user pressed either button of the dialog displayed
fiore@3 177 * after {@code showDialog} is called.
fiore@3 178 * It assign a value to the return value and it frees the dialog resources.
fiore@3 179 * It can be overwritten by subclasses but care should be taken of calling this class method via
fiore@3 180 * {@code super} in order to properly close the dialog.
fiore@3 181 *
fiore@3 182 * @param dialog the dialog displayed after {@code showDialog} is called.
fiore@3 183 * @param message
fiore@3 184 * @param source the button that triggered the closing of {@code dialog}
fiore@3 185 */
fiore@3 186 protected void onClose(JDialog dialog,Object message, JButton source){
fiore@3 187 optPane.setValue(source);
fiore@3 188 dialog.dispose();
fiore@3 189 }
fiore@3 190
fiore@3 191 private String title;
fiore@3 192 private JOptionPane optPane;
fiore@3 193 private JButton okButton;
fiore@3 194 private JButton cancelButton;
fiore@3 195
fiore@3 196
fiore@3 197 /* -------- STATIC METHODS ----------- */
fiore@0 198
fiore@0 199 public static String showTextAreaDialog(Component parentComponent, String message, String initialSelectionValue){
fiore@0 200 JTextArea textArea = new JTextArea(NOTES_TEXT_AREA_ROW_SIZE,NOTES_TEXT_AREA_COL_SIZE);
fiore@0 201 textArea.setText(initialSelectionValue);
fiore@0 202 NarratorFactory.getInstance().speak(message);
fiore@0 203 return textComponentDialog(parentComponent, message, textArea);
fiore@0 204 }
fiore@0 205
fiore@0 206 public static String showInputDialog(Component parentComponent, String message, String initialSelectionValue){
fiore@0 207 final JTextField textField = new JTextField(initialSelectionValue);
fiore@0 208 textField.selectAll();
fiore@0 209 NarratorFactory.getInstance().speak(message);
fiore@0 210 return textComponentDialog(parentComponent, message, textField);
fiore@0 211 }
fiore@0 212
fiore@0 213 private static String textComponentDialog(Component parentComponent, String message, final JTextComponent textComponent){
fiore@0 214 Object componentToDisplay = textComponent;
fiore@0 215 if(textComponent instanceof JTextArea)
fiore@0 216 componentToDisplay = new JScrollPane(textComponent);
fiore@0 217
fiore@0 218 Object[] displayObjects = { new JLabel(message), componentToDisplay };
fiore@0 219 final JOptionPane optPane = new JOptionPane();
fiore@0 220 optPane.setMessage(displayObjects);
fiore@0 221 optPane.setMessageType(QUESTION_MESSAGE);
fiore@0 222 optPane.setOptionType(OK_CANCEL_OPTION);
fiore@0 223 /* ctrl key will hush the TTS */
fiore@0 224 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@0 225 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@0 226
fiore@0 227 final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.input"));
fiore@0 228 if(textComponent instanceof JTextArea)
fiore@0 229 dialog.setResizable(true);
fiore@0 230 dialog.addWindowFocusListener(new WindowAdapter(){
fiore@0 231 @Override
fiore@0 232 public void windowGainedFocus(WindowEvent e) {
fiore@0 233 textComponent.requestFocusInWindow();
fiore@0 234 }
fiore@0 235 });
fiore@0 236
fiore@0 237 SpeechUtilities.changeTabListener(optPane,dialog);
fiore@0 238 textComponent.addKeyListener(SpeechUtilities.getSpeechKeyListener(true));
fiore@0 239 textComponent.setEditable(true);
fiore@0 240 // start the editing sound
fiore@0 241 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@0 242 dialog.setVisible(true);
fiore@0 243 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@0 244
fiore@0 245 if(optPane.getValue() == null)//window closed
fiore@0 246 return null;
fiore@0 247 else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel
fiore@0 248 return null;
fiore@0 249 else{ // pressed on OK
fiore@0 250 return textComponent.getText().trim();
fiore@0 251 }
fiore@0 252 }
fiore@0 253
fiore@0 254 public static String showInputDialog(Component parentComponent, String message){
fiore@0 255 return showInputDialog(parentComponent, message, "");
fiore@0 256 }
fiore@0 257
fiore@0 258 public static Object showSelectionDialog(Component parentComponent, String message, Object[] options, Object initialValue){
fiore@0 259 final LoopComboBox comboBox = new LoopComboBox(options);
fiore@0 260 comboBox.setSelectedItem(initialValue);
fiore@0 261 Object[] displayObjects = { new JLabel(message), comboBox };
fiore@0 262 JOptionPane optPane = new JOptionPane();
fiore@0 263 optPane.setMessage(displayObjects);
fiore@0 264 optPane.setMessageType(QUESTION_MESSAGE);
fiore@0 265 optPane.setOptionType(OK_CANCEL_OPTION);
fiore@0 266 /* ctrl key will hush the TTS */
fiore@0 267 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@0 268 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@0 269
fiore@0 270 NarratorFactory.getInstance().speak(message+", "+SpeechUtilities.getComponentSpeech(comboBox));
fiore@0 271 final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.select"));
fiore@0 272 dialog.addWindowFocusListener(new WindowAdapter(){
fiore@0 273 @Override
fiore@0 274 public void windowGainedFocus(WindowEvent e) {
fiore@0 275 comboBox.requestFocusInWindow();
fiore@0 276 }
fiore@0 277 });
fiore@0 278
fiore@0 279 comboBox.addItemListener(SpeechUtilities.getSpeechComboBoxItemListener());
fiore@0 280
fiore@0 281 SpeechUtilities.changeTabListener(optPane,dialog);
fiore@0 282 // start the editing sound
fiore@0 283 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@0 284 dialog.setVisible(true);
fiore@0 285 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@0 286 if(optPane.getValue() == null)//window closed
fiore@0 287 return null;
fiore@0 288 else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel )//pressed on cancel
fiore@0 289 return null;
fiore@0 290 else{ // pressed on OK
fiore@0 291 return comboBox.getSelectedItem();
fiore@0 292 }
fiore@0 293 }
fiore@0 294
fiore@0 295 public static Integer showNarratorRateDialog(Component parentComponent, String message, int value, int min, int max){
fiore@0 296 NarratorFactory.getInstance().speak(message);
fiore@0 297 final JSpinner spinner = new JSpinner(new LoopSpinnerNumberModel(value,min,max));
fiore@0 298 JFormattedTextField tf = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
fiore@0 299 tf.setEditable(false);
fiore@0 300 tf.setFocusable(false);
fiore@0 301 tf.setBackground(Color.white);
fiore@0 302
fiore@0 303 Object[] displayObjects = { new JLabel(message), spinner};
fiore@0 304 final JOptionPane optPane = new JOptionPane();
fiore@0 305 optPane.setMessage(displayObjects);
fiore@0 306 optPane.setMessageType(QUESTION_MESSAGE);
fiore@0 307 optPane.setOptionType(OK_CANCEL_OPTION);
fiore@0 308 /* ctrl key will hush the TTS */
fiore@0 309 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@0 310 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@0 311
fiore@0 312 final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.input"));
fiore@0 313 SpeechUtilities.changeTabListener(optPane,dialog);
fiore@0 314
fiore@0 315 dialog.addWindowFocusListener(new WindowAdapter(){
fiore@0 316 @Override
fiore@0 317 public void windowGainedFocus(WindowEvent e) {
fiore@0 318 spinner.requestFocusInWindow();
fiore@0 319 }
fiore@0 320 });
fiore@0 321 spinner.addChangeListener(new ChangeListener(){
fiore@0 322 @Override
fiore@0 323 public void stateChanged(ChangeEvent evt) {
fiore@0 324 JSpinner s = (JSpinner)(evt.getSource());
fiore@0 325 NarratorFactory.getInstance().setRate((Integer)s.getValue());
fiore@0 326 NarratorFactory.getInstance().speak(s.getValue().toString());
fiore@0 327 }
fiore@0 328 });
fiore@0 329 // start the editing sound
fiore@0 330 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@0 331 dialog.setVisible(true);
fiore@0 332 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@0 333
fiore@0 334 /* set the speech rate back to the value passed as argument */
fiore@0 335 NarratorFactory.getInstance().setRate(value);
fiore@0 336 if(optPane.getValue() == null)//window closed
fiore@0 337 return null;
fiore@0 338 else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel
fiore@0 339 return null;
fiore@0 340 else{ // pressed on OK
fiore@0 341 return (Integer)spinner.getValue();
fiore@0 342 }
fiore@0 343 }
fiore@0 344
fiore@0 345 public static int showConfirmDialog(Component parentComponent, String message, int optionType){
fiore@0 346 NarratorFactory.getInstance().speak(message);
fiore@0 347 JOptionPane optPane = new JOptionPane();
fiore@0 348 optPane.setMessage(message);
fiore@0 349 optPane.setMessageType(QUESTION_MESSAGE);
fiore@0 350 optPane.setOptionType(optionType);
fiore@0 351 /* ctrl key will hush the TTS */
fiore@0 352 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@0 353 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@0 354
fiore@0 355 JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.confirm"));
fiore@0 356 SpeechUtilities.changeTabListener(optPane,dialog);
fiore@0 357
fiore@0 358 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@0 359 dialog.setVisible(true);
fiore@0 360 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@0 361
fiore@0 362 if(optPane.getValue() == null)//window closed
fiore@0 363 return CANCEL_OPTION;
fiore@0 364 else
fiore@0 365 return ((Integer)optPane.getValue()).intValue();
fiore@0 366 }
fiore@0 367
fiore@0 368 public static void showMessageDialog(Component parentComponent, String message, int messageType){
fiore@0 369 NarratorFactory.getInstance().speak(MessageFormat.format(resources.getString("dialog.speech_option_pane.message"), message));
fiore@0 370 JOptionPane optPane = new JOptionPane();
fiore@0 371 optPane.setMessage(message);
fiore@0 372 optPane.setMessageType(messageType);
fiore@0 373 /* ctrl key will hush the TTS */
fiore@0 374 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@0 375 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@0 376
fiore@0 377 JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.confirm"));
fiore@0 378 SpeechUtilities.changeTabListener(optPane,dialog);
fiore@0 379 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@0 380 dialog.setVisible(true);
fiore@0 381 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@0 382 }
fiore@0 383
fiore@0 384 public static void showMessageDialog(Component parentComponent, String message){
fiore@0 385 showMessageDialog(parentComponent,message,ERROR_MESSAGE);
fiore@0 386 }
fiore@0 387
fiore@0 388 public static <T,V> int showProgressDialog(Component parentComponent, String message,final ProgressDialogWorker<T,V> worker, int millisToDecideToPopup){
fiore@3 389 JProgressBar progressBar = worker.bar;
fiore@0 390 Object displayObjects[] = {message, progressBar};
fiore@0 391 final JOptionPane optPane = new JOptionPane(displayObjects);
fiore@0 392 optPane.setOptionType(DEFAULT_OPTION);
fiore@0 393 optPane.setOptions(new Object[] {PROGRESS_DIALOG_CANCEL_OPTION});
fiore@0 394 /* ctrl key will hush the TTS */
fiore@0 395 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@0 396 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@0 397
fiore@0 398 final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.download"));
fiore@0 399 SpeechUtilities.changeTabListener(optPane,dialog);
fiore@0 400
fiore@0 401 worker.setDialog(dialog);
fiore@0 402 worker.execute();
fiore@0 403 try {
fiore@0 404 Thread.sleep(millisToDecideToPopup);
fiore@0 405 } catch (InterruptedException ie) {
fiore@0 406 throw new RuntimeException(ie); //should never happen
fiore@0 407 }
fiore@0 408 if(worker.isDone())
fiore@0 409 return OK_OPTION;
fiore@0 410
fiore@0 411 NarratorFactory.getInstance().speak(message);
fiore@0 412 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@0 413 dialog.setVisible(true);
fiore@0 414 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@0 415 if( optPane.getValue() == null ||
fiore@0 416 optPane.getValue() == PROGRESS_DIALOG_CANCEL_OPTION ||
fiore@0 417 Integer.valueOf(CLOSED_OPTION).equals(optPane.getValue())){
fiore@0 418 worker.cancel(true);
fiore@0 419 return CANCEL_OPTION;
fiore@0 420 }
fiore@0 421 return OK_OPTION;
fiore@0 422 }
fiore@0 423
fiore@0 424 public static Set<Integer> showModifiersDialog(Component parentComponent, String message, List<String> modifierTypes, Set<Integer> modifierIndexes){
fiore@0 425 JOptionPane optPane = new JOptionPane();
fiore@0 426
fiore@0 427 JPanel checkBoxPanel = new JPanel(new GridLayout(0, 1));
fiore@0 428 final JCheckBox[] checkBoxes = new JCheckBox[modifierTypes.size()];
fiore@0 429 for(int i=0;i<checkBoxes.length;i++){
fiore@0 430 checkBoxes[i] = new JCheckBox(modifierTypes.get(i));
fiore@0 431 if(modifierIndexes.contains(i))
fiore@0 432 checkBoxes[i].setSelected(true);
fiore@0 433 checkBoxPanel.add(checkBoxes[i]);
fiore@0 434 checkBoxes[i].addItemListener(SpeechUtilities.getCheckBoxSpeechItemListener());
fiore@0 435 }
fiore@0 436 NarratorFactory.getInstance().speak(message+" "+SpeechUtilities.getComponentSpeech(checkBoxes[0]));
fiore@0 437
fiore@0 438 Object[] displayObjects = {new JLabel(message),checkBoxPanel};
fiore@0 439 optPane.setMessage(displayObjects);
fiore@0 440 optPane.setMessageType(QUESTION_MESSAGE);
fiore@0 441 optPane.setOptionType(OK_CANCEL_OPTION);
fiore@0 442 /* ctrl key will hush the TTS */
fiore@0 443 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
fiore@0 444 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
fiore@0 445 JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.modifiers"));
fiore@0 446 SpeechUtilities.changeTabListener(optPane,dialog);
fiore@0 447
fiore@0 448 dialog.addWindowFocusListener(new WindowAdapter(){
fiore@0 449 @Override
fiore@0 450 public void windowGainedFocus(WindowEvent e) {
fiore@0 451 checkBoxes[0].requestFocusInWindow();
fiore@0 452 }
fiore@0 453 });
fiore@0 454
fiore@0 455 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
fiore@0 456 dialog.setVisible(true);
fiore@0 457 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
fiore@0 458
fiore@0 459 if(optPane.getValue() == null)//window closed
fiore@0 460 return null;
fiore@0 461 else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel
fiore@0 462 return null;
fiore@0 463 else{ // pressed on OK
fiore@0 464 Set<Integer> returnSet = new LinkedHashSet<Integer>();
fiore@0 465 for(int i=0;i<checkBoxes.length;i++)
fiore@0 466 if(checkBoxes[i].isSelected())
fiore@0 467 returnSet.add(i);
fiore@0 468 return returnSet;
fiore@0 469 }
fiore@0 470 }
fiore@0 471
fiore@0 472 public static Frame getFrameForComponent(Component parentComponent){
fiore@0 473 return JOptionPane.getFrameForComponent(parentComponent);
fiore@0 474 }
fiore@0 475
fiore@0 476 private static ResourceBundle resources = ResourceBundle.getBundle(EditorFrame.class.getName());
fiore@0 477 private static final int NOTES_TEXT_AREA_COL_SIZE = 10;
fiore@0 478 private static final int NOTES_TEXT_AREA_ROW_SIZE = 10;
fiore@0 479 private static final String PROGRESS_DIALOG_CANCEL_OPTION = resources.getString("dialog.speech_option_pane.cancel");
fiore@0 480
fiore@0 481
fiore@0 482 public static final int QUESTION_MESSAGE = JOptionPane.QUESTION_MESSAGE;
fiore@0 483 public static final int ERROR_MESSAGE = JOptionPane.ERROR_MESSAGE;
fiore@0 484 public static final int INFORMATION_MESSAGE = JOptionPane.INFORMATION_MESSAGE;
fiore@0 485 public static final int WARNING_MESSAGE = JOptionPane.WARNING_MESSAGE;
fiore@0 486 public static final int OK_CANCEL_OPTION = JOptionPane.OK_CANCEL_OPTION;
fiore@0 487 public static final int CANCEL_OPTION = JOptionPane.CANCEL_OPTION;
fiore@0 488 public static final int OK_OPTION = JOptionPane.OK_OPTION;
fiore@0 489 public static final int CLOSED_OPTION = JOptionPane.CLOSED_OPTION;
fiore@0 490 public static final int DEFAULT_OPTION = JOptionPane.DEFAULT_OPTION;
fiore@0 491 public static final int YES_NO_OPTION = JOptionPane.YES_NO_OPTION;
fiore@0 492 public static final int YES_OPTION = JOptionPane.YES_OPTION;
fiore@0 493 public static final int NO_OPTION = JOptionPane.NO_OPTION;
fiore@0 494
fiore@0 495
fiore@0 496 public static abstract class ProgressDialogWorker<T,V> extends SwingWorker<T,V> {
fiore@3 497 public ProgressDialogWorker(){
fiore@3 498 bar = new JProgressBar();
fiore@3 499 bar.setIndeterminate(true);
fiore@3 500 }
fiore@3 501
fiore@0 502 private void setDialog(JDialog dialog){
fiore@0 503 this.dialog = dialog;
fiore@0 504 }
fiore@0 505
fiore@0 506 @Override
fiore@3 507 protected void done() { //executed in EDT when the work is done
fiore@0 508 if(dialog != null)
fiore@0 509 dialog.dispose();
fiore@0 510 }
fiore@0 511
fiore@0 512 private JDialog dialog;
fiore@3 513 protected JProgressBar bar;
fiore@0 514 }
fiore@0 515
fiore@0 516
fiore@0 517 }