comparison java/src/uk/ac/qmul/eecs/ccmi/simpletemplate/SpeechWizardPanel.java @ 0:9418ab7b7f3f

Initial import
author Fiore Martin <fiore@eecs.qmul.ac.uk>
date Fri, 16 Dec 2011 17:35:51 +0000
parents
children
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.simpletemplate;
21
22 import java.awt.Color;
23 import java.awt.Component;
24 import java.awt.Container;
25 import java.awt.FlowLayout;
26 import java.awt.GridBagConstraints;
27 import java.awt.GridBagLayout;
28 import java.awt.Insets;
29 import java.awt.event.KeyAdapter;
30 import java.awt.event.KeyEvent;
31 import java.text.MessageFormat;
32 import java.util.Collection;
33 import java.util.ResourceBundle;
34
35 import javax.swing.DefaultComboBoxModel;
36 import javax.swing.JComboBox;
37 import javax.swing.JComponent;
38 import javax.swing.JFormattedTextField;
39 import javax.swing.JLabel;
40 import javax.swing.JPanel;
41 import javax.swing.JScrollPane;
42 import javax.swing.JSeparator;
43 import javax.swing.JSpinner;
44 import javax.swing.JTextField;
45 import javax.swing.SpinnerModel;
46 import javax.swing.SwingConstants;
47 import javax.swing.event.ChangeEvent;
48 import javax.swing.event.ChangeListener;
49
50 import jwizardcomponent.JWizardComponents;
51 import jwizardcomponent.JWizardPanel;
52 import uk.ac.qmul.eecs.ccmi.gui.LoopComboBox;
53 import uk.ac.qmul.eecs.ccmi.speech.NarratorFactory;
54 import uk.ac.qmul.eecs.ccmi.speech.SpeechUtilities;
55
56 /*
57 * The abstract class providing basic implementation for the panels displayed when the template
58 * wizard is run in order to build a diagram template. Subclasses will define the central component
59 * displayed in the panel. The central component is an input component (e.g. a JTextField),
60 * through which the user enters the input required for at that particular step of the wizard.
61 *
62 *
63 * @see Wizard
64 */
65 @SuppressWarnings("serial")
66 abstract class SpeechWizardPanel extends JWizardPanel {
67 public SpeechWizardPanel(JWizardComponents wizardComponents, String title, int next, int previous){
68 super(wizardComponents,title);
69 label = new JLabel(title);
70 this.next = next;
71 this.previous = previous;
72 }
73
74 @Override
75 public void update(){
76 Component focusOwner = assignFocus();
77 NarratorFactory.getInstance().speak(
78 new StringBuilder(getPanelTitle())
79 .append(' ')
80 .append(SpeechUtilities.getComponentSpeech(focusOwner)).toString());
81 super.update();
82 }
83
84 @Override
85 public void setPanelTitle(String title){
86 label.setText(title);
87 super.setPanelTitle(title);
88 }
89
90 protected Component assignFocus(){
91 if(component != null)
92 component.requestFocus();
93 return component;
94 }
95
96 /**
97 * Lays out the components according to the layout manager. This method is used by subclasses
98 * by passing the component the user use for input (e.g. a text field or a combo-box) as argument.
99 * such component is placed at the centre of the panel above the buttons.
100 * @param centralComponent the component to be laid out at the centre dialog
101 */
102 protected void layoutComponents(JComponent centralComponent){
103 component = centralComponent;
104 /* pressing enter on the central component results in a switch to the next panel */
105 component.addKeyListener(new KeyAdapter(){
106 @Override
107 public void keyPressed(KeyEvent evt){
108 pressed = true;
109 }
110
111 @Override
112 public void keyTyped(KeyEvent evt){
113 /* switch on the next panel only if the press button started on the same window *
114 * this is to avoid keyTyped to be called after the panel switch and therefore refer *
115 * to a component different that the one the user pressed OK on */
116 if(evt.getKeyChar() == '\n' && pressed)
117 getWizardComponents().getNextButton().doClick();
118 pressed = false;
119 }
120 boolean pressed = false;
121 });
122
123 GridBagConstraints constr = new GridBagConstraints();
124 constr.gridx = 0;
125 constr.gridy = 0;
126 constr.gridwidth = 1;
127 constr.gridheight = 1;
128 constr.weightx = 1.0;
129 constr.weighty = 0.0;
130 constr.anchor = GridBagConstraints.PAGE_START;
131 constr.fill = GridBagConstraints.BOTH;
132 constr.insets = new Insets(5, 5, 5, 5);
133 constr.ipadx = 0;
134 constr.ipady = 0;
135
136 /* Label */
137 setLayout(new GridBagLayout());
138 JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
139 label.setHorizontalAlignment(SwingConstants.LEADING);
140 labelPanel.add(label);
141 add(labelPanel,constr);
142
143 /* JSeparator */
144 constr.gridy = 1;
145 constr.anchor = GridBagConstraints.WEST;
146 constr.fill = GridBagConstraints.BOTH;
147 constr.insets = new Insets(1, 1, 1, 1);
148 add(new JSeparator(), constr);
149
150 /* central component */
151 Container centralComponentContainer;
152 if(centralComponent instanceof JScrollPane ){
153 centralComponentContainer = centralComponent;
154 }else{
155 centralComponentContainer = new JPanel(new GridBagLayout());
156 centralComponentContainer.add(centralComponent
157 , new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
158 , GridBagConstraints.CENTER, GridBagConstraints.BOTH
159 , new Insets(0, 0, 0, 0), 0, 0));
160 }
161 constr.gridy = 2;
162 constr.weighty = 1.0;
163 constr.anchor = GridBagConstraints.CENTER;
164 constr.insets = new Insets(0, 0, 0, 0);
165 add(centralComponentContainer,constr);
166 }
167
168 @Override
169 public void next(){
170 switchPanel(next);
171 }
172
173 @Override
174 public void back(){
175 switchPanel(previous);
176 }
177
178 private JLabel label;
179 private int next;
180 private int previous;
181 private JComponent component;
182 public static int OWN_SWITCH = -1;
183 public static int DISABLE_SWITCH = -2;
184 }
185
186 @SuppressWarnings("serial")
187 class SelectWizardPanel extends SpeechWizardPanel {
188 SelectWizardPanel(JWizardComponents wizardComponents, String title, Collection<String> options, int next, int previous, Model.Record record){
189 super(wizardComponents,title,next,previous);
190 String[] optionsArray = new String[options.size()];
191 comboBox = new LoopComboBox(new DefaultComboBoxModel(options.toArray(optionsArray)));
192 comboBox.addItemListener(SpeechUtilities.getSpeechComboBoxItemListener());
193 layoutComponents(comboBox);
194 this.record = record;
195 }
196
197 SelectWizardPanel(JWizardComponents wizardComponents, String title, Collection<String> options, int[] nexts, int previous, Model.Record record){
198 this(wizardComponents, title, options, OWN_SWITCH, previous, record);
199 this.nexts = nexts;
200 }
201
202 SelectWizardPanel(JWizardComponents wizardComponents, String title, Collection<String> options, int[] nexts, int previous){
203 this(wizardComponents, title, options, nexts, previous,null);
204 }
205
206 @Override
207 public void next(){
208 if(record != null)
209 record.value = (String)comboBox.getSelectedItem();
210 if(nexts != null)
211 switchPanel(nexts[comboBox.getSelectedIndex()]);
212 else
213 super.next();
214 }
215
216 @Override
217 public void update(){
218 if(record != null)
219 comboBox.setSelectedItem(record.value);
220 super.update();
221 }
222
223 JComboBox comboBox;
224 int[] nexts;
225 Model.Record record;
226 }
227
228 @SuppressWarnings("serial")
229 class TextWizardPanel extends SpeechWizardPanel {
230 TextWizardPanel(JWizardComponents wizardComponents, String title, Collection<String> existingValues, int next, int previous, Model.Record record){
231 super(wizardComponents,title,next,previous);
232 textField = new JTextField();
233 textField.setColumns(10);
234 textField.addKeyListener(SpeechUtilities.getSpeechKeyListener(true));
235 layoutComponents(textField);
236 this.record = record;
237 this.existingValues = existingValues;
238 }
239
240 public void next(){
241 String text = textField.getText().trim();
242 /* if the user enters a text he has already entered (that is, it's in the existingValues the don't go on */
243 /* and notify the user they have to chose another text. The only exception is when the record contains */
244 /* the same text the user entered as that means they are going through the editing of an existing element*/
245 if(text.isEmpty()||"\n".equals(text)){
246 NarratorFactory.getInstance().speak(ResourceBundle.getBundle(SpeechWizardDialog.class.getName()).getString("dialog.error.empty_text"));
247 return;
248 }
249 for(String value : existingValues){
250 if(value.equals(text) && !text.equals(record.value)){
251 NarratorFactory.getInstance().speak(MessageFormat.format(
252 ResourceBundle.getBundle(SpeechWizardDialog.class.getName()).getString("dialog.error.existing_value"),
253 text));
254 return;
255 }
256 }
257 if(record != null)
258 record.value = text;
259 super.next();
260 }
261
262 @Override
263 public void update(){
264 if(record != null)
265 textField.setText(record.value);
266 super.update();
267 }
268
269 JTextField textField;
270 Collection<String> existingValues;
271 Model.Record record;
272 }
273
274 @SuppressWarnings("serial")
275 class SpinnerWizardPanel extends SpeechWizardPanel{
276 public SpinnerWizardPanel(JWizardComponents wizardComponents, String title, SpinnerModel spinnerModel, int next, int previous, Model.Record record){
277 super(wizardComponents,title,next,previous);
278 this.record = record;
279 spinner = new JSpinner(spinnerModel);
280 spinner.addChangeListener(new ChangeListener(){
281 @Override
282 public void stateChanged(ChangeEvent evt) {
283 JSpinner s = (JSpinner)(evt.getSource());
284 NarratorFactory.getInstance().speak(s.getValue().toString());
285 }
286 });
287 JFormattedTextField tf = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
288 tf.setEditable(false);
289 tf.setFocusable(false);
290 tf.setBackground(Color.white);
291 layoutComponents(spinner);
292 }
293
294 @Override
295 public void next(){
296 if(record != null)
297 record.value = spinner.getValue().toString();
298 super.next();
299 }
300
301 @Override
302 public void update(){
303 if(record != null){
304 if(!record.value.isEmpty())
305 spinner.setValue(Integer.parseInt(record.value));
306 }
307 super.update();
308 }
309
310 Model.Record record;
311 JSpinner spinner;
312 }
313
314 @SuppressWarnings("serial")
315 class DummyWizardPanel extends JWizardPanel{
316 DummyWizardPanel(JWizardComponents wizardComponents){
317 super(wizardComponents);
318 }
319 }