comparison java/src/uk/ac/qmul/eecs/ccmi/gui/SpeechOptionPane.java @ 0:9418ab7b7f3f

Initial import
author Fiore Martin <fiore@eecs.qmul.ac.uk>
date Fri, 16 Dec 2011 17:35:51 +0000
parents
children 9e67171477bc
comparison
equal deleted inserted replaced
-1:000000000000 0:9418ab7b7f3f
1 /*
2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
3
4 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 package uk.ac.qmul.eecs.ccmi.gui;
21
22 import java.awt.Color;
23 import java.awt.Component;
24 import java.awt.Frame;
25 import java.awt.GridLayout;
26 import java.awt.event.InputEvent;
27 import java.awt.event.KeyEvent;
28 import java.awt.event.WindowAdapter;
29 import java.awt.event.WindowEvent;
30 import java.text.MessageFormat;
31 import java.util.LinkedHashSet;
32 import java.util.List;
33 import java.util.ResourceBundle;
34 import java.util.Set;
35
36 import javax.swing.JCheckBox;
37 import javax.swing.JComponent;
38 import javax.swing.JDialog;
39 import javax.swing.JFormattedTextField;
40 import javax.swing.JLabel;
41 import javax.swing.JOptionPane;
42 import javax.swing.JPanel;
43 import javax.swing.JProgressBar;
44 import javax.swing.JScrollPane;
45 import javax.swing.JSpinner;
46 import javax.swing.JTextArea;
47 import javax.swing.JTextField;
48 import javax.swing.KeyStroke;
49 import javax.swing.SwingWorker;
50 import javax.swing.event.ChangeEvent;
51 import javax.swing.event.ChangeListener;
52 import javax.swing.text.JTextComponent;
53
54 import uk.ac.qmul.eecs.ccmi.sound.SoundEvent;
55 import uk.ac.qmul.eecs.ccmi.sound.SoundFactory;
56 import uk.ac.qmul.eecs.ccmi.speech.NarratorFactory;
57 import uk.ac.qmul.eecs.ccmi.speech.SpeechUtilities;
58
59 /**
60 *
61 * TheSpeechOptionPane provides one-line calls to display accessible dialog boxes. Input by the user as well
62 * as focused components are spoken out through text to speech synthesis performed by the {@link Narrator} instance.
63 *
64 */
65 public abstract class SpeechOptionPane {
66
67 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);
69 textArea.setText(initialSelectionValue);
70 NarratorFactory.getInstance().speak(message);
71 return textComponentDialog(parentComponent, message, textArea);
72 }
73
74 public static String showInputDialog(Component parentComponent, String message, String initialSelectionValue){
75 final JTextField textField = new JTextField(initialSelectionValue);
76 textField.selectAll();
77 NarratorFactory.getInstance().speak(message);
78 return textComponentDialog(parentComponent, message, textField);
79 }
80
81 private static String textComponentDialog(Component parentComponent, String message, final JTextComponent textComponent){
82 Object componentToDisplay = textComponent;
83 if(textComponent instanceof JTextArea)
84 componentToDisplay = new JScrollPane(textComponent);
85
86 Object[] displayObjects = { new JLabel(message), componentToDisplay };
87 final JOptionPane optPane = new JOptionPane();
88 optPane.setMessage(displayObjects);
89 optPane.setMessageType(QUESTION_MESSAGE);
90 optPane.setOptionType(OK_CANCEL_OPTION);
91 /* ctrl key will hush the TTS */
92 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
93 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
94
95 final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.input"));
96 if(textComponent instanceof JTextArea)
97 dialog.setResizable(true);
98 dialog.addWindowFocusListener(new WindowAdapter(){
99 @Override
100 public void windowGainedFocus(WindowEvent e) {
101 textComponent.requestFocusInWindow();
102 }
103 });
104
105 SpeechUtilities.changeTabListener(optPane,dialog);
106 textComponent.addKeyListener(SpeechUtilities.getSpeechKeyListener(true));
107 textComponent.setEditable(true);
108 // start the editing sound
109 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
110 dialog.setVisible(true);
111 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
112
113 if(optPane.getValue() == null)//window closed
114 return null;
115 else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel
116 return null;
117 else{ // pressed on OK
118 return textComponent.getText().trim();
119 }
120 }
121
122 public static String showInputDialog(Component parentComponent, String message){
123 return showInputDialog(parentComponent, message, "");
124 }
125
126 public static Object showSelectionDialog(Component parentComponent, String message, Object[] options, Object initialValue){
127 final LoopComboBox comboBox = new LoopComboBox(options);
128 comboBox.setSelectedItem(initialValue);
129 Object[] displayObjects = { new JLabel(message), comboBox };
130 JOptionPane optPane = new JOptionPane();
131 optPane.setMessage(displayObjects);
132 optPane.setMessageType(QUESTION_MESSAGE);
133 optPane.setOptionType(OK_CANCEL_OPTION);
134 /* ctrl key will hush the TTS */
135 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
136 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
137
138 NarratorFactory.getInstance().speak(message+", "+SpeechUtilities.getComponentSpeech(comboBox));
139 final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.select"));
140 dialog.addWindowFocusListener(new WindowAdapter(){
141 @Override
142 public void windowGainedFocus(WindowEvent e) {
143 comboBox.requestFocusInWindow();
144 }
145 });
146
147 comboBox.addItemListener(SpeechUtilities.getSpeechComboBoxItemListener());
148
149 SpeechUtilities.changeTabListener(optPane,dialog);
150 // start the editing sound
151 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
152 dialog.setVisible(true);
153 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
154 if(optPane.getValue() == null)//window closed
155 return null;
156 else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel )//pressed on cancel
157 return null;
158 else{ // pressed on OK
159 return comboBox.getSelectedItem();
160 }
161 }
162
163 public static Integer showNarratorRateDialog(Component parentComponent, String message, int value, int min, int max){
164 NarratorFactory.getInstance().speak(message);
165 final JSpinner spinner = new JSpinner(new LoopSpinnerNumberModel(value,min,max));
166 JFormattedTextField tf = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
167 tf.setEditable(false);
168 tf.setFocusable(false);
169 tf.setBackground(Color.white);
170
171 Object[] displayObjects = { new JLabel(message), spinner};
172 final JOptionPane optPane = new JOptionPane();
173 optPane.setMessage(displayObjects);
174 optPane.setMessageType(QUESTION_MESSAGE);
175 optPane.setOptionType(OK_CANCEL_OPTION);
176 /* ctrl key will hush the TTS */
177 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
178 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
179
180 final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.input"));
181 SpeechUtilities.changeTabListener(optPane,dialog);
182
183 dialog.addWindowFocusListener(new WindowAdapter(){
184 @Override
185 public void windowGainedFocus(WindowEvent e) {
186 spinner.requestFocusInWindow();
187 }
188 });
189 spinner.addChangeListener(new ChangeListener(){
190 @Override
191 public void stateChanged(ChangeEvent evt) {
192 JSpinner s = (JSpinner)(evt.getSource());
193 NarratorFactory.getInstance().setRate((Integer)s.getValue());
194 NarratorFactory.getInstance().speak(s.getValue().toString());
195 }
196 });
197 // start the editing sound
198 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
199 dialog.setVisible(true);
200 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
201
202 /* set the speech rate back to the value passed as argument */
203 NarratorFactory.getInstance().setRate(value);
204 if(optPane.getValue() == null)//window closed
205 return null;
206 else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel
207 return null;
208 else{ // pressed on OK
209 return (Integer)spinner.getValue();
210 }
211 }
212
213 public static int showConfirmDialog(Component parentComponent, String message, int optionType){
214 NarratorFactory.getInstance().speak(message);
215 JOptionPane optPane = new JOptionPane();
216 optPane.setMessage(message);
217 optPane.setMessageType(QUESTION_MESSAGE);
218 optPane.setOptionType(optionType);
219 /* ctrl key will hush the TTS */
220 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
221 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
222
223 JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.confirm"));
224 SpeechUtilities.changeTabListener(optPane,dialog);
225
226 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
227 dialog.setVisible(true);
228 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
229
230 if(optPane.getValue() == null)//window closed
231 return CANCEL_OPTION;
232 else
233 return ((Integer)optPane.getValue()).intValue();
234 }
235
236 public static void showMessageDialog(Component parentComponent, String message, int messageType){
237 NarratorFactory.getInstance().speak(MessageFormat.format(resources.getString("dialog.speech_option_pane.message"), message));
238 JOptionPane optPane = new JOptionPane();
239 optPane.setMessage(message);
240 optPane.setMessageType(messageType);
241 /* ctrl key will hush the TTS */
242 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
243 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
244
245 JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.confirm"));
246 SpeechUtilities.changeTabListener(optPane,dialog);
247 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
248 dialog.setVisible(true);
249 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
250 }
251
252 public static void showMessageDialog(Component parentComponent, String message){
253 showMessageDialog(parentComponent,message,ERROR_MESSAGE);
254 }
255
256 public static <T,V> int showProgressDialog(Component parentComponent, String message,final ProgressDialogWorker<T,V> worker, int millisToDecideToPopup){
257 JProgressBar progressBar = new JProgressBar();
258 progressBar.setIndeterminate(true);
259 Object displayObjects[] = {message, progressBar};
260 final JOptionPane optPane = new JOptionPane(displayObjects);
261 optPane.setOptionType(DEFAULT_OPTION);
262 optPane.setOptions(new Object[] {PROGRESS_DIALOG_CANCEL_OPTION});
263 /* ctrl key will hush the TTS */
264 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
265 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
266
267 final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.download"));
268 SpeechUtilities.changeTabListener(optPane,dialog);
269
270 worker.setDialog(dialog);
271 worker.execute();
272 try {
273 Thread.sleep(millisToDecideToPopup);
274 } catch (InterruptedException ie) {
275 throw new RuntimeException(ie); //should never happen
276 }
277 if(worker.isDone())
278 return OK_OPTION;
279
280 NarratorFactory.getInstance().speak(message);
281 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
282 dialog.setVisible(true);
283 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
284 if( optPane.getValue() == null ||
285 optPane.getValue() == PROGRESS_DIALOG_CANCEL_OPTION ||
286 Integer.valueOf(CLOSED_OPTION).equals(optPane.getValue())){
287 worker.cancel(true);
288 return CANCEL_OPTION;
289 }
290 return OK_OPTION;
291 }
292
293 public static Set<Integer> showModifiersDialog(Component parentComponent, String message, List<String> modifierTypes, Set<Integer> modifierIndexes){
294 JOptionPane optPane = new JOptionPane();
295
296 JPanel checkBoxPanel = new JPanel(new GridLayout(0, 1));
297 final JCheckBox[] checkBoxes = new JCheckBox[modifierTypes.size()];
298 for(int i=0;i<checkBoxes.length;i++){
299 checkBoxes[i] = new JCheckBox(modifierTypes.get(i));
300 if(modifierIndexes.contains(i))
301 checkBoxes[i].setSelected(true);
302 checkBoxPanel.add(checkBoxes[i]);
303 checkBoxes[i].addItemListener(SpeechUtilities.getCheckBoxSpeechItemListener());
304 }
305 NarratorFactory.getInstance().speak(message+" "+SpeechUtilities.getComponentSpeech(checkBoxes[0]));
306
307 Object[] displayObjects = {new JLabel(message),checkBoxPanel};
308 optPane.setMessage(displayObjects);
309 optPane.setMessageType(QUESTION_MESSAGE);
310 optPane.setOptionType(OK_CANCEL_OPTION);
311 /* ctrl key will hush the TTS */
312 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
313 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
314 JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.modifiers"));
315 SpeechUtilities.changeTabListener(optPane,dialog);
316
317 dialog.addWindowFocusListener(new WindowAdapter(){
318 @Override
319 public void windowGainedFocus(WindowEvent e) {
320 checkBoxes[0].requestFocusInWindow();
321 }
322 });
323
324 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
325 dialog.setVisible(true);
326 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
327
328 if(optPane.getValue() == null)//window closed
329 return null;
330 else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel
331 return null;
332 else{ // pressed on OK
333 Set<Integer> returnSet = new LinkedHashSet<Integer>();
334 for(int i=0;i<checkBoxes.length;i++)
335 if(checkBoxes[i].isSelected())
336 returnSet.add(i);
337 return returnSet;
338 }
339 }
340
341 public static Frame getFrameForComponent(Component parentComponent){
342 return JOptionPane.getFrameForComponent(parentComponent);
343 }
344
345 private static ResourceBundle resources = ResourceBundle.getBundle(EditorFrame.class.getName());
346 private static final int NOTES_TEXT_AREA_COL_SIZE = 10;
347 private static final int NOTES_TEXT_AREA_ROW_SIZE = 10;
348 private static final String PROGRESS_DIALOG_CANCEL_OPTION = resources.getString("dialog.speech_option_pane.cancel");
349
350
351 public static final int QUESTION_MESSAGE = JOptionPane.QUESTION_MESSAGE;
352 public static final int ERROR_MESSAGE = JOptionPane.ERROR_MESSAGE;
353 public static final int INFORMATION_MESSAGE = JOptionPane.INFORMATION_MESSAGE;
354 public static final int WARNING_MESSAGE = JOptionPane.WARNING_MESSAGE;
355 public static final int OK_CANCEL_OPTION = JOptionPane.OK_CANCEL_OPTION;
356 public static final int CANCEL_OPTION = JOptionPane.CANCEL_OPTION;
357 public static final int OK_OPTION = JOptionPane.OK_OPTION;
358 public static final int CLOSED_OPTION = JOptionPane.CLOSED_OPTION;
359 public static final int DEFAULT_OPTION = JOptionPane.DEFAULT_OPTION;
360 public static final int YES_NO_OPTION = JOptionPane.YES_NO_OPTION;
361 public static final int YES_OPTION = JOptionPane.YES_OPTION;
362 public static final int NO_OPTION = JOptionPane.NO_OPTION;
363
364
365 public static abstract class ProgressDialogWorker<T,V> extends SwingWorker<T,V> {
366 private void setDialog(JDialog dialog){
367 this.dialog = dialog;
368 }
369
370 @Override
371 protected void done() {
372 if(dialog != null)
373 dialog.dispose();
374 }
375
376 private JDialog dialog;
377 }
378
379
380 }