1
2
3
4 package org.ximtec.igesture.tool.view.admin.panel;
5
6 import java.awt.BorderLayout;
7 import java.awt.Color;
8 import java.awt.Dimension;
9 import java.awt.GridBagConstraints;
10 import java.awt.GridBagLayout;
11 import java.awt.event.ActionEvent;
12 import java.awt.event.ActionListener;
13 import java.awt.event.ItemEvent;
14 import java.awt.event.ItemListener;
15 import java.awt.event.KeyEvent;
16 import java.net.URL;
17 import java.util.ArrayList;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24 import java.util.concurrent.ConcurrentSkipListMap;
25 import java.util.logging.Level;
26 import java.util.logging.Logger;
27
28 import javax.swing.Action;
29 import javax.swing.BorderFactory;
30 import javax.swing.DefaultListModel;
31 import javax.swing.JButton;
32 import javax.swing.JCheckBox;
33 import javax.swing.JComboBox;
34 import javax.swing.JLabel;
35 import javax.swing.JList;
36 import javax.swing.JOptionPane;
37 import javax.swing.JPanel;
38 import javax.swing.JScrollPane;
39 import javax.swing.JSpinner;
40 import javax.swing.JTextField;
41 import javax.swing.ListSelectionModel;
42 import javax.swing.SpinnerNumberModel;
43
44 import org.sigtec.graphix.GridBagLayouter;
45 import org.w3c.dom.Node;
46 import org.w3c.dom.NodeList;
47 import org.ximtec.igesture.core.GestureClass;
48 import org.ximtec.igesture.core.GestureSet;
49 import org.ximtec.igesture.core.composite.CompositeDescriptor;
50 import org.ximtec.igesture.core.composite.Constraint;
51 import org.ximtec.igesture.core.composite.DefaultConstraint;
52 import org.ximtec.igesture.core.composite.DefaultConstraintEntry;
53 import org.ximtec.igesture.io.AbstractGestureDevice;
54 import org.ximtec.igesture.io.DeviceManagerListener;
55 import org.ximtec.igesture.io.IDeviceManager;
56 import org.ximtec.igesture.tool.GestureConstants;
57 import org.ximtec.igesture.tool.binding.ConstraintTextFieldBinding;
58 import org.ximtec.igesture.tool.core.Controller;
59 import org.ximtec.igesture.tool.service.DeviceManagerService;
60 import org.ximtec.igesture.tool.util.Formatter;
61 import org.ximtec.igesture.tool.view.MainController;
62 import org.ximtec.igesture.tool.view.MainModel;
63 import org.ximtec.igesture.tool.view.admin.action.AddGestureClassToConstraintAction;
64 import org.ximtec.igesture.tool.view.admin.action.RemoveAllGestureClassesFromConstraintAction;
65 import org.ximtec.igesture.tool.view.admin.action.RemoveGestureClassFromConstraintAction;
66 import org.ximtec.igesture.util.XMLParser;
67
68 import com.jgoodies.forms.builder.DefaultFormBuilder;
69 import com.jgoodies.forms.layout.FormLayout;
70
71
72
73
74
75 public class CompositeDescriptorPanel extends DefaultDescriptorPanel<CompositeDescriptor> implements DeviceManagerListener{
76
77 private static final Logger LOGGER = Logger.getLogger(CompositeDescriptorPanel.class.getName());
78
79 private static final int INPUTAREA_SIZE = 200;
80
81 private static final String SELECT_SET = "Select a set";
82 private static final String SELECT_GESTURE = "Select a gesture";
83 private static final String SELECT_DEVICE_TYPE = "Select a device type";
84
85 private JComboBox cmbSets, cmbGestures, cmbDevices;
86 private JCheckBox chkUser, chkDevices;
87 private JSpinner spinUser;
88 private JList devicesList, gestureList;
89 private JButton btnRemove, btnClear, btnAdd;
90
91 private IDeviceManager deviceManager;
92
93 private Map<String, String> deviceMapping;
94
95 private Constraint constraint;
96
97 public CompositeDescriptorPanel(Controller controller, CompositeDescriptor descriptor) {
98 super(controller, descriptor);
99
100 deviceManager = controller.getLocator().getService(DeviceManagerService.IDENTIFIER, IDeviceManager.class);
101 deviceManager.addDeviceManagerListener(this);
102 constraint = descriptor.getConstraint();
103 ((DefaultConstraint)constraint).addPropertyChangeListener(controller.getLocator().getService(MainController.IDENTIFIER,MainController.class));
104 init();
105 }
106
107 private void init()
108 {
109 initTitle();
110 initParameterSection();
111 initInputSection();
112 }
113
114
115
116
117 private void initParameterSection()
118 {
119 JPanel panel = new JPanel();
120
121 FormLayout layout = new FormLayout(
122 "100dlu, 4dlu, 100dlu",
123 "pref, 4dlu, pref, 4dlu, pref, 4dlu, pref, 4dlu, pref, 4dlu, pref, 4dlu, pref, 4dlu, pref, 4dlu, pref, 4dlu, pref, 4dlu, pref");
124
125 DefaultFormBuilder builder = new DefaultFormBuilder(layout);
126 builder.setDefaultDialogBorder();
127
128 builder.append(getComponentFactory().createLabel(GestureConstants.CONFIGURATION_PANEL_PARAMETERS));
129 builder.nextLine(2);
130
131
132 Map<String, String> parameter = getDescriptor().getConstraint().getParameters();
133 ConcurrentSkipListMap<String, String> map = new ConcurrentSkipListMap<String,String>();
134 map.putAll(parameter);
135 for (String parameterName : parameter.keySet()) {
136 builder.append(new JLabel(parameterName));
137 JTextField paramTextField = new JTextField();
138 new ConstraintTextFieldBinding(paramTextField, (DefaultConstraint)constraint, parameterName);
139 builder.append(paramTextField);
140 builder.nextLine(2);
141 }
142
143 JPanel paramPanel = builder.getPanel();
144 paramPanel.setOpaque(true);
145 paramPanel.setBackground(Color.WHITE);
146
147 panel.add(paramPanel,BorderLayout.CENTER);
148
149 panel.setOpaque(true);
150 panel.setAutoscrolls(true);
151 setContent(panel);
152 }
153
154
155
156
157
158 private void initInputSection()
159 {
160
161 deviceMapping = new HashMap<String, String>();
162 XMLParser parser = new XMLParser(){
163
164 @Override
165 public void execute(ArrayList<NodeList> nodeLists) {
166 String name = ((Node)nodeLists.get(0).item(0)).getNodeValue();
167 String clazz = ((Node)nodeLists.get(1).item(0)).getNodeValue();
168 deviceMapping.put(name, clazz);
169 }
170
171 };
172 ArrayList<String> nodes = new ArrayList<String>();
173 nodes.add("name");
174 nodes.add("class");
175 try {
176 URL path = CompositeDescriptorPanel.class.getClassLoader().getResource("config.xml");
177 parser.parse(path.getFile(),"device", nodes);
178 } catch (Exception e) {
179 LOGGER.log(Level.SEVERE,"Could not parse configuration file (config.xml - devices).",e);
180 };
181
182 //
183
184 JLabel lblSets = getComponentFactory().createLabel(GestureConstants.COMPOSITE_DESCRIPTOR_GESTURE_SETS);
185 cmbSets = new JComboBox(getController().getLocator().getService(MainModel.IDENTIFIER, MainModel.class)
186 .getGestureSets().toArray());
187 cmbSets.insertItemAt(SELECT_SET, 0);
188 cmbSets.setSelectedIndex(0);
189
190 JLabel lblGestures = getComponentFactory().createLabel(GestureConstants.COMPOSITE_DESCRIPTOR_GESTURE_CLASSES);
191 cmbGestures = new JComboBox(new Object[]{SELECT_GESTURE});
192 cmbGestures.setEnabled(false);
193
194 cmbSets.addActionListener(new ActionListener(){
195
196 @Override
197 public void actionPerformed(ActionEvent e) {
198
199
200 JComboBox source = (JComboBox) e.getSource();
201
202 cmbGestures.removeAllItems();
203 cmbGestures.addItem(SELECT_GESTURE);
204
205 if(source.getSelectedIndex() == 0)
206 {
207 cmbGestures.setEnabled(false);
208 }
209 else
210 {
211 cmbGestures.setEnabled(true);
212 GestureSet set = (GestureSet) cmbSets.getSelectedItem();
213
214 Object[] items = set.getGestureClasses().toArray();
215 for (int i = 0; i < items.length; i++) {
216 cmbGestures.addItem(items[i]);
217 }
218 }
219 }
220
221 });
222
223
224 chkUser = createCheckBox("User:",KeyEvent.VK_U);
225 spinUser = new JSpinner(new SpinnerNumberModel(0,0,100,1));
226 spinUser.setEnabled(false);
227 chkUser.addItemListener(new ItemListener(){
228
229 @Override
230 public void itemStateChanged(ItemEvent e) {
231
232 JCheckBox source = (JCheckBox) e.getSource();
233 spinUser.setEnabled(source.isSelected());
234 }
235
236 });
237
238
239
240 chkDevices = createCheckBox("Device(s):", KeyEvent.VK_D);
241 cmbDevices = new JComboBox(deviceMapping.keySet().toArray());
242 cmbDevices.setEnabled(false);
243 cmbDevices.insertItemAt(SELECT_DEVICE_TYPE, 0);
244 cmbDevices.setSelectedIndex(0);
245
246 devicesList = new JList();
247 DefaultListModel devicesModel = new DefaultListModel();
248 devicesList.setModel(devicesModel);
249 devicesList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
250 devicesList.setEnabled(false);
251
252 final JScrollPane scrollDevicesList = new JScrollPane(devicesList);
253 scrollDevicesList.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.GRAY),
254 "Devices"));
255 scrollDevicesList.setPreferredSize(new Dimension(INPUTAREA_SIZE,INPUTAREA_SIZE/2));
256 scrollDevicesList.setEnabled(false);
257
258 chkDevices.addItemListener(new ItemListener(){
259
260 @Override
261 public void itemStateChanged(ItemEvent e) {
262
263 JCheckBox source = (JCheckBox)e.getSource();
264 boolean selected = source.isSelected();
265 cmbDevices.setEnabled(selected);
266 scrollDevicesList.setEnabled(selected);
267 devicesList.setEnabled(selected);
268 }
269
270 });
271 cmbDevices.addActionListener(new ActionListener(){
272
273 @Override
274 public void actionPerformed(ActionEvent e) {
275 JComboBox source = (JComboBox)e.getSource();
276
277 if(source.getSelectedIndex() != 0)
278 {
279
280 DefaultListModel model = new DefaultListModel();
281 for(Iterator<AbstractGestureDevice<?,?>> iterator = deviceManager.getDevices().iterator(); iterator.hasNext();)
282 {
283 AbstractGestureDevice< ?, ?> device = iterator.next();
284 if(device.getClass().getName().equals(deviceMapping.get(source.getSelectedItem())))
285 {
286 model.addElement(device.getDeviceID());
287 }
288 }
289 devicesList.setModel(model);
290 }
291 else
292 devicesList.setModel(new DefaultListModel());
293 }
294
295 });
296
297 JPanel contentPanel = new JPanel();
298 contentPanel.setLayout(new GridBagLayout());
299 GridBagLayouter.addComponent(contentPanel, lblSets,
300 0, 0, 1, 1, 0, 0, 0, 0, 0.5, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
301 GridBagLayouter.addComponent(contentPanel, cmbSets,
302 1, 0, 1, 1, 0, 0, 0, 0, 0.5, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
303 GridBagLayouter.addComponent(contentPanel, lblGestures,
304 0, 1, 1, 1, 0, 0, 0, 0, 0.5, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
305 GridBagLayouter.addComponent(contentPanel, cmbGestures,
306 1, 1, 1, 1, 0, 0, 0, 0, 0.5, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
307 GridBagLayouter.addComponent(contentPanel, chkUser,
308 2, 0, 1, 1, 0, 0, 0, 0, 0.5, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
309 GridBagLayouter.addComponent(contentPanel, spinUser,
310 3, 0, 1, 1, 0, 0, 0, 0, 0.5, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
311 GridBagLayouter.addComponent(contentPanel, chkDevices,
312 2, 1, 1, 1, 0, 0, 0, 0, 0.5, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
313 GridBagLayouter.addComponent(contentPanel, cmbDevices,
314 3, 1, 1, 1, 0, 0, 0, 0, 0.5, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
315 GridBagLayouter.addComponent(contentPanel, scrollDevicesList,
316 3, 2, 1, 3, 0, 0, 0, 0, 0.5, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
317
318 btnAdd = createButton(
319 GestureConstants.ADD_GESTURE_CLASS_TO_CONSTRAINT,
320 new AddGestureClassToConstraintAction(getController(),this),false);
321 btnRemove = createButton(
322 GestureConstants.REMOVE_GESTURE_CLASS_FROM_CONSTRAINT,
323 new RemoveGestureClassFromConstraintAction(getController(),this),false);
324 btnClear = createButton(
325 GestureConstants.REMOVE_ALL_GESTURE_CLASSES_FROM_CONSTRAINT,
326 new RemoveAllGestureClassesFromConstraintAction(getController(),this),false);
327
328 cmbGestures.addActionListener(new ActionListener(){
329
330 @Override
331 public void actionPerformed(ActionEvent e) {
332 JComboBox source = (JComboBox)e.getSource();
333
334 if(source.getSelectedIndex() == 0)
335 btnAdd.setEnabled(false);
336 else
337 btnAdd.setEnabled(true);
338
339 }
340
341 });
342
343 GridBagLayouter.addComponent(contentPanel, btnAdd,
344 1, 2, 1, 1, 0, 0, 0, 0, 0.5, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
345 GridBagLayouter.addComponent(contentPanel, btnRemove,
346 0, 4, 1, 1, 0, 0, 0, 0, 0.5, 0, GridBagConstraints.PAGE_END, GridBagConstraints.HORIZONTAL);
347 GridBagLayouter.addComponent(contentPanel, btnClear,
348 1, 4, 1, 1, 0, 0, 0, 0, 0.5, 0, GridBagConstraints.PAGE_END, GridBagConstraints.HORIZONTAL);
349
350 JPanel basePanel = new JPanel();
351 basePanel.setLayout(new BorderLayout());
352 basePanel.add(contentPanel,BorderLayout.CENTER);
353
354
355 gestureList = new JList();
356 DefaultListModel gesturesModel = new DefaultListModel();
357 gestureList.setModel(gesturesModel);
358 gestureList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
359
360
361 List<DefaultConstraintEntry> entries = getDescriptor().getConstraint().getGestureEntries();
362 if(entries != null && !entries.isEmpty())
363 {
364
365 for (Iterator iterator = entries.iterator(); iterator.hasNext();) {
366 DefaultConstraintEntry entry = (DefaultConstraintEntry) iterator.next();
367 gesturesModel.addElement(entry);
368 }
369
370
371 btnRemove.setEnabled(true);
372 btnClear.setEnabled(true);
373 }
374
375
376 JScrollPane scrollResultList = new JScrollPane(gestureList);
377 scrollResultList.setPreferredSize(new Dimension(basePanel.getWidth(),INPUTAREA_SIZE/2));
378 basePanel.add(scrollResultList,BorderLayout.SOUTH);
379
380 setBottom(basePanel);
381 }
382
383
384
385
386
387
388
389
390 private JButton createButton(String key, Action action, boolean enabled)
391 {
392 JButton btn = getComponentFactory().createButton(key,action);
393 btn.setEnabled(enabled);
394 Formatter.formatButton(btn);
395 return btn;
396 }
397
398
399
400
401 private JCheckBox createCheckBox(String text, int mnemonic)
402 {
403 JCheckBox chk = new JCheckBox(text);
404 chk.setMnemonic(mnemonic);
405 return chk;
406 }
407
408
409
410
411 public void removeGestureClass()
412 {
413
414 DefaultListModel model = (DefaultListModel)gestureList.getModel();
415 DefaultConstraintEntry entry = (DefaultConstraintEntry) gestureList.getSelectedValue();
416 model.removeElement(entry);
417
418 getDescriptor().getConstraint().removeGestureClass(entry);
419
420
421 if(model.getSize() == 0)
422 {
423 btnRemove.setEnabled(false);
424 btnClear.setEnabled(false);
425 }
426 }
427
428
429
430
431 public void removeAllGestureClasses()
432 {
433
434 DefaultListModel model = (DefaultListModel)gestureList.getModel();
435 model.removeAllElements();
436
437 getDescriptor().getConstraint().removeAllGestureClasses();
438
439
440 btnRemove.setEnabled(false);
441 btnClear.setEnabled(false);
442 }
443
444
445
446
447 public void addGestureClass()
448 {
449 String gestureClass = null, deviceType = null;
450 int user = -1;
451 Set<String> devices = null;
452
453
454 GestureClass gs = (GestureClass)cmbGestures.getSelectedItem();
455 gestureClass = gs.getName()+":"+gs.getId();
456
457
458 if(chkUser.isSelected())
459 user = ((Integer)spinUser.getValue()).intValue();
460
461
462 if(chkDevices.isSelected())
463 {
464 deviceType = cmbDevices.getSelectedItem().toString();
465
466 if(!devicesList.isSelectionEmpty())
467 {
468 devices = new HashSet<String>();
469 Object[] values = devicesList.getSelectedValues();
470 for (int i = 0; i < values.length; i++) {
471 devices.add(values[i].toString());
472 }
473 }
474 }
475 try
476 {
477
478 if(chkUser.isSelected() && chkDevices.isSelected())
479 getDescriptor().getConstraint().addGestureClass(gestureClass, user, deviceType, devices);
480 else if(chkUser.isSelected())
481 getDescriptor().getConstraint().addGestureClass(gestureClass, user);
482 else if(chkDevices.isSelected())
483 getDescriptor().getConstraint().addGestureClass(gestureClass, deviceType, devices);
484 else
485 getDescriptor().getConstraint().addGestureClass(gestureClass);
486
487
488 List<DefaultConstraintEntry> entries = getDescriptor().getConstraint().getGestureEntries();
489 DefaultConstraintEntry entry = entries.get(entries.size()-1);
490 DefaultListModel model = (DefaultListModel)gestureList.getModel();
491 model.addElement(entry);
492 }
493 catch(IllegalArgumentException e)
494 {
495
496 LOGGER.log(Level.SEVERE,"Constraint Configuration Error.",e);
497 JOptionPane.showMessageDialog(null, e.getMessage(), "Constraint Configuration Error", JOptionPane.ERROR_MESSAGE);
498 }
499
500
501 btnClear.setEnabled(true);
502 btnRemove.setEnabled(true);
503 }
504
505
506
507
508 @Override
509 public void updateDeviceManagerListener(int operation, AbstractGestureDevice<?, ?> device) {
510
511 if(cmbDevices.getSelectedIndex() != 0)
512 {
513 if(operation == DeviceManagerListener.ADD && device.getClass().getSimpleName().equals(cmbDevices.getSelectedItem().toString()))
514 {
515 ((DefaultListModel)devicesList.getModel()).addElement(device.getDeviceID());
516 }
517 else if(operation == DeviceManagerListener.REMOVE && device.getClass().getSimpleName().equals(cmbDevices.getSelectedItem().toString()))
518 {
519 ((DefaultListModel)devicesList.getModel()).removeElement(device.getDeviceID());
520 }
521 }
522 }
523
524 }