1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package de.desy.acop.displayers;
24
25 import java.awt.BorderLayout;
26 import java.awt.Color;
27 import java.awt.datatransfer.DataFlavor;
28 import java.awt.event.ActionEvent;
29 import java.awt.event.MouseAdapter;
30 import java.awt.event.MouseEvent;
31 import java.awt.event.MouseMotionListener;
32 import java.beans.PropertyVetoException;
33 import java.util.ArrayList;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.Map;
37
38 import javax.swing.AbstractAction;
39 import javax.swing.Action;
40 import javax.swing.JComponent;
41 import javax.swing.JPanel;
42 import javax.swing.JScrollPane;
43 import javax.swing.ListSelectionModel;
44 import javax.swing.TransferHandler;
45
46 import com.cosylab.gui.adapters.Converter;
47 import com.cosylab.gui.components.ObjectTable;
48 import com.cosylab.gui.components.customizer.AbstractCustomizerPanel;
49 import com.cosylab.gui.components.table.cells.TableCell;
50 import com.cosylab.gui.components.util.CosyTransferHandler;
51 import com.cosylab.gui.components.util.PopupManager;
52 import com.cosylab.gui.components.util.RunnerHelper;
53 import com.cosylab.gui.components.util.ScreenCapturer;
54 import com.cosylab.gui.displayers.DataConsumer;
55 import com.cosylab.gui.displayers.DataSource;
56 import com.cosylab.gui.displayers.DataState;
57 import com.cosylab.gui.displayers.DoubleSeqConsumer;
58 import com.cosylab.gui.util.DisplayerParametersFlavor;
59 import com.cosylab.gui.util.MultipleDisplayerParametersFlavor;
60 import com.cosylab.util.CommonException;
61
62 import de.desy.acop.displayers.selector.SelectorUtilities;
63 import de.desy.acop.displayers.table.AcopBitTableColumn;
64 import de.desy.acop.displayers.table.AcopNumericTableColumn;
65 import de.desy.acop.displayers.table.AcopStringTableColumn;
66 import de.desy.acop.displayers.table.AcopTableColumn;
67 import de.desy.acop.displayers.table.AcopTableModel;
68 import de.desy.acop.displayers.table.AcopTableParameters;
69 import de.desy.acop.displayers.table.AcopTableParametersFlavor;
70 import de.desy.acop.displayers.table.TableColumnType;
71 import de.desy.acop.displayers.tools.AcopMultipleDisplayerInfoDialog;
72 import de.desy.acop.displayers.tools.AcopTableTransferHandler;
73 import de.desy.acop.displayers.tools.ConnectionParametersFlavor;
74 import de.desy.acop.displayers.tools.MultipleAcopDisplayer;
75 import de.desy.acop.transport.AccessMode;
76 import de.desy.acop.transport.ConnectionFailed;
77 import de.desy.acop.transport.ConnectionParameters;
78 import de.desy.acop.transport.adapters.AcopTransportDataSource;
79 import de.desy.acop.transport.adapters.AdapterFactory;
80 import de.desy.acop.transport.adapters.AdapterFactoryService;
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 public class AcopTable extends JPanel implements MultipleAcopDisplayer<AcopTableParameters> {
102
103 private static final long serialVersionUID = -2993155391577813158L;
104 private JScrollPane scrollPane;
105 private ObjectTable table;
106 private AcopTableModel model;
107 private int suspended = 0;
108 private Map<String,AcopTableColumn> consumers= new HashMap<String,AcopTableColumn>();
109 private HashMap<AcopTableParameters, AcopTableColumn> connections = new HashMap<AcopTableParameters, AcopTableColumn>();
110 private DataState dataState = new DataState(DataState.NORMAL);
111 private PopupManager popupManager;
112 private AbstractCustomizerPanel customizer;
113 private AcopTableParameters selectedParameters;
114 private boolean popupEnabled;
115
116 private AcopMultipleDisplayerInfoDialog dialog;
117
118
119
120
121
122 public AcopTable() {
123 super();
124 initialize();
125 DataFlavor[] flavor = new DataFlavor[]{AcopTableParametersFlavor.FLAVOR,
126 MultipleDisplayerParametersFlavor.FLAVOR,
127 DisplayerParametersFlavor.FLAVOR,ConnectionParametersFlavor.FLAVOR,
128 DataFlavor.stringFlavor};
129 new AcopTableTransferHandler(this, true, true, flavor, false);
130 }
131
132
133
134
135
136
137 public AcopTableParameters getSelectedParameters() {
138 return selectedParameters;
139 }
140
141 private void initialize() {
142 this.setLayout(new BorderLayout());
143 scrollPane = new JScrollPane(getTable());
144 this.add(scrollPane, BorderLayout.CENTER);
145 setPopupEnabled(true);
146 scrollPane.addMouseListener(getPopupManager().getMouseHook());
147 getTable().addMouseListener(getPopupManager().getMouseHook());
148 setNumberOfRows(20);
149 getTable().getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
150 getTable().addMouseListener(new MouseAdapter() {
151 @Override
152 public void mousePressed(MouseEvent e) {
153 int row =getTable().getSelectedRow();
154 int column = getTable().getSelectedColumn();
155 if (row >= 0 && column >= 0) {
156 Object o = getTable().getModel().getValueAt(row, column);
157 if (o instanceof TableCell) {
158 Object source = ((TableCell)o).getDataSource();
159 if (source instanceof AcopTableColumn) {
160 AcopTableParameters parameters = ((AcopTableColumn)source).getDisplayerParameters();
161 if (SelectorUtilities.isChannel(parameters.getConnectionParameters())) {
162 try {
163 String device = ((String[])AdapterFactoryService.getInstance().getAdapterFactory().getCharacteristics(parameters.getConnectionParameters()).get("xLabels"))[row];
164 ConnectionParameters cp = parameters.getConnectionParameters();
165 ConnectionParameters newCP = new ConnectionParameters(cp.getAccessProtocol(), cp.getDeviceContext(), cp.getDeviceGroup(), device, cp.getDeviceProperty(), cp.getAccessMode(), cp.getAccessRate(), -1);
166 selectedParameters = parameters.deriveWith(newCP);
167 return;
168 } catch (ConnectionFailed e1) {
169 e1.printStackTrace();
170 }
171 }
172
173 if (SelectorUtilities.getSequenceLength(parameters.getConnectionParameters()) > 1) {
174 selectedParameters = new AcopTableParameters(parameters.getConnectionParameters().deriveWithPropertySize(-1), parameters.getColumnType(), row, parameters.getConverter(), parameters.getColumnName());
175 } else {
176 selectedParameters = parameters.deriveWith(parameters.getConnectionParameters().deriveWithPropertySize(-1));
177 }
178
179 }
180 }
181 }
182 }
183 });
184 }
185
186
187
188
189
190
191
192
193 public ObjectTable getTable() {
194 if (table == null) {
195 table = new ObjectTable();
196 table.setModel(getTableModel());
197 }
198 return table;
199 }
200
201 private AcopTableModel getTableModel() {
202 if (model == null) {
203 model = new AcopTableModel();
204 }
205 return model;
206 }
207
208
209
210
211 public void cleanup() {
212 for(AcopTableColumn c: consumers.values()) {
213 c.destroy();
214 }
215 consumers.clear();
216 }
217
218
219
220
221 public void suspend() {
222 suspended++;
223 }
224
225
226
227
228 public synchronized void resume() {
229 if (suspended>0) {
230 suspended--;
231 }
232 }
233
234
235
236
237 public boolean isSuspended() {
238 return suspended>0;
239 }
240
241
242
243
244 public DataState getDataState() {
245 return dataState;
246 }
247
248
249
250
251 public <D extends DataConsumer> D getConsumer(String name, Class<D> type) {
252 return getConsumer(name, name, type);
253 }
254
255 private <D extends DataConsumer> D getConsumer(String uniqueName, String shortName, Class<D> type) {
256
257 if (consumers.containsKey(uniqueName)) {
258 return type.cast(consumers.get(uniqueName));
259 }
260
261 AcopTableColumn c = null;
262 if (type.isAssignableFrom(AcopNumericTableColumn.class)) {
263 c = new AcopNumericTableColumn(this, uniqueName, shortName);
264 } else if (type.isAssignableFrom(AcopBitTableColumn.class)) {
265 c = new AcopBitTableColumn(this, uniqueName, shortName);
266 } else if (type.isAssignableFrom(AcopStringTableColumn.class)) {
267 c = new AcopStringTableColumn(this, uniqueName, shortName);
268 }
269
270 if (c != null) {
271 getTableModel().addColumn(c);
272 consumers.put(uniqueName,c);
273 return type.cast(c);
274 }
275
276 return null;
277 }
278
279
280
281
282 public void releaseConsumer(DataConsumer consumer) {
283 consumers.remove(consumer.getName()).destroy();
284 getTableModel().removeColumn((AcopTableColumn)consumer);
285 }
286
287
288
289
290 public DataConsumer[] getConsumers() {
291 return consumers.values().toArray(new DataConsumer[consumers.size()]);
292 }
293
294
295
296
297 @SuppressWarnings("unchecked")
298 public Class<DataConsumer>[] getSupportedConsumerTypes() {
299 return new Class[]{DoubleSeqConsumer.class};
300 }
301
302 private static String[] getDeviceNames(AcopTableParameters parameters) throws ConnectionFailed {
303 AdapterFactory factory = AdapterFactoryService.getInstance().getAdapterFactory();
304 String[] names = (String[])factory.getCharacteristics(parameters.getConnectionParameters()).get("xLabels");
305 int size = parameters.getConnectionParameters().getPropertySize();
306 if (size <= 0 || size == names.length) {
307 return names;
308 }
309 String[] retVal = new String[size];
310 for (int i = 0; i < size; i++) {
311 retVal[i] = names[i];
312 }
313 return retVal;
314 }
315
316
317
318
319
320 public void addDisplayerParameters(AcopTableParameters parameters) throws CommonException, PropertyVetoException {
321 if (parameters == null) return;
322 if (connections.get(parameters) != null) {
323 return;
324 }
325 suspend();
326 AcopTableParameters[] old = getDisplayerParameters();
327 AcopTableColumn consumer = null;
328 AdapterFactory factory = AdapterFactoryService.getInstance().getAdapterFactory();
329 if (parameters.getColumnType() == TableColumnType.NAME) {
330 consumer = getConsumer(parameters.toString(), parameters.getName(), AcopStringTableColumn.class);
331 consumer.setDisplayerParameters(parameters);
332 ((AcopStringTableColumn)consumer).updateValue(0,getDeviceNames(parameters));
333 } else {
334 if (parameters.getColumnType() == TableColumnType.STRING) {
335 consumer = getConsumer(parameters.toString(), parameters.getName(), AcopStringTableColumn.class);
336 } else if (parameters.getColumnType() == TableColumnType.BIT) {
337 consumer = getConsumer(parameters.toString(), parameters.getName(), AcopBitTableColumn.class);
338 } else {
339 consumer = getConsumer(parameters.toString(), parameters.getName(), AcopNumericTableColumn.class);
340 }
341 AcopTransportDataSource ds = factory.createDataSource(parameters.getConnectionParameters());
342 if (parameters.getConverter() != null && !parameters.getColumnType().equals(TableColumnType.STRING)){
343 Converter c = parameters.getConverter();
344 c.addConsumer(consumer);
345 ds.addConsumer(c);
346 }
347 else {
348 ds.addConsumer(consumer);
349 }
350 consumer.setDisplayerParameters(parameters);
351 }
352
353 connections.put(parameters, consumer);
354 resume();
355 firePropertyChange(MultipleAcopDisplayer.DISPLAYER_PARAMETERS_PROPERTY, old, getDisplayerParameters());
356 }
357
358
359
360
361
362
363 public void addConnectionParameters(ConnectionParameters parameters) throws CommonException, PropertyVetoException {
364
365 addDisplayerParameters(new AcopTableParameters(parameters, TableColumnType.VALUE, null));
366 }
367
368
369
370
371
372 public AcopTableParameters[] getDisplayerParameters() {
373 AcopTableParameters[] params = new AcopTableParameters[connections.keySet().size()];
374 return connections.keySet().toArray(params);
375 }
376
377
378
379
380
381
382 public ConnectionParameters[] getConnectionParameters() {
383
384 AcopTableParameters[] agp = getDisplayerParameters();
385 ConnectionParameters[] cp = new ConnectionParameters[agp.length];
386 for (int i = 0; i < agp.length; i++) {
387 cp[i] = agp[i].getConnectionParameters();
388 }
389 return cp;
390 }
391
392
393
394
395
396 public DataSource removeDisplayerParameters(AcopTableParameters parameters) {
397 AcopTableParameters[] old = getDisplayerParameters();
398 AdapterFactory factory = AdapterFactoryService.getInstance().getAdapterFactory();
399 AcopTableColumn consumer = connections.remove(parameters);
400 if (consumer == null) return null;
401 DataSource ds = null;
402 if (parameters.getColumnType() != TableColumnType.NAME) {
403 ds = factory.releaseDataSource(parameters.getConnectionParameters());
404 if (parameters.getConverter() != null) {
405 ds.removeConsumer(parameters.getConverter());
406 parameters.getConverter().removeConsumer(consumer);
407 } else {
408 ds.removeConsumer(consumer);
409 }
410 }
411 releaseConsumer(consumer);
412 firePropertyChange(MultipleAcopDisplayer.DISPLAYER_PARAMETERS_PROPERTY, old, getDisplayerParameters());
413 return ds;
414
415 }
416
417
418
419
420
421
422 public DataSource removeConnectionParameters(ConnectionParameters parameters) {
423 AcopTableParameters[] old = getDisplayerParameters();
424 DataSource ds = null;
425 for (AcopTableParameters p : old) {
426 if (p.getConnectionParameters().equals(parameters)) {
427 AdapterFactory factory = AdapterFactoryService.getInstance().getAdapterFactory();
428 AcopTableColumn consumer = connections.remove(parameters);
429 if (consumer == null) continue;
430 ds = factory.releaseDataSource(parameters);
431 ds.removeConsumer(consumer);
432 releaseConsumer(consumer);
433 }
434 }
435 firePropertyChange(MultipleAcopDisplayer.DISPLAYER_PARAMETERS_PROPERTY, old, getDisplayerParameters());
436 return ds;
437 }
438
439
440
441
442
443 public void setDisplayerParameters(AcopTableParameters[] parameters) throws CommonException, PropertyVetoException {
444 AcopTableParameters[] old = getDisplayerParameters();
445 ArrayList<AcopTableParameters> toBeRemoved = new ArrayList<AcopTableParameters>();
446 Iterator<AcopTableParameters> it = connections.keySet().iterator();
447 while(it.hasNext()) {
448 toBeRemoved.add(it.next());
449 }
450
451 ArrayList<AcopTableParameters> toBeAdded = new ArrayList<AcopTableParameters>();
452
453 for (AcopTableParameters p : parameters) {
454 if (toBeRemoved.contains(p)) {
455 toBeRemoved.remove(p);
456 } else {
457 toBeAdded.add(p);
458 }
459 }
460
461 for(AcopTableParameters p : toBeRemoved) {
462 removeDisplayerParameters(p);
463 }
464
465 for(AcopTableParameters p : toBeAdded) {
466 addDisplayerParameters(p);
467 }
468
469 firePropertyChange(MultipleAcopDisplayer.DISPLAYER_PARAMETERS_PROPERTY, old, parameters);
470 }
471
472
473
474
475
476 public void setConnectionParameters(ConnectionParameters[] parameters) throws CommonException, PropertyVetoException {
477
478 AcopTableParameters[] agp = new AcopTableParameters[parameters.length];
479 for (int i = 0; i < parameters.length; i++) {
480 agp[i] = new AcopTableParameters(parameters[i], TableColumnType.VALUE, null);
481 }
482 setDisplayerParameters(agp);
483 }
484
485
486
487
488
489
490 public AbstractCustomizerPanel getCustomizer()
491 {
492 if (customizer == null) {
493 customizer = AbstractCustomizerPanel.findCustomizer(this);
494 }
495 return customizer;
496 }
497
498
499
500
501
502 public PopupManager getPopupManager() {
503 if (popupManager == null) {
504 popupManager = new PopupManager(this, false);
505 popupManager.addAction(new AbstractAction("Preferences...") {
506 private static final long serialVersionUID = 1L;
507 public void actionPerformed(ActionEvent e)
508 {
509 getCustomizer().showDialog();
510 }
511 });
512
513 popupManager.addAction(new AbstractAction("Capture screen..."){
514 private static final long serialVersionUID = 1L;
515
516 public void actionPerformed(ActionEvent e){
517 ScreenCapturer sc = new ScreenCapturer(AcopTable.this);
518 sc.showScreenDialog();
519 }
520 });
521
522 popupManager.addAction(new AbstractAction("Info...") {
523 private static final long serialVersionUID = 1L;
524 public void actionPerformed(ActionEvent e)
525 {
526 getInfoDialog().setVisible(true);
527 }
528 });
529 }
530 return popupManager;
531 }
532
533
534
535
536
537
538 public boolean isPopupEnabled() {
539 return popupEnabled;
540 }
541
542
543
544
545
546
547 public void setPopupEnabled(boolean enabled) {
548 if (popupEnabled == enabled) return;
549 popupEnabled = enabled;
550 if (enabled) {
551 addMouseListener(getPopupManager().getMouseHook());
552 } else {
553 removeMouseListener(getPopupManager().getMouseHook());
554 }
555 firePropertyChange("popupEnabled",!popupEnabled,popupEnabled);
556 }
557
558
559
560
561
562 public int getNumberOfRows() {
563 return getTableModel().getRowCount();
564 }
565
566
567
568
569
570 public void setNumberOfRows(int numberOfRows) {
571 getTableModel().setRowCount(numberOfRows);
572 }
573
574
575
576
577
578 @Override
579 public void setTransferHandler(TransferHandler newHandler) {
580 super.setTransferHandler(newHandler);
581 CosyTransferHandler.registerTransferHandler(this, newHandler, new JComponent[]{scrollPane, getTable()});
582 }
583
584
585
586
587
588
589 @Override
590 public synchronized void removeMouseMotionListener(MouseMotionListener l) {
591 super.removeMouseMotionListener(l);
592 scrollPane.removeMouseMotionListener(l);
593 getTable().removeMouseMotionListener(l);
594 }
595
596
597
598
599
600
601
602 public void setDragEnabled(boolean enabled) {
603 if (getTransferHandler() instanceof CosyTransferHandler) {
604 if (((CosyTransferHandler)getTransferHandler()).isExportEnabled() == enabled) return;
605
606 ((CosyTransferHandler)getTransferHandler()).setExportEnabled(enabled, this);
607 }
608 }
609
610
611
612
613
614
615 public boolean isDragEnabled() {
616 if (getTransferHandler() instanceof CosyTransferHandler) {
617 return ((CosyTransferHandler)getTransferHandler()).isExportEnabled();
618 } else {
619 return getTransferHandler() != null;
620 }
621 }
622
623
624
625
626
627
628
629 public void setDropEnabled(boolean enabled) {
630 if (getTransferHandler() instanceof CosyTransferHandler) {
631 if (((CosyTransferHandler)getTransferHandler()).isReceiveEnabled() == enabled) return;
632
633 ((CosyTransferHandler)getTransferHandler()).setReceiveEnabled(enabled, this);
634 }
635 }
636
637
638
639
640
641
642 public boolean isDropEnabled() {
643 if (getTransferHandler() instanceof CosyTransferHandler) {
644 return ((CosyTransferHandler)getTransferHandler()).isReceiveEnabled();
645 } else {
646 return getTransferHandler() != null;
647 }
648 }
649
650
651
652
653
654
655 public AcopMultipleDisplayerInfoDialog getInfoDialog() {
656 if (dialog == null) {
657 dialog = new AcopMultipleDisplayerInfoDialog(this);
658 }
659 return dialog;
660 }
661
662
663
664
665
666 public void setPropertiesPopupEnabled(boolean enable) {
667 Action[] actions = getPopupManager().getActions();
668 for (Action a : actions) {
669 if (a != null && "Preferences...".equals(a.getValue(Action.NAME))) {
670 a.setEnabled(enable);
671 return;
672 }
673 }
674 }
675
676
677
678
679
680 public boolean isPropertiesPopupEnabled() {
681 Action[] actions = getPopupManager().getActions();
682 for (Action a : actions) {
683 if (a != null && "Preferences...".equals(a.getValue(Action.NAME))) {
684 return a.isEnabled();
685 }
686 }
687 return false;
688 }
689
690
691
692
693
694
695 public void setReorderingAllowed(boolean reorderingAllowed) {
696 if (getReorderingAllowed() == reorderingAllowed) return;
697 getTable().getTableHeader().setReorderingAllowed(reorderingAllowed);
698 firePropertyChange("reordeningAllowed", !reorderingAllowed, reorderingAllowed);
699 }
700
701
702
703
704
705
706 public boolean getReorderingAllowed() {
707 return getTable().getTableHeader().getReorderingAllowed();
708 }
709
710
711
712
713
714 @Override
715 public void setBackground(Color bg) {
716 super.setBackground(bg);
717 getTable().setBackground(bg);
718 }
719
720
721
722
723
724 @Override
725 public void setForeground(Color fg) {
726 super.setForeground(fg);
727 getTable().setForeground(fg);
728 }
729
730
731
732 public static void main(String[] args) throws CommonException, PropertyVetoException {
733 AcopTable table = new AcopTable();
734 table.setForeground(Color.RED);
735
736
737
738
739
740 table.addDisplayerParameters(new AcopTableParameters(new ConnectionParameters("TINE", "WORKSHOP", "WKSineGen","Device 0", "Amplitude", AccessMode.POLL, 1000), TableColumnType.VALUE, "bla"));
741
742 RunnerHelper.runComponent(table, 800, 600);
743 }
744
745 }