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