annotate java/src/uk/ac/qmul/eecs/ccmi/simpletemplate/SpeechWizardPanel.java @ 1:71ff0735df5a

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