comparison java/src/uk/ac/qmul/eecs/ccmi/gui/SpeechOptionPane.java @ 3:9e67171477bc

PHANTOM Omni Heptic device release
author Fiore Martin <fiore@eecs.qmul.ac.uk>
date Wed, 25 Apr 2012 17:09:09 +0100
parents 9418ab7b7f3f
children d66dd5880081
comparison
equal deleted inserted replaced
2:4b2f975e35fa 3:9e67171477bc
21 21
22 import java.awt.Color; 22 import java.awt.Color;
23 import java.awt.Component; 23 import java.awt.Component;
24 import java.awt.Frame; 24 import java.awt.Frame;
25 import java.awt.GridLayout; 25 import java.awt.GridLayout;
26 import java.awt.event.ActionEvent;
27 import java.awt.event.ActionListener;
26 import java.awt.event.InputEvent; 28 import java.awt.event.InputEvent;
27 import java.awt.event.KeyEvent; 29 import java.awt.event.KeyEvent;
28 import java.awt.event.WindowAdapter; 30 import java.awt.event.WindowAdapter;
29 import java.awt.event.WindowEvent; 31 import java.awt.event.WindowEvent;
30 import java.text.MessageFormat; 32 import java.text.MessageFormat;
31 import java.util.LinkedHashSet; 33 import java.util.LinkedHashSet;
32 import java.util.List; 34 import java.util.List;
33 import java.util.ResourceBundle; 35 import java.util.ResourceBundle;
34 import java.util.Set; 36 import java.util.Set;
35 37
38 import javax.swing.AbstractAction;
39 import javax.swing.JButton;
36 import javax.swing.JCheckBox; 40 import javax.swing.JCheckBox;
37 import javax.swing.JComponent; 41 import javax.swing.JComponent;
38 import javax.swing.JDialog; 42 import javax.swing.JDialog;
39 import javax.swing.JFormattedTextField; 43 import javax.swing.JFormattedTextField;
40 import javax.swing.JLabel; 44 import javax.swing.JLabel;
51 import javax.swing.event.ChangeListener; 55 import javax.swing.event.ChangeListener;
52 import javax.swing.text.JTextComponent; 56 import javax.swing.text.JTextComponent;
53 57
54 import uk.ac.qmul.eecs.ccmi.sound.SoundEvent; 58 import uk.ac.qmul.eecs.ccmi.sound.SoundEvent;
55 import uk.ac.qmul.eecs.ccmi.sound.SoundFactory; 59 import uk.ac.qmul.eecs.ccmi.sound.SoundFactory;
60 import uk.ac.qmul.eecs.ccmi.speech.Narrator;
56 import uk.ac.qmul.eecs.ccmi.speech.NarratorFactory; 61 import uk.ac.qmul.eecs.ccmi.speech.NarratorFactory;
57 import uk.ac.qmul.eecs.ccmi.speech.SpeechUtilities; 62 import uk.ac.qmul.eecs.ccmi.speech.SpeechUtilities;
58 63
59 /** 64 /**
60 * 65 *
61 * TheSpeechOptionPane provides one-line calls to display accessible dialog boxes. Input by the user as well 66 * An option panel made out of an {@code Object} being displayed and to buttons: one for accepting and another one for
62 * as focused components are spoken out through text to speech synthesis performed by the {@link Narrator} instance. 67 * cancelling the option.
68 * Furthermore, this class provides one-line calls to display accessible dialog boxes. Input by the user as well
69 * as focused components are spoken out through text to speech synthesis performed by a {@link Narrator} instance.
70 *
63 * 71 *
64 */ 72 */
65 public abstract class SpeechOptionPane { 73 public class SpeechOptionPane {
74
75 /**
76 * Construct a new {@code SpeechOptionPane} with no title. The title is displayed at the top of the dialog
77 * that is displayed after a call to {@code showDialog}
78 */
79 public SpeechOptionPane(){
80 this("");
81 }
82
83 /**
84 * Construct a new {@code SpeechOptionPane} with no title. The title is displayed at the top of the dialog
85 * that is displayed after a call to {@code showDialog}
86 *
87 * @param title the String to be displayed
88 */
89 public SpeechOptionPane(String title){
90 this.title = title;
91 okButton = new JButton("OK");
92 cancelButton = new JButton("Cancel");
93 }
94
95 /**
96 * Pops the a dialog holding this SpeechOptionPane
97 *
98 * @param parent the parent component of the dialog
99 * @param the {@code Object} to display
100 * @return an integer indicating the option selected by the user
101 */
102 @SuppressWarnings("serial")
103 public int showDialog(Component parent,final Object message){
104 optPane = new JOptionPane();
105 optPane.setMessage(message);
106 /* Enter will entail a unique action, regardless the component that's focused */
107 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "closeDialog");
108 optPane.getActionMap().put("closeDialog", new AbstractAction(){
109 @Override
110 public void actionPerformed(ActionEvent evt) {
111 okButton.doClick();
112 }
113 });
114 optPane.setMessageType(JOptionPane.PLAIN_MESSAGE);
115 Object[] options = {
116 okButton,
117 cancelButton
118 };
119 optPane.setOptions(options);
120 /* ctrl key will hush the TTS */
121 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
122 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
123 final JDialog dialog = optPane.createDialog(parent, title);
124 SpeechUtilities.changeTabListener(optPane,dialog);
125 /* when either button is pressed, dialog is disposed and the button itself becomes the optPane.value */
126 ActionListener buttonListener = new ActionListener(){
127 @Override
128 public void actionPerformed(ActionEvent evt) {
129 onClose(dialog,message,(JButton)evt.getSource());
130 }
131 };
132 okButton.addActionListener(buttonListener);
133 cancelButton.addActionListener(buttonListener);
134
135 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
136 dialog.setVisible(true);
137 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
138 dialog.dispose();
139 if(okButton.equals(optPane.getValue())){
140 return OK_OPTION;
141 }else{
142 return CANCEL_OPTION;
143 }
144 }
145
146 /**
147 * Sets the string appearing at the top of the dialog where this option pane is displayed when {@code showDialog}
148 * is called.
149 * @param title
150 */
151 public void setDialogTitle(String title){
152 this.title = title;
153 }
154
155 /**
156 * Returns the {@code JButton} that the user has to press (when the option pane is displayed after
157 * {@code showDialog} is called) in order to accept the option.
158 *
159 * @return a reference to the internal {@code JButton}
160 */
161 public JButton getOkButton(){
162 return okButton;
163 }
164
165 /**
166 * Returns the {@code JButton} that the user has to press (when the option pane is displayed after
167 * {@code showDialog} is called) in order to reject the option.
168 *
169 * @return a reference to the internal {@code JButton}
170 */
171 public JButton getCancelButton(){
172 return cancelButton;
173 }
174
175 /**
176 * This method is called just after the user pressed either button of the dialog displayed
177 * after {@code showDialog} is called.
178 * It assign a value to the return value and it frees the dialog resources.
179 * It can be overwritten by subclasses but care should be taken of calling this class method via
180 * {@code super} in order to properly close the dialog.
181 *
182 * @param dialog the dialog displayed after {@code showDialog} is called.
183 * @param message
184 * @param source the button that triggered the closing of {@code dialog}
185 */
186 protected void onClose(JDialog dialog,Object message, JButton source){
187 optPane.setValue(source);
188 dialog.dispose();
189 }
190
191 private String title;
192 private JOptionPane optPane;
193 private JButton okButton;
194 private JButton cancelButton;
195
196
197 /* -------- STATIC METHODS ----------- */
66 198
67 public static String showTextAreaDialog(Component parentComponent, String message, String initialSelectionValue){ 199 public static String showTextAreaDialog(Component parentComponent, String message, String initialSelectionValue){
68 JTextArea textArea = new JTextArea(NOTES_TEXT_AREA_ROW_SIZE,NOTES_TEXT_AREA_COL_SIZE); 200 JTextArea textArea = new JTextArea(NOTES_TEXT_AREA_ROW_SIZE,NOTES_TEXT_AREA_COL_SIZE);
69 textArea.setText(initialSelectionValue); 201 textArea.setText(initialSelectionValue);
70 NarratorFactory.getInstance().speak(message); 202 NarratorFactory.getInstance().speak(message);
252 public static void showMessageDialog(Component parentComponent, String message){ 384 public static void showMessageDialog(Component parentComponent, String message){
253 showMessageDialog(parentComponent,message,ERROR_MESSAGE); 385 showMessageDialog(parentComponent,message,ERROR_MESSAGE);
254 } 386 }
255 387
256 public static <T,V> int showProgressDialog(Component parentComponent, String message,final ProgressDialogWorker<T,V> worker, int millisToDecideToPopup){ 388 public static <T,V> int showProgressDialog(Component parentComponent, String message,final ProgressDialogWorker<T,V> worker, int millisToDecideToPopup){
257 JProgressBar progressBar = new JProgressBar(); 389 JProgressBar progressBar = worker.bar;
258 progressBar.setIndeterminate(true);
259 Object displayObjects[] = {message, progressBar}; 390 Object displayObjects[] = {message, progressBar};
260 final JOptionPane optPane = new JOptionPane(displayObjects); 391 final JOptionPane optPane = new JOptionPane(displayObjects);
261 optPane.setOptionType(DEFAULT_OPTION); 392 optPane.setOptionType(DEFAULT_OPTION);
262 optPane.setOptions(new Object[] {PROGRESS_DIALOG_CANCEL_OPTION}); 393 optPane.setOptions(new Object[] {PROGRESS_DIALOG_CANCEL_OPTION});
263 /* ctrl key will hush the TTS */ 394 /* ctrl key will hush the TTS */
361 public static final int YES_OPTION = JOptionPane.YES_OPTION; 492 public static final int YES_OPTION = JOptionPane.YES_OPTION;
362 public static final int NO_OPTION = JOptionPane.NO_OPTION; 493 public static final int NO_OPTION = JOptionPane.NO_OPTION;
363 494
364 495
365 public static abstract class ProgressDialogWorker<T,V> extends SwingWorker<T,V> { 496 public static abstract class ProgressDialogWorker<T,V> extends SwingWorker<T,V> {
497 public ProgressDialogWorker(){
498 bar = new JProgressBar();
499 bar.setIndeterminate(true);
500 }
501
366 private void setDialog(JDialog dialog){ 502 private void setDialog(JDialog dialog){
367 this.dialog = dialog; 503 this.dialog = dialog;
368 } 504 }
369 505
370 @Override 506 @Override
371 protected void done() { 507 protected void done() { //executed in EDT when the work is done
372 if(dialog != null) 508 if(dialog != null)
373 dialog.dispose(); 509 dialog.dispose();
374 } 510 }
375 511
376 private JDialog dialog; 512 private JDialog dialog;
513 protected JProgressBar bar;
377 } 514 }
378 515
379 516
380 } 517 }