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.Component;
|
fiore@0
|
23 import java.awt.Dimension;
|
fiore@0
|
24 import java.awt.FlowLayout;
|
fiore@0
|
25 import java.awt.Frame;
|
fiore@0
|
26 import java.awt.GridBagLayout;
|
fiore@0
|
27 import java.awt.GridLayout;
|
fiore@0
|
28 import java.awt.event.ActionEvent;
|
fiore@0
|
29 import java.awt.event.KeyEvent;
|
fiore@0
|
30 import java.io.IOException;
|
fiore@0
|
31 import java.text.MessageFormat;
|
fiore@0
|
32 import java.util.ArrayList;
|
fiore@0
|
33 import java.util.Arrays;
|
fiore@0
|
34 import java.util.Collection;
|
fiore@0
|
35 import java.util.LinkedHashMap;
|
fiore@0
|
36 import java.util.LinkedHashSet;
|
fiore@0
|
37 import java.util.ResourceBundle;
|
fiore@0
|
38 import java.util.Set;
|
fiore@0
|
39
|
fiore@0
|
40 import javax.swing.AbstractAction;
|
fiore@0
|
41 import javax.swing.DefaultComboBoxModel;
|
fiore@0
|
42 import javax.swing.JCheckBox;
|
fiore@0
|
43 import javax.swing.JComboBox;
|
fiore@0
|
44 import javax.swing.JComponent;
|
fiore@0
|
45 import javax.swing.JPanel;
|
fiore@0
|
46 import javax.swing.JScrollPane;
|
fiore@0
|
47 import javax.swing.JTextField;
|
fiore@0
|
48 import javax.swing.KeyStroke;
|
fiore@0
|
49 import javax.swing.SpinnerModel;
|
fiore@0
|
50
|
fiore@0
|
51 import jwizardcomponent.FinishAction;
|
fiore@0
|
52 import jwizardcomponent.JWizardComponents;
|
fiore@0
|
53 import jwizardcomponent.JWizardPanel;
|
fiore@0
|
54 import uk.ac.qmul.eecs.ccmi.diagrammodel.NodeProperties;
|
fiore@0
|
55 import uk.ac.qmul.eecs.ccmi.diagrammodel.NodeProperties.Modifiers;
|
fiore@0
|
56 import uk.ac.qmul.eecs.ccmi.gui.Diagram;
|
fiore@0
|
57 import uk.ac.qmul.eecs.ccmi.gui.Edge;
|
fiore@0
|
58 import uk.ac.qmul.eecs.ccmi.gui.LineStyle;
|
fiore@0
|
59 import uk.ac.qmul.eecs.ccmi.gui.LoopComboBox;
|
fiore@0
|
60 import uk.ac.qmul.eecs.ccmi.gui.LoopSpinnerNumberModel;
|
fiore@0
|
61 import uk.ac.qmul.eecs.ccmi.gui.Node;
|
fiore@0
|
62 import uk.ac.qmul.eecs.ccmi.gui.SpeechSummaryPane;
|
fiore@0
|
63 import uk.ac.qmul.eecs.ccmi.simpletemplate.SimpleShapeNode.ShapeType;
|
fiore@0
|
64 import uk.ac.qmul.eecs.ccmi.sound.SoundEvent;
|
fiore@0
|
65 import uk.ac.qmul.eecs.ccmi.sound.SoundFactory;
|
fiore@0
|
66 import uk.ac.qmul.eecs.ccmi.speech.NarratorFactory;
|
fiore@0
|
67 import uk.ac.qmul.eecs.ccmi.speech.SpeechUtilities;
|
fiore@0
|
68 import uk.ac.qmul.eecs.ccmi.utils.GridBagUtilities;
|
fiore@0
|
69
|
fiore@0
|
70 /**
|
fiore@0
|
71 *
|
fiore@0
|
72 * A Wizard-like sequence of screens prompted to the user to let they input (e.g. which shape a node will have or how many nodes an edge can connect at most)
|
fiore@0
|
73 * how to build a template diagram. A template diagram is a prototype diagram
|
fiore@0
|
74 * (containing prototype nodes and edges) which can later on be used for creating instances
|
fiore@0
|
75 * of that type of diagram through clonation. The wizard is completely accessible via audio
|
fiore@0
|
76 * as all the content and all focused components names are spoken out by the {@link Narrator} through a text to speech synthesizer.
|
fiore@0
|
77 *
|
fiore@0
|
78 */
|
fiore@0
|
79 public class Wizard {
|
fiore@0
|
80 public Wizard(Frame frame, Collection<String> existingDiagrams, Diagram diagramToEdit){
|
fiore@0
|
81 dialog = new SpeechWizardDialog(frame);
|
fiore@0
|
82 resources = ResourceBundle.getBundle(SpeechWizardDialog.class.getName());
|
fiore@0
|
83
|
fiore@0
|
84 model = createModel(diagramToEdit);
|
fiore@0
|
85 node = new Model.Node();
|
fiore@0
|
86 edge = new Model.Edge();
|
fiore@0
|
87 property = new Model.Property();
|
fiore@0
|
88 modifier = new Model.Modifier();
|
fiore@0
|
89
|
fiore@0
|
90 initWizardComponents(existingDiagrams,diagramToEdit);
|
fiore@0
|
91
|
fiore@0
|
92 /* if the user is editing from an existing diagram, they have to choose a new name. They're switched *
|
fiore@0
|
93 * directly to the diagram name panel so they have to enter a new name as they would otherwise *
|
fiore@0
|
94 * not be allowed to proceed. */
|
fiore@0
|
95 if(diagramToEdit != null)
|
fiore@0
|
96 dialog.getWizardComponents().setCurrentIndex(DIAGRAM_NAME);
|
fiore@0
|
97
|
fiore@0
|
98 /* when the user clicks on the finish button they'll be prompted with a summary text area dialog *
|
fiore@0
|
99 * describing what they have created so far and asking for a confirmation to proceed with the actual *
|
fiore@0
|
100 * creation of the template. */
|
fiore@0
|
101 dialog.getWizardComponents().setFinishAction(new FinishAction(dialog.getWizardComponents()){
|
fiore@0
|
102 @Override
|
fiore@0
|
103 public void performAction(){
|
fiore@0
|
104 String[] options = {
|
fiore@0
|
105 resources.getString("dialog.summary.ok_button_label"),
|
fiore@0
|
106 resources.getString("dialog.summary.cancel_button_label")};
|
fiore@0
|
107 int result = SpeechSummaryPane.showDialog(
|
fiore@0
|
108 dialog,
|
fiore@0
|
109 resources.getString("dialog.summary.title"),
|
fiore@0
|
110 model.toString(),
|
fiore@0
|
111 SpeechSummaryPane.OK_CANCEL_OPTION,
|
fiore@0
|
112 options);
|
fiore@0
|
113
|
fiore@0
|
114 if(result == SpeechSummaryPane.CANCEL){ // user wants to continue editing
|
fiore@0
|
115 SoundFactory.getInstance().play(SoundEvent.CANCEL);
|
fiore@0
|
116 return;
|
fiore@0
|
117 }
|
fiore@0
|
118 /* create the actual diagram (it will be return to the client class by execute()) */
|
fiore@0
|
119 diagram = createDiagram(model);
|
fiore@0
|
120 dialog.dispose();
|
fiore@0
|
121 }
|
fiore@0
|
122 });
|
fiore@0
|
123 }
|
fiore@0
|
124
|
fiore@0
|
125 public Wizard(Frame frame, Collection<String> existingDiagrams){
|
fiore@0
|
126 this(frame,existingDiagrams,null);
|
fiore@0
|
127 }
|
fiore@0
|
128
|
fiore@0
|
129 public Diagram execute(){
|
fiore@0
|
130 diagram = null;
|
fiore@0
|
131 dialog.show();
|
fiore@0
|
132 if(diagram == null)
|
fiore@0
|
133 SoundFactory.getInstance().play(SoundEvent.CANCEL);
|
fiore@0
|
134 return diagram;
|
fiore@0
|
135 }
|
fiore@0
|
136
|
fiore@0
|
137 @SuppressWarnings("serial")
|
fiore@0
|
138 private void initWizardComponents(Collection<String> existingDiagrams, final Diagram diagramToEdit){
|
fiore@0
|
139 /* --- MAIN PANEL --- */
|
fiore@0
|
140 String[] choices = {
|
fiore@0
|
141 resources.getString("panel.home.choice.diagram_name"),
|
fiore@0
|
142 resources.getString("panel.home.choice.nodes"),
|
fiore@0
|
143 resources.getString("panel.home.choice.edges"),
|
fiore@0
|
144 };
|
fiore@0
|
145 int[] nexts = {DIAGRAM_NAME,NODES,EDGES};
|
fiore@0
|
146
|
fiore@0
|
147 /* panel for the selection of main tasks when creating the diagram: enter diagram name, create node and *
|
fiore@0
|
148 * create edge. When a name is assigned an item is added to the selection which allows the user to finish *
|
fiore@0
|
149 * the template creation, much as they would do by pressing the finish button. If the user edits an existing *
|
fiore@0
|
150 * diagram they're prompted with a message to enter a new diagram name (as there cannot be two diagrams *
|
fiore@0
|
151 * with the same name. When the user enters the name the message goes away */
|
fiore@0
|
152 add(HOME,new SelectWizardPanel(
|
fiore@0
|
153 dialog.getWizardComponents(),
|
fiore@0
|
154 resources.getString("panel.home.title.new"),
|
fiore@0
|
155 Arrays.asList(choices),
|
fiore@0
|
156 nexts,
|
fiore@0
|
157 SpeechWizardPanel.DISABLE_SWITCH
|
fiore@0
|
158 ){
|
fiore@0
|
159 @Override
|
fiore@0
|
160 public void update(){
|
fiore@0
|
161 if(!model.diagramName.value.isEmpty()){
|
fiore@0
|
162 dialog.setFinishButtonEnabled(true);
|
fiore@0
|
163 /* if the diagram has a name the template creation can finish. So add a selection item to the *
|
fiore@0
|
164 * comboBox unless it's already there from a previous update (item count < 4 ) */
|
fiore@0
|
165 if(comboBox.getItemCount() < 4)
|
fiore@0
|
166 ((DefaultComboBoxModel)comboBox.getModel()).addElement(resources.getString("panel.home.choice.finish"));
|
fiore@0
|
167 }
|
fiore@0
|
168 super.update();
|
fiore@0
|
169 }
|
fiore@0
|
170 @Override
|
fiore@0
|
171 public void next(){
|
fiore@0
|
172 if(comboBox.getSelectedIndex() == 3)
|
fiore@0
|
173 dialog.getWizardComponents().getFinishButton().doClick();
|
fiore@0
|
174 else
|
fiore@0
|
175 super.next();
|
fiore@0
|
176 }
|
fiore@0
|
177 });
|
fiore@0
|
178
|
fiore@0
|
179 /* --- DIAGRAM NAME INPUT PANEL --- */
|
fiore@0
|
180 add(DIAGRAM_NAME, new TextWizardPanel(
|
fiore@0
|
181 dialog.getWizardComponents(),
|
fiore@0
|
182 resources.getString(diagramToEdit == null ? "panel.diagram_name.title" : "panel.diagram_name.title.editing_existing_diagram"),
|
fiore@0
|
183 existingDiagrams,
|
fiore@0
|
184 HOME,
|
fiore@0
|
185 HOME,
|
fiore@0
|
186 model.diagramName
|
fiore@0
|
187 ){
|
fiore@0
|
188 @Override
|
fiore@0
|
189 public void update(){
|
fiore@0
|
190 /* this is a little nasty trick to achieve the following: when the user creates a new diagram out of an already existing
|
fiore@0
|
191 * one they're directly prompted with this panel. We want the name of the diagram to be there for awareness
|
fiore@0
|
192 * but at the same time it must not be accepted by the program as it would otherwise clash with
|
fiore@0
|
193 * with the starting diagam's. As the program accepts it when the text entered in the text field is equal to
|
fiore@0
|
194 * model.diagramName.value (for when the user wants to re-edit the name of a diagram they're creating) we must
|
fiore@0
|
195 * fill model.DiagramName.value with the name of the starting diagram to get it shown and spoken out but then
|
fiore@0
|
196 * it's assigned the empty string not to let the user to go forward */
|
fiore@0
|
197 if(diagramToEdit != null && model.diagramName.value.isEmpty()){
|
fiore@0
|
198 model.diagramName.value = diagramToEdit.getName();
|
fiore@0
|
199 super.update();
|
fiore@0
|
200 model.diagramName.value = "";
|
fiore@0
|
201 }else{
|
fiore@0
|
202 super.update();
|
fiore@0
|
203 }
|
fiore@0
|
204 }
|
fiore@0
|
205 });
|
fiore@0
|
206
|
fiore@0
|
207 /* --- NODE ACTION SELECTION PANEL --- */
|
fiore@0
|
208 /* decide whether to add a new node or to edit/delete an existing node */
|
fiore@0
|
209 String[] nodeOptions = {
|
fiore@0
|
210 resources.getString("panel.nodes.actions.add"),
|
fiore@0
|
211 resources.getString("panel.nodes.actions.edit"),
|
fiore@0
|
212 resources.getString("panel.nodes.actions.del"),
|
fiore@0
|
213 resources.getString("panel.nodes.actions.finish")};
|
fiore@0
|
214 int[] nodeNexts = {NODE_TYPE,NODE_EDIT,NODE_DEL,HOME};
|
fiore@0
|
215 add(NODES, new ActionChooserPanel(
|
fiore@0
|
216 dialog.getWizardComponents(),
|
fiore@0
|
217 model.nodes.getNames(),
|
fiore@0
|
218 resources.getString("panel.nodes.title"),
|
fiore@0
|
219 nodeOptions,
|
fiore@0
|
220 nodeNexts,
|
fiore@0
|
221 HOME,
|
fiore@0
|
222 node
|
fiore@0
|
223 ));
|
fiore@0
|
224
|
fiore@0
|
225 /* --- NODE TYPE NAME INPUT PANEL --- */
|
fiore@0
|
226 add(NODE_TYPE,new TextWizardPanel(
|
fiore@0
|
227 dialog.getWizardComponents(),
|
fiore@0
|
228 resources.getString("panel.node_name.title"),
|
fiore@0
|
229 model.nodes.getNames(),
|
fiore@0
|
230 NODE_SHAPE,
|
fiore@0
|
231 NODES,
|
fiore@0
|
232 node.type
|
fiore@0
|
233 ));
|
fiore@0
|
234
|
fiore@0
|
235 /* --- NODE TO DELETE SELECTION PANEL*/
|
fiore@0
|
236 add(NODE_DEL, new DeletePanel(
|
fiore@0
|
237 dialog.getWizardComponents(),
|
fiore@0
|
238 resources.getString("panel.node_del.title"),
|
fiore@0
|
239 NODES,
|
fiore@0
|
240 NODES,
|
fiore@0
|
241 model.nodes));
|
fiore@0
|
242
|
fiore@0
|
243 /* -- NODE TO EDIT SELECTION PANEL */
|
fiore@0
|
244 add(NODE_EDIT, new EditPanel(
|
fiore@0
|
245 dialog.getWizardComponents(),
|
fiore@0
|
246 resources.getString("panel.node_edit.title"),
|
fiore@0
|
247 NODE_TYPE,
|
fiore@0
|
248 NODES,
|
fiore@0
|
249 model.nodes,
|
fiore@0
|
250 node
|
fiore@0
|
251 ));
|
fiore@0
|
252
|
fiore@0
|
253 ShapeType[] shapeTypes = ShapeType.values();
|
fiore@0
|
254 ArrayList<String> shapeTypeNames = new ArrayList<String>(shapeTypes.length);
|
fiore@0
|
255 for(int i=0; i<shapeTypes.length;i++)
|
fiore@0
|
256 if(shapeTypes[i] != ShapeType.Transparent)
|
fiore@0
|
257 shapeTypeNames.add(shapeTypes[i].toString());
|
fiore@0
|
258
|
fiore@0
|
259 /* -- NODE SHAPE SELECTION PANEL --- */
|
fiore@0
|
260 add(NODE_SHAPE, new SelectWizardPanel(
|
fiore@0
|
261 dialog.getWizardComponents(),
|
fiore@0
|
262 resources.getString("panel.node_shape.title"),
|
fiore@0
|
263 shapeTypeNames,
|
fiore@0
|
264 NODE_YESNO_PROPERTIES,
|
fiore@0
|
265 NODE_TYPE,
|
fiore@0
|
266 node.shape
|
fiore@0
|
267 ));
|
fiore@0
|
268
|
fiore@0
|
269 /* --- SELECT WHETHER THE THE NODE HAS TO HAVE PROPERTIES --- */
|
fiore@0
|
270 String[] yesnoPropertyOptions = {
|
fiore@0
|
271 resources.getString("panel.yesno_properties.add"),
|
fiore@0
|
272 resources.getString("panel.yesno_properties.finish")
|
fiore@0
|
273 };
|
fiore@0
|
274 int[] yesnoPropertyNexts = {PROPERTIES,NODES};
|
fiore@0
|
275
|
fiore@0
|
276 add(NODE_YESNO_PROPERTIES,new SelectWizardPanel(
|
fiore@0
|
277 dialog.getWizardComponents(),
|
fiore@0
|
278 resources.getString("panel.yesno_properties.title"),
|
fiore@0
|
279 Arrays.asList(yesnoPropertyOptions),
|
fiore@0
|
280 yesnoPropertyNexts,
|
fiore@0
|
281 NODE_SHAPE
|
fiore@0
|
282 ){
|
fiore@0
|
283 @Override
|
fiore@0
|
284 public void next(){
|
fiore@0
|
285 if(comboBox.getSelectedIndex() == 1){
|
fiore@0
|
286 Model.Node newNode = new Model.Node();
|
fiore@0
|
287 Model.copy(node, newNode);
|
fiore@0
|
288 model.nodes.put(newNode.id,newNode);
|
fiore@0
|
289 }
|
fiore@0
|
290 super.next();
|
fiore@0
|
291 }
|
fiore@0
|
292 });
|
fiore@0
|
293
|
fiore@0
|
294 /* --- PROPERTIES ACTION SELECTION PANEL --- */
|
fiore@0
|
295 String[] propertyOptions = {
|
fiore@0
|
296 resources.getString("panel.properties.actions.add"),
|
fiore@0
|
297 resources.getString("panel.properties.actions.edit"),
|
fiore@0
|
298 resources.getString("panel.properties.actions.del"),
|
fiore@0
|
299 resources.getString("panel.properties.action.finish")};
|
fiore@0
|
300 int[] propertyNexts = {PROPERTY_TYPE,PROPERTY_EDIT,PROPERTY_DEL,NODES};
|
fiore@0
|
301
|
fiore@0
|
302 add(PROPERTIES, new ActionChooserPanel(
|
fiore@0
|
303 dialog.getWizardComponents(),
|
fiore@0
|
304 node.properties.getNames(),
|
fiore@0
|
305 resources.getString("panel.properties.title"),
|
fiore@0
|
306 propertyOptions,
|
fiore@0
|
307 propertyNexts,
|
fiore@0
|
308 NODE_SHAPE,
|
fiore@0
|
309 property
|
fiore@0
|
310 ){
|
fiore@0
|
311 @Override
|
fiore@0
|
312 public void next(){
|
fiore@0
|
313 /* if the user selects finish, create a new node put in it the values of */
|
fiore@0
|
314 /* the temporary property and store it in the model */
|
fiore@0
|
315 if( (comboBox.getSelectedIndex() == 1 && comboBox.getItemCount() == 2)||
|
fiore@0
|
316 (comboBox.getSelectedIndex() == 3 && comboBox.getItemCount() == 4)){
|
fiore@0
|
317 Model.Node newNode = new Model.Node();
|
fiore@0
|
318 Model.copy(node, newNode);
|
fiore@0
|
319 model.nodes.put(newNode.id,newNode);
|
fiore@0
|
320 }
|
fiore@0
|
321 super.next();
|
fiore@0
|
322 }
|
fiore@0
|
323 });
|
fiore@0
|
324
|
fiore@0
|
325 /* --- PROPERTY TYPE NAME INPUT PANEL --- */
|
fiore@0
|
326 add(PROPERTY_TYPE,new TextWizardPanel(
|
fiore@0
|
327 dialog.getWizardComponents(),
|
fiore@0
|
328 resources.getString("panel.property_name.title"),
|
fiore@0
|
329 node.properties.getNames(),
|
fiore@0
|
330 PROPERTY_POSITION,
|
fiore@0
|
331 PROPERTIES,
|
fiore@0
|
332 property.type
|
fiore@0
|
333 ));
|
fiore@0
|
334
|
fiore@0
|
335 /* --- PROPERTY TO DELETE SELECTION PANEL --- */
|
fiore@0
|
336 add(PROPERTY_DEL, new DeletePanel(
|
fiore@0
|
337 dialog.getWizardComponents(),
|
fiore@0
|
338 resources.getString("panel.property_del.title"),
|
fiore@0
|
339 PROPERTIES,
|
fiore@0
|
340 PROPERTIES,
|
fiore@0
|
341 node.properties
|
fiore@0
|
342 ));
|
fiore@0
|
343
|
fiore@0
|
344 /* --- PROPERTY TO EDIT SELECTION PANEL --- */
|
fiore@0
|
345 add(PROPERTY_EDIT, new EditPanel(
|
fiore@0
|
346 dialog.getWizardComponents(),
|
fiore@0
|
347 resources.getString("panel.property_edit.title"),
|
fiore@0
|
348 PROPERTY_TYPE,
|
fiore@0
|
349 PROPERTIES,
|
fiore@0
|
350 node.properties,
|
fiore@0
|
351 property
|
fiore@0
|
352 ));
|
fiore@0
|
353
|
fiore@0
|
354 /* --- PROPERTY POSITION SELECTION DIALOG --- */
|
fiore@0
|
355 SimpleShapeNode.Position positions[] = SimpleShapeNode.Position.values();
|
fiore@0
|
356 ArrayList<String> positionNames = new ArrayList<String>(positions.length);
|
fiore@0
|
357 for(int i=0; i<positions.length;i++)
|
fiore@0
|
358 positionNames.add(positions[i].toString());
|
fiore@0
|
359 int[] positionNexts = {PROPERTY_YESNO_MODIFIER,PROPERTY_SHAPE};
|
fiore@0
|
360
|
fiore@0
|
361
|
fiore@0
|
362 add(PROPERTY_POSITION, new SelectWizardPanel(
|
fiore@0
|
363 dialog.getWizardComponents(),
|
fiore@0
|
364 resources.getString("panel.property_position.title"),
|
fiore@0
|
365 positionNames,
|
fiore@0
|
366 positionNexts,
|
fiore@0
|
367 PROPERTY_TYPE,
|
fiore@0
|
368 property.position
|
fiore@0
|
369 ));
|
fiore@0
|
370
|
fiore@0
|
371 /* --- PROPERTY SHAPE SELECTION DIALOG --- */
|
fiore@0
|
372 shapeTypeNames.add(ShapeType.Transparent.toString());
|
fiore@0
|
373 add(PROPERTY_SHAPE, new SelectWizardPanel(
|
fiore@0
|
374 dialog.getWizardComponents(),
|
fiore@0
|
375 resources.getString("panel.property_shape.title"),
|
fiore@0
|
376 shapeTypeNames,
|
fiore@0
|
377 PROPERTY_YESNO_MODIFIER,
|
fiore@0
|
378 PROPERTY_POSITION,
|
fiore@0
|
379 property.shape
|
fiore@0
|
380 ));
|
fiore@0
|
381
|
fiore@0
|
382 /* --- SELECT WHETHER THE THE PROPERTY HAS TO HAVE MODIFIERS --- */
|
fiore@0
|
383 String[] yesnoModifierOptions = {
|
fiore@0
|
384 resources.getString("panel.yesno_modifiers.add"),
|
fiore@0
|
385 resources.getString("panel.yesno_modifiers.finish")
|
fiore@0
|
386 };
|
fiore@0
|
387 int[] yesnoModifierNexts = {MODIFIERS,PROPERTIES};
|
fiore@0
|
388
|
fiore@0
|
389 add(PROPERTY_YESNO_MODIFIER,new SelectWizardPanel(
|
fiore@0
|
390 dialog.getWizardComponents(),
|
fiore@0
|
391 resources.getString("panel.yesno_modifiers.title"),
|
fiore@0
|
392 Arrays.asList(yesnoModifierOptions),
|
fiore@0
|
393 yesnoModifierNexts,
|
fiore@0
|
394 PROPERTY_POSITION
|
fiore@0
|
395 ){
|
fiore@0
|
396 @Override
|
fiore@0
|
397 public void next(){
|
fiore@0
|
398 if(comboBox.getSelectedIndex() == 1){
|
fiore@0
|
399 Model.Property newProperty = new Model.Property();
|
fiore@0
|
400 Model.copy(property, newProperty);
|
fiore@0
|
401 node.properties.put(newProperty.id,newProperty);
|
fiore@0
|
402 }
|
fiore@0
|
403 super.next();
|
fiore@0
|
404 }
|
fiore@0
|
405 });
|
fiore@0
|
406 /* --- MODIFIERS ACTION SELECTION PANE --- */
|
fiore@0
|
407 String[] modifierOptions = {
|
fiore@0
|
408 resources.getString("panel.modifiers.actions.add"),
|
fiore@0
|
409 resources.getString("panel.modifiers.actions.edit"),
|
fiore@0
|
410 resources.getString("panel.modifiers.actions.del"),
|
fiore@0
|
411 resources.getString("panel.modifiers.actions.finish")
|
fiore@0
|
412 };
|
fiore@0
|
413 int[] modifiersNexts = {MODIFIER_TYPE,MODIFIER_EDIT,MODIFIER_DEL,PROPERTIES};
|
fiore@0
|
414
|
fiore@0
|
415 add(MODIFIERS, new ActionChooserPanel(
|
fiore@0
|
416 dialog.getWizardComponents(),
|
fiore@0
|
417 property.modifiers.getNames(),
|
fiore@0
|
418 resources.getString("panel.modifiers.title"),
|
fiore@0
|
419 modifierOptions,
|
fiore@0
|
420 modifiersNexts,
|
fiore@0
|
421 PROPERTY_POSITION,
|
fiore@0
|
422 modifier){
|
fiore@0
|
423
|
fiore@0
|
424 @Override
|
fiore@0
|
425 public void next(){
|
fiore@0
|
426 /* if the user selects finish, create a new property put in it the values of */
|
fiore@0
|
427 /* the temporary property and store it in the model */
|
fiore@0
|
428 if( (comboBox.getSelectedIndex() == 1 && comboBox.getItemCount() == 2)||
|
fiore@0
|
429 (comboBox.getSelectedIndex() == 3 && comboBox.getItemCount() == 4)){
|
fiore@0
|
430 Model.Property newProperty = new Model.Property();
|
fiore@0
|
431 Model.copy(property, newProperty);
|
fiore@0
|
432 node.properties.put(newProperty.id,newProperty);
|
fiore@0
|
433 }
|
fiore@0
|
434 super.next();
|
fiore@0
|
435 }
|
fiore@0
|
436 });
|
fiore@0
|
437
|
fiore@0
|
438 /* --- MODIFIER TYPE PANEL --- */
|
fiore@0
|
439 add(MODIFIER_TYPE, new TextWizardPanel(
|
fiore@0
|
440 dialog.getWizardComponents(),
|
fiore@0
|
441 resources.getString("panel.modifier_type.title"),
|
fiore@0
|
442 property.modifiers.getNames(),
|
fiore@0
|
443 MODIFIER_FORMAT,
|
fiore@0
|
444 MODIFIERS,
|
fiore@0
|
445 modifier.type
|
fiore@0
|
446 ));
|
fiore@0
|
447
|
fiore@0
|
448 add(MODIFIER_DEL, new DeletePanel(
|
fiore@0
|
449 dialog.getWizardComponents(),
|
fiore@0
|
450 resources.getString("panel.modifier_del.title"),
|
fiore@0
|
451 MODIFIERS,
|
fiore@0
|
452 MODIFIERS,
|
fiore@0
|
453 property.modifiers));
|
fiore@0
|
454
|
fiore@0
|
455 add(MODIFIER_EDIT, new EditPanel(
|
fiore@0
|
456 dialog.getWizardComponents(),
|
fiore@0
|
457 resources.getString("panel.modifier_edit.title"),
|
fiore@0
|
458 MODIFIER_TYPE,
|
fiore@0
|
459 MODIFIERS,
|
fiore@0
|
460 property.modifiers,
|
fiore@0
|
461 modifier
|
fiore@0
|
462 ));
|
fiore@0
|
463
|
fiore@0
|
464 add(MODIFIER_FORMAT, new FormatWizardPanel());
|
fiore@0
|
465 /* --- EDGE ACTION SELECTION PANEL --- */
|
fiore@0
|
466 /* decide whether to add a new edge or to edit/delete an existing edge */
|
fiore@0
|
467 String[] edgeOptions = {
|
fiore@0
|
468 resources.getString("panel.edges.actions.add"),
|
fiore@0
|
469 resources.getString("panel.edges.actions.edit"),
|
fiore@0
|
470 resources.getString("panel.edges.actions.del"),
|
fiore@0
|
471 resources.getString("panel.edges.actions.finish")};
|
fiore@0
|
472 int[] edgeNexts = {EDGE_TYPE,EDGE_EDIT,EDGE_DEL,HOME};
|
fiore@0
|
473 add(EDGES, new ActionChooserPanel(
|
fiore@0
|
474 dialog.getWizardComponents(),
|
fiore@0
|
475 model.edges.getNames(),
|
fiore@0
|
476 resources.getString("panel.edges.title"),
|
fiore@0
|
477 edgeOptions,
|
fiore@0
|
478 edgeNexts,
|
fiore@0
|
479 HOME,
|
fiore@0
|
480 edge
|
fiore@0
|
481 ));
|
fiore@0
|
482
|
fiore@0
|
483 /* --- EDGE TYPE NAME INPUT PANEL --- */
|
fiore@0
|
484 add(EDGE_TYPE,new TextWizardPanel(
|
fiore@0
|
485 dialog.getWizardComponents(),
|
fiore@0
|
486 resources.getString("panel.edge_name.title"),
|
fiore@0
|
487 model.edges.getNames(),
|
fiore@0
|
488 EDGE_LINE_STYLE,
|
fiore@0
|
489 EDGES,
|
fiore@0
|
490 edge.type
|
fiore@0
|
491 ));
|
fiore@0
|
492
|
fiore@0
|
493 /* --- EDGE TO DELETE SELECTION PANEL --- */
|
fiore@0
|
494 add(EDGE_DEL, new DeletePanel(
|
fiore@0
|
495 dialog.getWizardComponents(),
|
fiore@0
|
496 resources.getString("panel.edge_del.title"),
|
fiore@0
|
497 EDGES,
|
fiore@0
|
498 EDGES,
|
fiore@0
|
499 model.edges));
|
fiore@0
|
500
|
fiore@0
|
501 /* --- EDGE TO EDIT SELECTION PANEL --- */
|
fiore@0
|
502 add(EDGE_EDIT, new EditPanel(
|
fiore@0
|
503 dialog.getWizardComponents(),
|
fiore@0
|
504 resources.getString("panel.edge_edit.title"),
|
fiore@0
|
505 EDGE_TYPE,
|
fiore@0
|
506 EDGES,
|
fiore@0
|
507 model.edges,
|
fiore@0
|
508 edge
|
fiore@0
|
509 ));
|
fiore@0
|
510
|
fiore@0
|
511 /* --- LINE STYLE SELECTION PANEL --- */
|
fiore@0
|
512 LineStyle[] lineStyles = LineStyle.values();
|
fiore@0
|
513 String[] lineStyleNames = new String[lineStyles.length];
|
fiore@0
|
514 for(int i=0; i<lineStyles.length;i++)
|
fiore@0
|
515 lineStyleNames[i] = lineStyles[i].toString();
|
fiore@0
|
516
|
fiore@0
|
517 add(EDGE_LINE_STYLE, new SelectWizardPanel(
|
fiore@0
|
518 dialog.getWizardComponents(),
|
fiore@0
|
519 resources.getString("panel.edge_linestyle.title"),
|
fiore@0
|
520 Arrays.asList(lineStyleNames),
|
fiore@0
|
521 EDGE_MIN_NODES,
|
fiore@0
|
522 EDGE_TYPE,
|
fiore@0
|
523 edge.lineStyle
|
fiore@0
|
524 ));
|
fiore@0
|
525
|
fiore@0
|
526 /* --- MIN NODES SELECTION PANEL --- */
|
fiore@0
|
527 SpinnerModel minNodesSpinnerModel = new LoopSpinnerNumberModel(2,2,4);
|
fiore@0
|
528 add(EDGE_MIN_NODES,new SpinnerWizardPanel(
|
fiore@0
|
529 dialog.getWizardComponents(),
|
fiore@0
|
530 resources.getString("panel.edge_min_nodes.title"),
|
fiore@0
|
531 minNodesSpinnerModel,
|
fiore@0
|
532 EDGE_MAX_NODES,
|
fiore@0
|
533 EDGE_LINE_STYLE,
|
fiore@0
|
534 edge.minNodes
|
fiore@0
|
535 ));
|
fiore@0
|
536
|
fiore@0
|
537 /* --- MAX NODES SELECTION PANEL --- */
|
fiore@0
|
538 SpinnerModel maxNodesSpinnerModel = new LoopSpinnerNumberModel(2,2,4);
|
fiore@0
|
539 add(EDGE_MAX_NODES, new SpinnerWizardPanel(
|
fiore@0
|
540 dialog.getWizardComponents(),
|
fiore@0
|
541 resources.getString("panel.edge_max_nodes.title"),
|
fiore@0
|
542 maxNodesSpinnerModel,
|
fiore@0
|
543 EDGE_YESNO_ARROW_HEAD,
|
fiore@0
|
544 EDGE_MIN_NODES,
|
fiore@0
|
545 edge.maxNodes
|
fiore@0
|
546 ){
|
fiore@0
|
547 @Override
|
fiore@0
|
548 public void next(){
|
fiore@0
|
549 int min = Integer.parseInt(edge.minNodes.value);
|
fiore@0
|
550 int max = Integer.parseInt(spinner.getValue().toString());
|
fiore@0
|
551 if(min > max){
|
fiore@0
|
552 NarratorFactory.getInstance().speak(resources.getString("dialog.error.min_max"));
|
fiore@0
|
553 }else{
|
fiore@0
|
554 super.next();
|
fiore@0
|
555 }
|
fiore@0
|
556 }
|
fiore@0
|
557
|
fiore@0
|
558 });
|
fiore@0
|
559
|
fiore@0
|
560 /* --- SELECT WHETHER THE EDGE MUST HAVE ARROW HEADS OR NOT --- */
|
fiore@0
|
561 String[] arrowHeadOptions = {
|
fiore@0
|
562 resources.getString("panel.edge_yesno_arrow_head.actions.add"),
|
fiore@0
|
563 resources.getString("panel.edge_yesno_arrow_head.actions.finish")
|
fiore@0
|
564 };
|
fiore@0
|
565 int[] arrowHeadNexts = {EDGE_ARROW_HEAD,EDGES};
|
fiore@0
|
566 add(EDGE_YESNO_ARROW_HEAD,new SelectWizardPanel(
|
fiore@0
|
567 dialog.getWizardComponents(),
|
fiore@0
|
568 resources.getString("panel.edge_yesno_arrow_head.title"),
|
fiore@0
|
569 Arrays.asList(arrowHeadOptions),
|
fiore@0
|
570 arrowHeadNexts,
|
fiore@0
|
571 EDGE_MAX_NODES
|
fiore@0
|
572 ){
|
fiore@0
|
573 @Override
|
fiore@0
|
574 public void next(){
|
fiore@0
|
575 if(comboBox.getSelectedIndex() == 1){
|
fiore@0
|
576 Model.Edge newEdge = new Model.Edge();
|
fiore@0
|
577 Model.copy(edge, newEdge);
|
fiore@0
|
578 model.edges.put(newEdge.id,newEdge);
|
fiore@0
|
579 }
|
fiore@0
|
580 super.next();
|
fiore@0
|
581 }
|
fiore@0
|
582 });
|
fiore@0
|
583
|
fiore@0
|
584 /* --- ARROW HEAD SELECTION PANEL --- */
|
fiore@0
|
585 add(EDGE_ARROW_HEAD, new ArrowHeadPanel());
|
fiore@0
|
586
|
fiore@0
|
587 add(LAST_PANEL, new DummyWizardPanel(dialog.getWizardComponents()));
|
fiore@0
|
588
|
fiore@0
|
589 SpeechUtilities.changeTabListener((JComponent)dialog.getContentPane(), dialog);
|
fiore@0
|
590 }
|
fiore@0
|
591
|
fiore@0
|
592 private void add(int index, JWizardPanel panel){
|
fiore@0
|
593 dialog.getWizardComponents().addWizardPanel(index,panel);
|
fiore@0
|
594 }
|
fiore@0
|
595
|
fiore@0
|
596 private Diagram createDiagram(Model model){
|
fiore@0
|
597 /* create the node prototypes */
|
fiore@0
|
598 Node[] nodes = new Node[model.nodes.size()];
|
fiore@0
|
599 int i = 0;
|
fiore@0
|
600 for(Model.Node n : model.nodes.values()){
|
fiore@0
|
601 nodes[i] = createDiagramNode(n);
|
fiore@0
|
602 i++;
|
fiore@0
|
603 }
|
fiore@0
|
604 /* create the edge prototypes */
|
fiore@0
|
605 Edge[] edges = new Edge[model.edges.size()];
|
fiore@0
|
606 i = 0;
|
fiore@0
|
607 for(Model.Edge e : model.edges.values()){
|
fiore@0
|
608 edges[i] = createDiagramEdge(e);
|
fiore@0
|
609 i++;
|
fiore@0
|
610 }
|
fiore@0
|
611 return Diagram.newInstance(model.diagramName.value, nodes, edges, new SimpleShapePrototypePersistenceDelegate());
|
fiore@0
|
612 }
|
fiore@0
|
613
|
fiore@0
|
614 private Node createDiagramNode(Model.Node n){
|
fiore@0
|
615 /* set up the properties */
|
fiore@0
|
616 LinkedHashMap<String,Set<String>> propertiesTypeDefinition = new LinkedHashMap<String,Set<String>>();
|
fiore@0
|
617 /* create the property type definition */
|
fiore@0
|
618 for(Model.Property modelProperty : n.properties.values()){
|
fiore@0
|
619 Set<String> modifiersTypeDefinition = new LinkedHashSet<String>();
|
fiore@0
|
620 for(Model.Modifier modifier : modelProperty.modifiers.values())
|
fiore@0
|
621 modifiersTypeDefinition.add(modifier.type.value);
|
fiore@0
|
622 propertiesTypeDefinition.put(modelProperty.type.value, modifiersTypeDefinition);
|
fiore@0
|
623 }
|
fiore@0
|
624 NodeProperties properties = new NodeProperties(propertiesTypeDefinition);
|
fiore@0
|
625 /* now that properties object is created attach the views on it */
|
fiore@0
|
626 for(Model.Property modelProperty : n.properties.values()){
|
fiore@0
|
627 PropertyView propertyView = new PropertyView(
|
fiore@0
|
628 SimpleShapeNode.Position.valueOf(modelProperty.position.value),
|
fiore@0
|
629 modelProperty.shape.value.isEmpty() ?
|
fiore@0
|
630 /* doesn't really matter as position is inside and shape won't be taken into account */
|
fiore@0
|
631 SimpleShapeNode.ShapeType.Rectangle :
|
fiore@0
|
632 SimpleShapeNode.ShapeType.valueOf(modelProperty.shape.value)
|
fiore@0
|
633 );
|
fiore@0
|
634 properties.setView(modelProperty.type.value, propertyView);
|
fiore@0
|
635 /* modifier view */
|
fiore@0
|
636 for(Model.Modifier modelModifier : modelProperty.modifiers.values()){
|
fiore@0
|
637 boolean bold = false;
|
fiore@0
|
638 boolean italic = false;
|
fiore@0
|
639 boolean underline = false;
|
fiore@0
|
640 String prefix = "";
|
fiore@0
|
641 String suffix = "";
|
fiore@0
|
642 for(String value : modelModifier.format.values){
|
fiore@0
|
643 if(value.equals(resources.getString("modifier.format.bold"))){
|
fiore@0
|
644 bold = true;
|
fiore@0
|
645 }else if(value.equals(resources.getString("modifier.format.underline"))){
|
fiore@0
|
646 underline = true;
|
fiore@0
|
647 }else if(value.equals(resources.getString("modifier.format.italic"))){
|
fiore@0
|
648 italic = true;
|
fiore@0
|
649 }else if(value.equals(resources.getString("modifier.format.prefix"))){
|
fiore@0
|
650 prefix = modelModifier.affix.values[PREFIX_INDEX];
|
fiore@0
|
651 }else if(value.equals(resources.getString("modifier.format.suffix"))){
|
fiore@0
|
652 suffix = modelModifier.affix.values[SUFFIX_INDEX];
|
fiore@0
|
653 }
|
fiore@0
|
654 }
|
fiore@0
|
655 ModifierView modifierView = new ModifierView(underline,bold,italic,prefix,suffix);
|
fiore@0
|
656 properties.getModifiers(modelProperty.type.value).setView(modelModifier.type.value, modifierView);
|
fiore@0
|
657 }
|
fiore@0
|
658 }
|
fiore@0
|
659 return SimpleShapeNode.getInstance(
|
fiore@0
|
660 SimpleShapeNode.ShapeType.valueOf(n.shape.value),
|
fiore@0
|
661 n.type.value,
|
fiore@0
|
662 properties);
|
fiore@0
|
663 }
|
fiore@0
|
664
|
fiore@0
|
665 private Edge createDiagramEdge(Model.Edge e){
|
fiore@0
|
666 /* create the arrow head array out of the string stored in the model */
|
fiore@0
|
667 ArrowHead[] arrowHeads = new ArrowHead[e.arrowHeads.values.length];
|
fiore@0
|
668 for(int i=0; i<e.arrowHeads.values.length;i++){
|
fiore@0
|
669 try {
|
fiore@0
|
670 arrowHeads[i] = ArrowHead.getArrowHeadFromString(e.arrowHeads.values[i]);
|
fiore@0
|
671 } catch (IOException ioe) {
|
fiore@0
|
672 throw new RuntimeException(ioe);// the wizard mustn't allow the user to enter different strings
|
fiore@0
|
673 }
|
fiore@0
|
674 }
|
fiore@0
|
675 return new SimpleShapeEdge(
|
fiore@0
|
676 e.type.value,
|
fiore@0
|
677 LineStyle.valueOf(e.lineStyle.value),
|
fiore@0
|
678 arrowHeads,
|
fiore@0
|
679 e.arrowHeadsDescriptions.values,
|
fiore@0
|
680 Integer.parseInt(e.minNodes.value),
|
fiore@0
|
681 Integer.parseInt(e.maxNodes.value)
|
fiore@0
|
682 );
|
fiore@0
|
683 }
|
fiore@0
|
684
|
fiore@0
|
685 private Model createModel(Diagram diagram) {
|
fiore@0
|
686 Model model = new Model();
|
fiore@0
|
687 if(diagram == null)
|
fiore@0
|
688 return model;
|
fiore@0
|
689
|
fiore@0
|
690 /* the name isn't copied as the user as to find a new one */
|
fiore@0
|
691 /* model.diagramName.value = diagram.getName();*/
|
fiore@0
|
692
|
fiore@0
|
693 /* nodes */
|
fiore@0
|
694 for(Node n : diagram.getNodePrototypes()){
|
fiore@0
|
695 if(!(n instanceof SimpleShapeNode))
|
fiore@0
|
696 continue;
|
fiore@0
|
697 Model.Node modelNode = createModelNode((SimpleShapeNode)n);
|
fiore@0
|
698 model.nodes.put(modelNode.id,modelNode);
|
fiore@0
|
699 }
|
fiore@0
|
700 /* edges */
|
fiore@0
|
701 for(Edge e : diagram.getEdgePrototypes()){
|
fiore@0
|
702 if(!(e instanceof SimpleShapeEdge))
|
fiore@0
|
703 continue;
|
fiore@0
|
704 Model.Edge modelEdge = createModelEdge((SimpleShapeEdge)e);
|
fiore@0
|
705 model.edges.put(modelEdge.id, modelEdge);
|
fiore@0
|
706 }
|
fiore@0
|
707 return model;
|
fiore@0
|
708 }
|
fiore@0
|
709
|
fiore@0
|
710 /**
|
fiore@0
|
711 * fills up the model node object with informations from the real diagram node
|
fiore@0
|
712 * @param n
|
fiore@0
|
713 * @return
|
fiore@0
|
714 */
|
fiore@0
|
715 private Model.Node createModelNode(SimpleShapeNode n){
|
fiore@0
|
716 Model.Node modelNode = new Model.Node();
|
fiore@0
|
717 modelNode.type.value = n.getType();
|
fiore@0
|
718 modelNode.shape.value = n.getShapeType().toString();
|
fiore@0
|
719
|
fiore@0
|
720 NodeProperties properties = n.getProperties();
|
fiore@0
|
721 for(String propertyType : properties.getTypes()){
|
fiore@0
|
722 Model.Property modelProperty = new Model.Property();
|
fiore@0
|
723 modelProperty.type.value = propertyType;
|
fiore@0
|
724 /* if the view is not a PropertyView or is null then assign a default value */
|
fiore@0
|
725 /* it should never happen but it's just to keep it safer and more forward compliant */
|
fiore@0
|
726 if(! (properties.getView(propertyType) instanceof PropertyView)){
|
fiore@0
|
727 modelProperty.position.value = SimpleShapeNode.Position.Inside.toString();
|
fiore@0
|
728 }else{
|
fiore@0
|
729 PropertyView propertyView = (PropertyView)properties.getView(propertyType);
|
fiore@0
|
730 modelProperty.position.value = propertyView.getPosition().toString();
|
fiore@0
|
731 modelProperty.shape.value = propertyView.getShapeType().toString();
|
fiore@0
|
732 }
|
fiore@0
|
733 Modifiers modifiers = properties.getModifiers(propertyType);
|
fiore@0
|
734 for(String modifierType : modifiers.getTypes()){
|
fiore@0
|
735 Model.Modifier modelModifier = new Model.Modifier();
|
fiore@0
|
736 modelModifier.type.value = modifierType;
|
fiore@0
|
737 if(modifiers.getView(modifierType) instanceof ModifierView){
|
fiore@0
|
738 ModifierView modifierView = (ModifierView)modifiers.getView(modifierType);
|
fiore@0
|
739 /* the string array with the modifier values must be created, so the size must be known before */
|
fiore@0
|
740 int numModifierValues = 0;
|
fiore@0
|
741 if(modifierView.isBold())
|
fiore@0
|
742 numModifierValues++;
|
fiore@0
|
743 if(modifierView.isItalic())
|
fiore@0
|
744 numModifierValues++;
|
fiore@0
|
745 if(modifierView.isUnderline())
|
fiore@0
|
746 numModifierValues++;
|
fiore@0
|
747 if(!modifierView.getPrefix().isEmpty())
|
fiore@0
|
748 numModifierValues++;
|
fiore@0
|
749 if(!modifierView.getSuffix().isEmpty())
|
fiore@0
|
750 numModifierValues++;
|
fiore@0
|
751 /* create the string array and fill it up with values */
|
fiore@0
|
752 modelModifier.format.values = new String[numModifierValues];
|
fiore@0
|
753 numModifierValues = 0;
|
fiore@0
|
754 if(modifierView.isBold())
|
fiore@0
|
755 modelModifier.format.values[numModifierValues++] = resources.getString("modifier.format.bold");
|
fiore@0
|
756 if(modifierView.isItalic())
|
fiore@0
|
757 modelModifier.format.values[numModifierValues++] = resources.getString("modifier.format.italic");
|
fiore@0
|
758 if(modifierView.isUnderline())
|
fiore@0
|
759 modelModifier.format.values[numModifierValues++] = resources.getString("modifier.format.underline");
|
fiore@0
|
760 if(!modifierView.getPrefix().isEmpty()){
|
fiore@0
|
761 modelModifier.format.values[numModifierValues++] = resources.getString("modifier.format.prefix");
|
fiore@0
|
762 modelModifier.affix.values[PREFIX_INDEX] = modifierView.getPrefix();
|
fiore@0
|
763 }
|
fiore@0
|
764
|
fiore@0
|
765 if(!modifierView.getSuffix().isEmpty()){
|
fiore@0
|
766 modelModifier.format.values[numModifierValues++] = resources.getString("modifier.format.suffix");
|
fiore@0
|
767 modelModifier.affix.values[SUFFIX_INDEX] = modifierView.getSuffix();
|
fiore@0
|
768 }
|
fiore@0
|
769 }
|
fiore@0
|
770 modelProperty.modifiers.put(modelModifier.id, modelModifier);
|
fiore@0
|
771 }
|
fiore@0
|
772 modelNode.properties.put(modelProperty.id, modelProperty);
|
fiore@0
|
773 }
|
fiore@0
|
774 return modelNode;
|
fiore@0
|
775 }
|
fiore@0
|
776
|
fiore@0
|
777 private Model.Edge createModelEdge(SimpleShapeEdge e){
|
fiore@0
|
778 Model.Edge modelEdge = new Model.Edge();
|
fiore@0
|
779 modelEdge.type.value = e.getType();
|
fiore@0
|
780 modelEdge.lineStyle.value = e.getStyle().toString();
|
fiore@0
|
781 modelEdge.maxNodes.value = Integer.toString(e.getMaxAttachedNodes());
|
fiore@0
|
782 modelEdge.minNodes.value = Integer.toString(e.getMinAttachedNodes());
|
fiore@0
|
783
|
fiore@0
|
784 /* arrow heads and arrowheads descriptions */
|
fiore@0
|
785 modelEdge.arrowHeadsDescriptions.values = e.getAvailableEndDescriptions();
|
fiore@0
|
786 modelEdge.arrowHeads.values = new String[e.getHeads().length];
|
fiore@0
|
787 for(int i =0; i<e.getHeads().length;i++){
|
fiore@0
|
788 modelEdge.arrowHeads.values[i] = e.getHeads()[i].toString();
|
fiore@0
|
789 }
|
fiore@0
|
790
|
fiore@0
|
791 return modelEdge;
|
fiore@0
|
792 }
|
fiore@0
|
793
|
fiore@0
|
794 private SpeechWizardDialog dialog;
|
fiore@0
|
795 private Diagram diagram;
|
fiore@0
|
796 private ResourceBundle resources;
|
fiore@0
|
797 private Model model;
|
fiore@0
|
798 /* these are the temporary variables where the data are stored during the wizard *
|
fiore@0
|
799 * when a sub task is completed ( node creation, edge creation, property creation)*
|
fiore@0
|
800 * the data stored in the temporary variables are saved in the model */
|
fiore@0
|
801 private Model.Node node;
|
fiore@0
|
802 private Model.Property property;
|
fiore@0
|
803 private Model.Modifier modifier;
|
fiore@0
|
804 private Model.Edge edge;
|
fiore@0
|
805
|
fiore@0
|
806 static int HOME = 0;
|
fiore@0
|
807 static int DIAGRAM_NAME = 1;
|
fiore@0
|
808 static int NODES = 2;
|
fiore@0
|
809 static int NODE_TYPE = 3;
|
fiore@0
|
810 static int NODE_DEL = 4;
|
fiore@0
|
811 static int NODE_EDIT = 5;
|
fiore@0
|
812 static int NODE_SHAPE = 6;
|
fiore@0
|
813 static int NODE_YESNO_PROPERTIES = 7;
|
fiore@0
|
814 static int PROPERTIES = 8;
|
fiore@0
|
815 static int PROPERTY_TYPE = 9;
|
fiore@0
|
816 static int PROPERTY_DEL = 10;
|
fiore@0
|
817 static int PROPERTY_EDIT = 11;
|
fiore@0
|
818 static int PROPERTY_POSITION = 12;
|
fiore@0
|
819 static int PROPERTY_SHAPE = 13;
|
fiore@0
|
820 static int PROPERTY_YESNO_MODIFIER = 14;
|
fiore@0
|
821 static int MODIFIERS = 15;
|
fiore@0
|
822 static int MODIFIER_TYPE = 16;
|
fiore@0
|
823 static int MODIFIER_DEL = 17;
|
fiore@0
|
824 static int MODIFIER_EDIT = 18;
|
fiore@0
|
825 static int MODIFIER_FORMAT = 19;
|
fiore@0
|
826 static int EDGES = 20;
|
fiore@0
|
827 static int EDGE_TYPE = 21;
|
fiore@0
|
828 static int EDGE_DEL = 22;
|
fiore@0
|
829 static int EDGE_EDIT = 23;
|
fiore@0
|
830 static int EDGE_LINE_STYLE = 24;
|
fiore@0
|
831 static int EDGE_MIN_NODES = 25;
|
fiore@0
|
832 static int EDGE_MAX_NODES = 26;
|
fiore@0
|
833 static int EDGE_YESNO_ARROW_HEAD = 27;
|
fiore@0
|
834 static int EDGE_ARROW_HEAD = 28;
|
fiore@0
|
835 static int LAST_PANEL = 29;
|
fiore@0
|
836
|
fiore@0
|
837 private static int PREFIX_INDEX = 0;
|
fiore@0
|
838 private static int SUFFIX_INDEX = 1;
|
fiore@0
|
839
|
fiore@0
|
840 /* the abstract class from which the panels for Nodes, edges and Modifiers inherit
|
fiore@0
|
841 * It displays the actions (add,edit,delete,finish) on a comboBox. if elementNames is empty
|
fiore@0
|
842 * it means that no element has been created yet and therefore edit and delete actions are disabled
|
fiore@0
|
843 */
|
fiore@0
|
844 @SuppressWarnings("serial")
|
fiore@0
|
845 private static class ActionChooserPanel extends SpeechWizardPanel{
|
fiore@0
|
846 ActionChooserPanel(JWizardComponents wizardComponents,Collection<String> elementNames, String title, String[] options, int[] nexts, int previous, Model.Element temporaryElement){
|
fiore@0
|
847 super(wizardComponents,title,OWN_SWITCH, previous);
|
fiore@0
|
848 this.options = options;
|
fiore@0
|
849 comboBoxModel = new DefaultComboBoxModel();
|
fiore@0
|
850 comboBoxModel.addElement(options[0]);
|
fiore@0
|
851 comboBoxModel.addElement(options[3]);
|
fiore@0
|
852 comboBox = new LoopComboBox(comboBoxModel);
|
fiore@0
|
853 comboBox.addItemListener(SpeechUtilities.getSpeechComboBoxItemListener());
|
fiore@0
|
854 layoutComponents(comboBox);
|
fiore@0
|
855 this.elementNames = elementNames;
|
fiore@0
|
856 this.temporaryElement = temporaryElement;
|
fiore@0
|
857 this.nexts = nexts;
|
fiore@0
|
858 }
|
fiore@0
|
859
|
fiore@0
|
860 @Override
|
fiore@0
|
861 public void update(){
|
fiore@0
|
862 if(elementNames.isEmpty() && comboBoxModel.getSize() == 4){
|
fiore@0
|
863 comboBoxModel.removeElement(options[1]);
|
fiore@0
|
864 comboBoxModel.removeElement(options[2]);
|
fiore@0
|
865 }else if(!elementNames.isEmpty() && comboBoxModel.getSize() == 2){
|
fiore@0
|
866 comboBoxModel.insertElementAt(options[1],1);
|
fiore@0
|
867 comboBoxModel.insertElementAt(options[2],2);
|
fiore@0
|
868 }
|
fiore@0
|
869 super.update();
|
fiore@0
|
870 }
|
fiore@0
|
871
|
fiore@0
|
872 @Override
|
fiore@0
|
873 public void next(){
|
fiore@0
|
874 /* if the selection was add element, then we clear the temporary holder */
|
fiore@0
|
875 if(comboBox.getSelectedIndex() == 0)
|
fiore@0
|
876 temporaryElement.clear();
|
fiore@0
|
877 /* jump to the selected next step, works both when it's only add/finish and when it's add/delete/edit/finish */
|
fiore@0
|
878 for(int i=0; i<options.length; i++)
|
fiore@0
|
879 if(comboBox.getSelectedItem().equals(options[i])){
|
fiore@0
|
880 switchPanel(nexts[i]);
|
fiore@0
|
881 return;
|
fiore@0
|
882 }
|
fiore@0
|
883 }
|
fiore@0
|
884
|
fiore@0
|
885 JComboBox comboBox;
|
fiore@0
|
886 Collection<String> elementNames;
|
fiore@0
|
887 DefaultComboBoxModel comboBoxModel;
|
fiore@0
|
888 String[] options;
|
fiore@0
|
889 Model.Element temporaryElement;
|
fiore@0
|
890 int[] nexts;
|
fiore@0
|
891 }
|
fiore@0
|
892
|
fiore@0
|
893 @SuppressWarnings("serial")
|
fiore@0
|
894 private static class DeletePanel extends SpeechWizardPanel {
|
fiore@0
|
895 DeletePanel(JWizardComponents wizardComponents,String title, int next, int previous, ModelMap<? extends Model.Element> elements){
|
fiore@0
|
896 super(wizardComponents,title,next, previous);
|
fiore@0
|
897 this.elements = elements;
|
fiore@0
|
898 comboBox = new LoopComboBox();
|
fiore@0
|
899 comboBox.addItemListener(SpeechUtilities.getSpeechComboBoxItemListener());
|
fiore@0
|
900 layoutComponents(comboBox);
|
fiore@0
|
901 }
|
fiore@0
|
902
|
fiore@0
|
903 @Override
|
fiore@0
|
904 public void update(){
|
fiore@0
|
905 String[] options = new String[elements.values().size()];
|
fiore@0
|
906 options = elements.getNames().toArray(options);
|
fiore@0
|
907 comboBox.setModel(new DefaultComboBoxModel(options));
|
fiore@0
|
908 super.update();
|
fiore@0
|
909 }
|
fiore@0
|
910
|
fiore@0
|
911 /**
|
fiore@0
|
912 * the default behaviour is to delete the selected element
|
fiore@0
|
913 */
|
fiore@0
|
914 @Override
|
fiore@0
|
915 public void next(){
|
fiore@0
|
916 Model.Element elementToDelete = null;
|
fiore@0
|
917 for(Model.Element element : elements.values()){
|
fiore@0
|
918 if(element.type.value.equals(comboBox.getSelectedItem())){
|
fiore@0
|
919 elementToDelete = element;
|
fiore@0
|
920 break;
|
fiore@0
|
921 }
|
fiore@0
|
922 }
|
fiore@0
|
923 Object o = elements.remove(elementToDelete.id);
|
fiore@0
|
924 assert(o != null);
|
fiore@0
|
925 super.next();
|
fiore@0
|
926 }
|
fiore@0
|
927
|
fiore@0
|
928 JComboBox comboBox;
|
fiore@0
|
929 ModelMap<? extends Model.Element> elements;
|
fiore@0
|
930 }
|
fiore@0
|
931
|
fiore@0
|
932 @SuppressWarnings("serial")
|
fiore@0
|
933 private static class EditPanel extends DeletePanel {
|
fiore@0
|
934 EditPanel(JWizardComponents wizardComponents,
|
fiore@0
|
935 String title,
|
fiore@0
|
936 int next,
|
fiore@0
|
937 int previous,
|
fiore@0
|
938 ModelMap<? extends Model.Element> elements,
|
fiore@0
|
939 Model.Element temporaryHolder){
|
fiore@0
|
940 super(wizardComponents, title,next, previous,elements);
|
fiore@0
|
941 this.temporaryHolder = temporaryHolder;
|
fiore@0
|
942 this.next = next;
|
fiore@0
|
943 }
|
fiore@0
|
944
|
fiore@0
|
945 @Override
|
fiore@0
|
946 public void next(){
|
fiore@0
|
947 Model.Element selected = null;
|
fiore@0
|
948 for(Model.Element e : elements.values()){
|
fiore@0
|
949 if(e.type.value.equals(comboBox.getSelectedItem())){
|
fiore@0
|
950 selected = e;
|
fiore@0
|
951 break;
|
fiore@0
|
952 }
|
fiore@0
|
953 }
|
fiore@0
|
954
|
fiore@0
|
955 Model.copy(selected, temporaryHolder);
|
fiore@0
|
956 switchPanel(next);
|
fiore@0
|
957 }
|
fiore@0
|
958
|
fiore@0
|
959 int next;
|
fiore@0
|
960 Model.Element temporaryHolder;
|
fiore@0
|
961 }
|
fiore@0
|
962
|
fiore@0
|
963 @SuppressWarnings("serial")
|
fiore@0
|
964 private class FormatWizardPanel extends SpeechWizardPanel{
|
fiore@0
|
965 FormatWizardPanel(){
|
fiore@0
|
966 super(dialog.getWizardComponents(),resources.getString("panel.modifier_format.title"),MODIFIERS,MODIFIER_TYPE);
|
fiore@0
|
967 String values[] = {
|
fiore@0
|
968 resources.getString("modifier.format.bold"),
|
fiore@0
|
969 resources.getString("modifier.format.underline"),
|
fiore@0
|
970 resources.getString("modifier.format.italic"),
|
fiore@0
|
971 resources.getString("modifier.format.prefix"),
|
fiore@0
|
972 resources.getString("modifier.format.suffix"),
|
fiore@0
|
973 };
|
fiore@0
|
974
|
fiore@0
|
975 checkBoxes = new JCheckBox[values.length];
|
fiore@0
|
976 checkBoxPanel = new JPanel(new GridLayout(0, 1));
|
fiore@0
|
977 for(int i=0; i<values.length;i++){
|
fiore@0
|
978 String value = values[i];
|
fiore@0
|
979 checkBoxes[i] = new JCheckBox(value);
|
fiore@0
|
980 checkBoxes[i].getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), "enter");
|
fiore@0
|
981 checkBoxes[i].getActionMap().put("enter", new AbstractAction(){
|
fiore@0
|
982 @Override
|
fiore@0
|
983 public void actionPerformed(ActionEvent arg0) {
|
fiore@0
|
984 getWizardComponents().getNextButton().doClick();
|
fiore@0
|
985 }
|
fiore@0
|
986 });
|
fiore@0
|
987 checkBoxes[i].addItemListener(SpeechUtilities.getCheckBoxSpeechItemListener());
|
fiore@0
|
988 /* prefix and suffix check boxes must have a JText area for the user to enter the String */
|
fiore@0
|
989 if(i == 3 || i == 4){
|
fiore@0
|
990 JPanel panel = new JPanel();
|
fiore@0
|
991 panel.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
|
fiore@0
|
992 panel.add(checkBoxes[i]);
|
fiore@0
|
993 if(i == 3){
|
fiore@0
|
994 prefixTextField = new JTextField();
|
fiore@0
|
995 prefixTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), "enter");
|
fiore@0
|
996 prefixTextField.getActionMap().put("enter", new AbstractAction(){
|
fiore@0
|
997 @Override
|
fiore@0
|
998 public void actionPerformed(ActionEvent arg0) {
|
fiore@0
|
999 getWizardComponents().getNextButton().doClick();
|
fiore@0
|
1000 }
|
fiore@0
|
1001 });
|
fiore@0
|
1002 prefixTextField.getAccessibleContext().setAccessibleName(checkBoxes[i].getText());
|
fiore@0
|
1003 prefixTextField.setColumns(5);
|
fiore@0
|
1004 prefixTextField.addKeyListener(SpeechUtilities.getSpeechKeyListener(true));
|
fiore@0
|
1005 panel.add(prefixTextField);
|
fiore@0
|
1006 }else{
|
fiore@0
|
1007 suffixTextField = new JTextField();
|
fiore@0
|
1008 suffixTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), "enter");
|
fiore@0
|
1009 suffixTextField.getActionMap().put("enter", new AbstractAction(){
|
fiore@0
|
1010 @Override
|
fiore@0
|
1011 public void actionPerformed(ActionEvent arg0) {
|
fiore@0
|
1012 getWizardComponents().getNextButton().doClick();
|
fiore@0
|
1013 }
|
fiore@0
|
1014 });
|
fiore@0
|
1015 suffixTextField.getAccessibleContext().setAccessibleName(checkBoxes[i].getText());
|
fiore@0
|
1016 suffixTextField.setColumns(5);
|
fiore@0
|
1017 suffixTextField.addKeyListener(SpeechUtilities.getSpeechKeyListener(true));
|
fiore@0
|
1018 panel.add(suffixTextField);
|
fiore@0
|
1019 }
|
fiore@0
|
1020 checkBoxPanel.add(panel);
|
fiore@0
|
1021 }else{
|
fiore@0
|
1022 checkBoxPanel.add(checkBoxes[i]);
|
fiore@0
|
1023 }
|
fiore@0
|
1024 }
|
fiore@0
|
1025 JScrollPane scrollPane = new JScrollPane(checkBoxPanel);
|
fiore@0
|
1026 scrollPane.setFocusable(false);
|
fiore@0
|
1027 layoutComponents(scrollPane);
|
fiore@0
|
1028 dialog.getWizardComponents().getFinishButton().setEnabled(true);
|
fiore@0
|
1029 }
|
fiore@0
|
1030
|
fiore@0
|
1031 /* store the checks into the StrArrayRecord, it doesn't call super.next thus */
|
fiore@0
|
1032 /* sub classes have to implement call the switch panel on their own */
|
fiore@0
|
1033 public void next(){
|
fiore@0
|
1034 int numCheckedBoxes = 0;
|
fiore@0
|
1035 for(JCheckBox check : checkBoxes){
|
fiore@0
|
1036 if(check.isSelected())
|
fiore@0
|
1037 numCheckedBoxes++;
|
fiore@0
|
1038 }
|
fiore@0
|
1039 String[] result = new String[numCheckedBoxes];
|
fiore@0
|
1040 numCheckedBoxes = 0;
|
fiore@0
|
1041 for(int i=0; i<checkBoxes.length;i++){
|
fiore@0
|
1042 /* store the text value of the check boxes, if it's the prefix or suffix */
|
fiore@0
|
1043 /* append the text entered by the user in the text areas */
|
fiore@0
|
1044 if(checkBoxes[i].isSelected()){
|
fiore@0
|
1045 String text = checkBoxes[i].getText();
|
fiore@0
|
1046 if(i == 3)
|
fiore@0
|
1047 modifier.affix.values[PREFIX_INDEX] = prefixTextField.getText();
|
fiore@0
|
1048 else if(i == 4)
|
fiore@0
|
1049 modifier.affix.values[SUFFIX_INDEX] = suffixTextField.getText();
|
fiore@0
|
1050 result[numCheckedBoxes++] = text;
|
fiore@0
|
1051 }
|
fiore@0
|
1052 }
|
fiore@0
|
1053 modifier.format.values = result;
|
fiore@0
|
1054 Model.Modifier newModifier = new Model.Modifier();
|
fiore@0
|
1055 Model.copy(modifier,newModifier);
|
fiore@0
|
1056 property.modifiers.put(newModifier.id,newModifier);
|
fiore@0
|
1057 super.next();
|
fiore@0
|
1058 }
|
fiore@0
|
1059
|
fiore@0
|
1060 @Override
|
fiore@0
|
1061 public void update(){
|
fiore@0
|
1062 /* set the check boxes and text field according to the modifier.format. so if we are editing an existing *
|
fiore@0
|
1063 * modifier we find the old values, else if it's a new modifier we find everything blank */
|
fiore@0
|
1064 if(modifier.format != null){
|
fiore@0
|
1065 prefixTextField.setText("");
|
fiore@0
|
1066 suffixTextField.setText("");
|
fiore@0
|
1067 for(JCheckBox check : checkBoxes){
|
fiore@0
|
1068 /* temporarily remove the speech Item listener in order to avoid bla bla bla not triggered by user */
|
fiore@0
|
1069 check.removeItemListener(SpeechUtilities.getCheckBoxSpeechItemListener());
|
fiore@0
|
1070 check.setSelected(false);
|
fiore@0
|
1071 for(String checkedValue : modifier.format.values){
|
fiore@0
|
1072 if(checkedValue.equals(check.getText())){//for bold,italic,underline
|
fiore@0
|
1073 check.setSelected(true);
|
fiore@0
|
1074 if(checkedValue.equals(resources.getString("modifier.format.prefix"))){
|
fiore@0
|
1075 prefixTextField.setText(modifier.affix.values[PREFIX_INDEX]);
|
fiore@0
|
1076 }else if(checkedValue.equals(resources.getString("modifier.format.suffix"))){
|
fiore@0
|
1077 suffixTextField.setText(modifier.affix.values[SUFFIX_INDEX]);
|
fiore@0
|
1078 }
|
fiore@0
|
1079 break;
|
fiore@0
|
1080 }
|
fiore@0
|
1081 }
|
fiore@0
|
1082 check.addItemListener(SpeechUtilities.getCheckBoxSpeechItemListener());
|
fiore@0
|
1083 }
|
fiore@0
|
1084 }
|
fiore@0
|
1085 super.update();
|
fiore@0
|
1086 }
|
fiore@0
|
1087
|
fiore@0
|
1088 @Override
|
fiore@0
|
1089 protected Component assignFocus(){
|
fiore@0
|
1090 /* focus on the first item */
|
fiore@0
|
1091 checkBoxes[0].requestFocus();
|
fiore@0
|
1092 return checkBoxes[0];
|
fiore@0
|
1093 }
|
fiore@0
|
1094
|
fiore@0
|
1095 JTextField prefixTextField;
|
fiore@0
|
1096 JTextField suffixTextField;
|
fiore@0
|
1097 JPanel checkBoxPanel;
|
fiore@0
|
1098 JCheckBox checkBoxes[];
|
fiore@0
|
1099 }
|
fiore@0
|
1100
|
fiore@0
|
1101 @SuppressWarnings("serial")
|
fiore@0
|
1102 private class ArrowHeadPanel extends SpeechWizardPanel {
|
fiore@0
|
1103 ArrowHeadPanel(){
|
fiore@0
|
1104 super(dialog.getWizardComponents(),resources.getString("panel.edge_arrow_head.title"),EDGES,EDGE_YESNO_ARROW_HEAD);
|
fiore@0
|
1105 JPanel panel = new JPanel(new GridBagLayout());
|
fiore@0
|
1106 final JScrollPane scrollPane = new JScrollPane(panel);
|
fiore@0
|
1107 scrollPane.setFocusable(false);
|
fiore@0
|
1108 GridBagUtilities gridBagUtils = new GridBagUtilities();
|
fiore@0
|
1109 int numArrowHeads = ArrowHead.values().length;
|
fiore@0
|
1110 arrowsCheckBoxes = new JCheckBox[numArrowHeads];
|
fiore@0
|
1111 arrowsTextDescriptions = new JTextField[numArrowHeads];
|
fiore@0
|
1112 for(int i=0; i<numArrowHeads; i++){
|
fiore@0
|
1113 /* set up the key bindings for all the check boxes and text fields */
|
fiore@0
|
1114 /* by pressing enter the wizard switches the next panel */
|
fiore@0
|
1115 arrowsCheckBoxes[i] = new JCheckBox(ArrowHead.values()[i].toString());
|
fiore@0
|
1116 arrowsCheckBoxes[i].getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), "enter");
|
fiore@0
|
1117 arrowsCheckBoxes[i].getActionMap().put("enter", new AbstractAction(){
|
fiore@0
|
1118 @Override
|
fiore@0
|
1119 public void actionPerformed(ActionEvent arg0) {
|
fiore@0
|
1120 getWizardComponents().getNextButton().doClick();
|
fiore@0
|
1121 }
|
fiore@0
|
1122 });
|
fiore@0
|
1123 arrowsTextDescriptions[i] = new JTextField();
|
fiore@0
|
1124 arrowsTextDescriptions[i].getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), "enter");
|
fiore@0
|
1125 arrowsTextDescriptions[i].getActionMap().put("enter", new AbstractAction(){
|
fiore@0
|
1126 @Override
|
fiore@0
|
1127 public void actionPerformed(ActionEvent arg0) {
|
fiore@0
|
1128 getWizardComponents().getNextButton().doClick();
|
fiore@0
|
1129 }
|
fiore@0
|
1130 });
|
fiore@0
|
1131 /* add the speech to the check boxes */
|
fiore@0
|
1132 arrowsCheckBoxes[i].addItemListener(SpeechUtilities.getCheckBoxSpeechItemListener());
|
fiore@0
|
1133
|
fiore@0
|
1134 arrowsTextDescriptions[i].setPreferredSize(new Dimension(TEXTFIELD_SIZE, arrowsTextDescriptions[i].getPreferredSize().height));
|
fiore@0
|
1135 arrowsTextDescriptions[i].getAccessibleContext().setAccessibleName(arrowsCheckBoxes[i].getText());
|
fiore@0
|
1136 arrowsTextDescriptions[i].addKeyListener(SpeechUtilities.getSpeechKeyListener(true));
|
fiore@0
|
1137 panel.add(arrowsCheckBoxes[i], gridBagUtils.label());
|
fiore@0
|
1138 panel.add(arrowsTextDescriptions[i],gridBagUtils.field());
|
fiore@0
|
1139 }
|
fiore@0
|
1140 layoutComponents(scrollPane);
|
fiore@0
|
1141 }
|
fiore@0
|
1142
|
fiore@0
|
1143 @Override
|
fiore@0
|
1144 public void update(){
|
fiore@0
|
1145 /* restore the values (checkbox + text) currently in edge.arrowHeads into the panel components */
|
fiore@0
|
1146 if(edge.arrowHeads != null){
|
fiore@0
|
1147 for(int i=0; i<arrowsCheckBoxes.length;i++){
|
fiore@0
|
1148 arrowsCheckBoxes[i].setSelected(false);
|
fiore@0
|
1149 arrowsTextDescriptions[i].setText("");
|
fiore@0
|
1150 for(int j=0; j< edge.arrowHeads.values.length; j++){
|
fiore@0
|
1151 if(arrowsCheckBoxes[i].getText().equals(edge.arrowHeads.values[j])){
|
fiore@0
|
1152 arrowsCheckBoxes[i].setSelected(true);
|
fiore@0
|
1153 arrowsTextDescriptions[i].setText(edge.arrowHeadsDescriptions.values[j]);
|
fiore@0
|
1154 break;
|
fiore@0
|
1155 }
|
fiore@0
|
1156 }
|
fiore@0
|
1157 }
|
fiore@0
|
1158 }
|
fiore@0
|
1159 super.update();
|
fiore@0
|
1160 }
|
fiore@0
|
1161 @Override
|
fiore@0
|
1162 public void next(){
|
fiore@0
|
1163 /* check that the user has entered a text for all of the selected check boxes */
|
fiore@0
|
1164 int numChecked = 0;//this is to keep count of the checked boxes, used after the check
|
fiore@0
|
1165 for(int i=0; i<arrowsCheckBoxes.length;i++){
|
fiore@0
|
1166 JCheckBox checkBox = arrowsCheckBoxes[i];
|
fiore@0
|
1167 if(checkBox.isSelected()){
|
fiore@0
|
1168 numChecked++;
|
fiore@0
|
1169 /* there cannot be a checked check box without the related textField filled in */
|
fiore@0
|
1170 if(arrowsTextDescriptions[i].getText().trim().isEmpty()){
|
fiore@0
|
1171 NarratorFactory.getInstance().speak(
|
fiore@0
|
1172 MessageFormat.format(
|
fiore@0
|
1173 resources.getString("dialog.error.empty_desc"),
|
fiore@0
|
1174 checkBox.getText())
|
fiore@0
|
1175 );
|
fiore@0
|
1176 return;
|
fiore@0
|
1177 }
|
fiore@0
|
1178 }
|
fiore@0
|
1179 }
|
fiore@0
|
1180 /* copy the label of the checked boxes and the text of the JTextField into the edge fields */
|
fiore@0
|
1181 edge.arrowHeads.values = new String[numChecked];
|
fiore@0
|
1182 edge.arrowHeadsDescriptions.values = new String[numChecked];
|
fiore@0
|
1183 numChecked = 0;
|
fiore@0
|
1184 for(int i=0; i<arrowsCheckBoxes.length;i++){
|
fiore@0
|
1185 if(arrowsCheckBoxes[i].isSelected()){
|
fiore@0
|
1186 edge.arrowHeads.values[numChecked] = arrowsCheckBoxes[i].getText();
|
fiore@0
|
1187 edge.arrowHeadsDescriptions.values[numChecked] = arrowsTextDescriptions[i].getText().trim();
|
fiore@0
|
1188 numChecked++;
|
fiore@0
|
1189 }
|
fiore@0
|
1190 }
|
fiore@0
|
1191 /* put the edge (copy of) into the model */
|
fiore@0
|
1192 Model.Edge newEdge = new Model.Edge();
|
fiore@0
|
1193 Model.copy(edge, newEdge);
|
fiore@0
|
1194 model.edges.put(newEdge.id,newEdge);
|
fiore@0
|
1195 super.next();
|
fiore@0
|
1196 }
|
fiore@0
|
1197
|
fiore@0
|
1198 @Override
|
fiore@0
|
1199 protected Component assignFocus(){
|
fiore@0
|
1200 /* focus on the first item */
|
fiore@0
|
1201 arrowsCheckBoxes[0].requestFocus();
|
fiore@0
|
1202 return arrowsCheckBoxes[0];
|
fiore@0
|
1203 }
|
fiore@0
|
1204
|
fiore@0
|
1205 JCheckBox arrowsCheckBoxes[];
|
fiore@0
|
1206 JTextField arrowsTextDescriptions[];
|
fiore@0
|
1207 final int TEXTFIELD_SIZE = 100;
|
fiore@0
|
1208 }
|
fiore@0
|
1209 }
|