Mercurial > hg > ccmieditor
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 } |