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 }
|