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.Component;
|
fiore@0
|
23 import java.awt.Dimension;
|
fiore@0
|
24 import java.awt.Toolkit;
|
fiore@0
|
25 import java.awt.event.InputEvent;
|
fiore@0
|
26 import java.awt.event.KeyEvent;
|
fiore@0
|
27 import java.awt.event.WindowAdapter;
|
fiore@0
|
28 import java.awt.event.WindowEvent;
|
fiore@0
|
29
|
fiore@0
|
30 import javax.swing.JComponent;
|
fiore@0
|
31 import javax.swing.JDialog;
|
fiore@0
|
32 import javax.swing.JLabel;
|
fiore@0
|
33 import javax.swing.JOptionPane;
|
fiore@0
|
34 import javax.swing.JScrollPane;
|
fiore@0
|
35 import javax.swing.JTextArea;
|
fiore@0
|
36 import javax.swing.KeyStroke;
|
fiore@0
|
37
|
fiore@0
|
38 import uk.ac.qmul.eecs.ccmi.sound.SoundEvent;
|
fiore@0
|
39 import uk.ac.qmul.eecs.ccmi.sound.SoundFactory;
|
fiore@0
|
40 import uk.ac.qmul.eecs.ccmi.speech.NarratorFactory;
|
fiore@0
|
41 import uk.ac.qmul.eecs.ccmi.speech.SpeechUtilities;
|
fiore@0
|
42
|
fiore@0
|
43 /**
|
fiore@0
|
44 * Abstract class with an one-line call to display a summary dialog.
|
fiore@0
|
45 * The summary text as well as focused components are spoken out through text to speech
|
fiore@5
|
46 * synthesis performed by the {@code Narrator} instance.
|
fiore@5
|
47 * A summary dialog has non editable text field and a button for confirmation only.
|
fiore@0
|
48 *
|
fiore@0
|
49 *
|
fiore@0
|
50 */
|
fiore@0
|
51 public abstract class SpeechSummaryPane {
|
fiore@0
|
52
|
fiore@5
|
53 /**
|
fiore@5
|
54 * shows the summary dialog
|
fiore@5
|
55 * @param parentComponent determines the {@code Frame} in which the dialog is displayed
|
fiore@5
|
56 * @param title the title of the displayed dialog
|
fiore@5
|
57 * @param text the text to be displayed in this dialog. his text, together with the title
|
fiore@5
|
58 * is uttered through the {@code Narrator} as soon as the dialog is shown
|
fiore@5
|
59 * @param optionType an integer designating the options available on the dialog
|
fiore@5
|
60 * either {@code OK_CANCEL_OPTION} or {@code OK_OPTION}
|
fiore@5
|
61 * @param options an array of strings indicating the possible choices the user can make
|
fiore@5
|
62 * @return an integer indicating the option selected by the user. Either {@code OK} or {@code CANCEL}
|
fiore@5
|
63 */
|
fiore@0
|
64 public static int showDialog(Component parentComponent, String title, String text, int optionType, String[] options){
|
fiore@0
|
65 if(optionType == OK_CANCEL_OPTION && options.length < 2)
|
fiore@0
|
66 throw new IllegalArgumentException("option type and opions number must be consistent");
|
fiore@0
|
67 final JTextArea textArea = new JTextArea();
|
fiore@0
|
68 textArea.setText(text);
|
fiore@0
|
69 NarratorFactory.getInstance().speak(title+". "+ text);
|
fiore@0
|
70
|
fiore@0
|
71 JScrollPane componentToDisplay = new JScrollPane(textArea);
|
fiore@0
|
72 /* set the maximum size: if there is a lot of content yet it doesn't take the whole screen */
|
fiore@0
|
73 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
fiore@0
|
74
|
fiore@0
|
75 int editorWidth = (int)screenSize.getWidth() * 5 / 8;
|
fiore@0
|
76 int editorHeight = (int)screenSize.getHeight() * 5 / 8;
|
fiore@0
|
77
|
fiore@0
|
78 Dimension currentSize = componentToDisplay.getPreferredSize();
|
fiore@0
|
79 componentToDisplay.setPreferredSize(new Dimension(
|
fiore@0
|
80 Math.min(currentSize.width, editorWidth) , Math.min(currentSize.height, editorHeight)));
|
fiore@0
|
81
|
fiore@0
|
82 Object[] displayObjects = { new JLabel(title), componentToDisplay };
|
fiore@0
|
83 final JOptionPane optPane = new JOptionPane();
|
fiore@0
|
84 optPane.setMessage(displayObjects);
|
fiore@0
|
85 optPane.setMessageType(JOptionPane.PLAIN_MESSAGE);
|
fiore@0
|
86 optPane.setOptionType(optionType);
|
fiore@0
|
87 /* set the options according to the option type */
|
fiore@0
|
88 optPane.setOptions(options);
|
fiore@0
|
89 /* ctrl key will hush the TTS */
|
fiore@0
|
90 optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up");
|
fiore@0
|
91 optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction());
|
fiore@0
|
92
|
fiore@0
|
93 final JDialog dialog = optPane.createDialog(parentComponent, "");
|
fiore@0
|
94 dialog.setResizable(true);
|
fiore@0
|
95
|
fiore@0
|
96 dialog.addWindowFocusListener(new WindowAdapter(){
|
fiore@0
|
97 @Override
|
fiore@0
|
98 public void windowGainedFocus(WindowEvent e) {
|
fiore@0
|
99 textArea.requestFocusInWindow();
|
fiore@0
|
100 }
|
fiore@0
|
101 });
|
fiore@0
|
102
|
fiore@0
|
103 SpeechUtilities.changeTabListener(optPane,dialog);
|
fiore@0
|
104 /* the textArea is not editable, so tab key event must not be consumed so that it can be picked up by the focus manager */
|
fiore@0
|
105 textArea.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB,0), "none");
|
fiore@0
|
106 textArea.addKeyListener(SpeechUtilities.getSpeechKeyListener(false));
|
fiore@0
|
107 textArea.setEditable(false);
|
fiore@0
|
108 // start the editing sound
|
fiore@0
|
109 SoundFactory.getInstance().startLoop(SoundEvent.EDITING);
|
fiore@0
|
110 dialog.setVisible(true);
|
fiore@5
|
111 dialog.dispose();
|
fiore@0
|
112 SoundFactory.getInstance().stopLoop(SoundEvent.EDITING);
|
fiore@0
|
113 NarratorFactory.getInstance().shutUp();
|
fiore@0
|
114
|
fiore@0
|
115 if(optPane.getValue() == null)//window closed
|
fiore@0
|
116 return CANCEL;
|
fiore@0
|
117 else if(optPane.getValue().equals(options[OK]))// pressed on OK
|
fiore@0
|
118 return OK;
|
fiore@0
|
119 else //pressed on cancel
|
fiore@0
|
120 return CANCEL;
|
fiore@0
|
121 }
|
fiore@0
|
122
|
fiore@0
|
123 public static final int OK = 0;
|
fiore@0
|
124 public static final int CANCEL = 1;
|
fiore@0
|
125 public static final int OK_CANCEL_OPTION = JOptionPane.OK_CANCEL_OPTION;
|
fiore@0
|
126 public static final int OK_OPTION = JOptionPane.OK_OPTION;
|
fiore@0
|
127 }
|