Mercurial > hg > ccmieditor
view 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 |
line wrap: on
line source
/* CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package uk.ac.qmul.eecs.ccmi.simpletemplate; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.text.MessageFormat; import java.util.Collection; import java.util.ResourceBundle; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFormattedTextField; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.SpinnerModel; import javax.swing.SwingConstants; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import jwizardcomponent.JWizardComponents; import jwizardcomponent.JWizardPanel; import uk.ac.qmul.eecs.ccmi.gui.LoopComboBox; import uk.ac.qmul.eecs.ccmi.speech.NarratorFactory; import uk.ac.qmul.eecs.ccmi.speech.SpeechUtilities; /* * The abstract class providing basic implementation for the panels displayed when the template * wizard is run in order to build a diagram template. Subclasses will define the central component * displayed in the panel. The central component is an input component (e.g. a JTextField), * through which the user enters the input required for at that particular step of the wizard. * * * @see Wizard */ @SuppressWarnings("serial") abstract class SpeechWizardPanel extends JWizardPanel { public SpeechWizardPanel(JWizardComponents wizardComponents, String title, int next, int previous){ super(wizardComponents,title); label = new JLabel(title); this.next = next; this.previous = previous; } @Override public void update(){ Component focusOwner = assignFocus(); NarratorFactory.getInstance().speak( new StringBuilder(getPanelTitle()) .append(' ') .append(SpeechUtilities.getComponentSpeech(focusOwner)).toString()); super.update(); } @Override public void setPanelTitle(String title){ label.setText(title); super.setPanelTitle(title); } protected Component assignFocus(){ if(component != null) component.requestFocus(); return component; } /** * Lays out the components according to the layout manager. This method is used by subclasses * by passing the component the user use for input (e.g. a text field or a combo-box) as argument. * such component is placed at the centre of the panel above the buttons. * @param centralComponent the component to be laid out at the centre dialog */ protected void layoutComponents(JComponent centralComponent){ component = centralComponent; /* pressing enter on the central component results in a switch to the next panel */ component.addKeyListener(new KeyAdapter(){ @Override public void keyPressed(KeyEvent evt){ pressed = true; } @Override public void keyTyped(KeyEvent evt){ /* switch on the next panel only if the press button started on the same window * * this is to avoid keyTyped to be called after the panel switch and therefore refer * * to a component different that the one the user pressed OK on */ if(evt.getKeyChar() == '\n' && pressed) getWizardComponents().getNextButton().doClick(); pressed = false; } boolean pressed = false; }); GridBagConstraints constr = new GridBagConstraints(); constr.gridx = 0; constr.gridy = 0; constr.gridwidth = 1; constr.gridheight = 1; constr.weightx = 1.0; constr.weighty = 0.0; constr.anchor = GridBagConstraints.PAGE_START; constr.fill = GridBagConstraints.BOTH; constr.insets = new Insets(5, 5, 5, 5); constr.ipadx = 0; constr.ipady = 0; /* Label */ setLayout(new GridBagLayout()); JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); label.setHorizontalAlignment(SwingConstants.LEADING); labelPanel.add(label); add(labelPanel,constr); /* JSeparator */ constr.gridy = 1; constr.anchor = GridBagConstraints.WEST; constr.fill = GridBagConstraints.BOTH; constr.insets = new Insets(1, 1, 1, 1); add(new JSeparator(), constr); /* central component */ Container centralComponentContainer; if(centralComponent instanceof JScrollPane ){ centralComponentContainer = centralComponent; }else{ centralComponentContainer = new JPanel(new GridBagLayout()); centralComponentContainer.add(centralComponent , new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 , GridBagConstraints.CENTER, GridBagConstraints.BOTH , new Insets(0, 0, 0, 0), 0, 0)); } constr.gridy = 2; constr.weighty = 1.0; constr.anchor = GridBagConstraints.CENTER; constr.insets = new Insets(0, 0, 0, 0); add(centralComponentContainer,constr); } @Override public void next(){ switchPanel(next); } @Override public void back(){ switchPanel(previous); } private JLabel label; private int next; private int previous; private JComponent component; public static int OWN_SWITCH = -1; public static int DISABLE_SWITCH = -2; } @SuppressWarnings("serial") class SelectWizardPanel extends SpeechWizardPanel { SelectWizardPanel(JWizardComponents wizardComponents, String title, Collection<String> options, int next, int previous, Model.Record record){ super(wizardComponents,title,next,previous); String[] optionsArray = new String[options.size()]; comboBox = new LoopComboBox(new DefaultComboBoxModel(options.toArray(optionsArray))); comboBox.addItemListener(SpeechUtilities.getSpeechComboBoxItemListener()); layoutComponents(comboBox); this.record = record; } SelectWizardPanel(JWizardComponents wizardComponents, String title, Collection<String> options, int[] nexts, int previous, Model.Record record){ this(wizardComponents, title, options, OWN_SWITCH, previous, record); this.nexts = nexts; } SelectWizardPanel(JWizardComponents wizardComponents, String title, Collection<String> options, int[] nexts, int previous){ this(wizardComponents, title, options, nexts, previous,null); } @Override public void next(){ if(record != null) record.value = (String)comboBox.getSelectedItem(); if(nexts != null) switchPanel(nexts[comboBox.getSelectedIndex()]); else super.next(); } @Override public void update(){ if(record != null) comboBox.setSelectedItem(record.value); super.update(); } JComboBox comboBox; int[] nexts; Model.Record record; } @SuppressWarnings("serial") class TextWizardPanel extends SpeechWizardPanel { TextWizardPanel(JWizardComponents wizardComponents, String title, Collection<String> existingValues, int next, int previous, Model.Record record){ super(wizardComponents,title,next,previous); textField = new JTextField(); textField.setColumns(10); textField.addKeyListener(SpeechUtilities.getSpeechKeyListener(true)); layoutComponents(textField); this.record = record; this.existingValues = existingValues; } public void next(){ String text = textField.getText().trim(); /* if the user enters a text he has already entered (that is, it's in the existingValues the don't go on */ /* and notify the user they have to chose another text. The only exception is when the record contains */ /* the same text the user entered as that means they are going through the editing of an existing element*/ if(text.isEmpty()||"\n".equals(text)){ NarratorFactory.getInstance().speak(ResourceBundle.getBundle(SpeechWizardDialog.class.getName()).getString("dialog.error.empty_text")); return; } for(String value : existingValues){ if(value.equals(text) && !text.equals(record.value)){ NarratorFactory.getInstance().speak(MessageFormat.format( ResourceBundle.getBundle(SpeechWizardDialog.class.getName()).getString("dialog.error.existing_value"), text)); return; } } if(record != null) record.value = text; super.next(); } @Override public void update(){ if(record != null) textField.setText(record.value); super.update(); } JTextField textField; Collection<String> existingValues; Model.Record record; } @SuppressWarnings("serial") class SpinnerWizardPanel extends SpeechWizardPanel{ public SpinnerWizardPanel(JWizardComponents wizardComponents, String title, SpinnerModel spinnerModel, int next, int previous, Model.Record record){ super(wizardComponents,title,next,previous); this.record = record; spinner = new JSpinner(spinnerModel); spinner.addChangeListener(new ChangeListener(){ @Override public void stateChanged(ChangeEvent evt) { JSpinner s = (JSpinner)(evt.getSource()); NarratorFactory.getInstance().speak(s.getValue().toString()); } }); JFormattedTextField tf = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField(); tf.setEditable(false); tf.setFocusable(false); tf.setBackground(Color.white); layoutComponents(spinner); } @Override public void next(){ if(record != null) record.value = spinner.getValue().toString(); super.next(); } @Override public void update(){ if(record != null){ if(!record.value.isEmpty()) spinner.setValue(Integer.parseInt(record.value)); } super.update(); } Model.Record record; JSpinner spinner; } @SuppressWarnings("serial") class DummyWizardPanel extends JWizardPanel{ DummyWizardPanel(JWizardComponents wizardComponents){ super(wizardComponents); } }