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.Color;
26 import java.awt.datatransfer.DataFlavor;
27 import java.awt.event.ActionEvent;
28 import java.beans.PropertyVetoException;
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.Iterator;
32 import java.util.Map;
33
34 import javax.swing.AbstractAction;
35 import javax.swing.Action;
36
37 import com.cosylab.gui.adapters.Converter;
38 import com.cosylab.gui.components.util.CosyTransferHandler;
39 import com.cosylab.gui.components.util.PopupManager;
40 import com.cosylab.gui.displayers.DataConsumer;
41 import com.cosylab.gui.displayers.DataSource;
42 import com.cosylab.gui.displayers.DataState;
43 import com.cosylab.gui.displayers.DoubleSeqConsumer;
44 import com.cosylab.gui.displayers.MultipleDisplayer;
45 import com.cosylab.gui.components.util.ColorManager;
46 import com.cosylab.gui.util.MultipleDisplayerParametersFlavor;
47 import com.cosylab.gui.util.UserSettingsProtection;
48 import com.cosylab.util.CommonException;
49
50 import de.desy.acop.chart.Acop;
51 import de.desy.acop.displayers.tools.AcopChartConsumer;
52 import de.desy.acop.displayers.tools.AcopDisplayerParametersFlavor;
53 import de.desy.acop.displayers.tools.AcopDisplayerParameters;
54 import de.desy.acop.displayers.tools.AcopGraphParameters;
55 import de.desy.acop.displayers.tools.AcopGraphParametersFlavor;
56 import de.desy.acop.displayers.tools.AcopMultipleDisplayerInfoDialog;
57 import de.desy.acop.displayers.tools.ConnectionParametersFlavor;
58 import de.desy.acop.displayers.tools.MultipleAcopDisplayer;
59 import de.desy.acop.displayers.tools.AcopChartTransferHandler;
60 import de.desy.acop.transport.ConnectionParameters;
61 import de.desy.acop.transport.adapters.AcopTransportDataSource;
62 import de.desy.acop.transport.adapters.AdapterFactory;
63 import de.desy.acop.transport.adapters.AdapterFactoryService;
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 public class AcopChart extends Acop implements MultipleDisplayer, MultipleAcopDisplayer<AcopGraphParameters> {
87
88 private static final long serialVersionUID = -2579109976414960938L;
89
90 private int maxLinkIndex=0;
91 private int suspended=0;
92 private Map<String,AcopChartConsumer> consumers= new HashMap<String,AcopChartConsumer>();
93 private HashMap<AcopGraphParameters, AcopChartConsumer> connections = new HashMap<AcopGraphParameters, AcopChartConsumer>();
94 private DataState dataState = new DataState(DataState.NORMAL);
95 private AcopMultipleDisplayerInfoDialog dialog;
96 private PopupManager popupManager;
97 private ColorManager colorManager = new ColorManager();
98
99
100
101
102
103 public AcopChart() {
104 super();
105 DataFlavor[] flavor = new DataFlavor[]{AcopGraphParametersFlavor.FLAVOR,
106 MultipleDisplayerParametersFlavor.FLAVOR, AcopDisplayerParametersFlavor.FLAVOR,
107 ConnectionParametersFlavor.FLAVOR,
108 DataFlavor.stringFlavor};
109 new AcopChartTransferHandler(this, true, true, flavor, true);
110
111 UserSettingsProtection.setProtection(this,new String[]{"caption", "yMin", "yMax"},false);
112 }
113
114
115
116 public void cleanup() {
117 for(AcopChartConsumer c: consumers.values()) {
118 c.destroy();
119 }
120 consumers.clear();
121 }
122
123
124
125
126 public void suspend() {
127 suspended++;
128 }
129
130
131
132
133 public synchronized void resume() {
134 if (suspended>0) {
135 suspended--;
136 }
137 }
138
139
140
141
142 public boolean isSuspended() {
143 return suspended>0;
144 }
145
146
147
148
149 public DataState getDataState() {
150 return dataState;
151 }
152
153
154
155
156 public <D extends DataConsumer> D getConsumer(String name, Class<D> type) {
157
158 if (type.isAssignableFrom(AcopChartConsumer.class)) {
159 if (consumers.containsKey(name)) {
160 return type.cast(consumers.get(name));
161 }
162
163 AcopChartConsumer c= new AcopChartConsumer(this, name);
164 c.setColor(colorManager.pickColor());
165 maxLinkIndex++;
166 consumers.put(name,c);
167 return type.cast(c);
168 }
169 return null;
170 }
171
172
173
174
175 public void releaseConsumer(DataConsumer consumer) {
176 consumers.remove(consumer.getName()).destroy();
177 updateYScaleOnRemove((AcopChartConsumer)consumer);
178 updateXScaleOnRemove((AcopChartConsumer)consumer);
179 colorManager.dropColor(((AcopChartConsumer)consumer).getColor());
180 }
181
182
183
184
185 public DataConsumer[] getConsumers() {
186 return consumers.values().toArray(new DataConsumer[consumers.size()]);
187 }
188
189
190
191
192 @SuppressWarnings("unchecked")
193 public Class<DataConsumer>[] getSupportedConsumerTypes() {
194 return new Class[]{DoubleSeqConsumer.class};
195 }
196
197
198
199
200
201 public void addDisplayerParameters(AcopGraphParameters parameters) throws CommonException, PropertyVetoException {
202 if (parameters == null) return;
203
204 parameters = synchronizeGraphParameters(parameters);
205 if (connections.get(parameters) != null) {
206 return;
207 }
208 AcopGraphParameters[] old = getDisplayerParameters();
209 AcopChartConsumer consumer = (AcopChartConsumer) getConsumer(parameters.toString(), DoubleSeqConsumer.class);
210
211 consumer.setDisplayerParameters(parameters);
212 AdapterFactory factory = AdapterFactoryService.getInstance().getAdapterFactory();
213 AcopTransportDataSource ds = factory.createDataSource(parameters.getConnectionParameters());
214 if (parameters.getConverter() != null){
215 Converter c = parameters.getConverter();
216 c.addConsumer(consumer);
217 ds.addConsumer(c);
218 }
219 else {
220 ds.addConsumer(consumer);
221 }
222 connections.put(parameters, consumer);
223 firePropertyChange(MultipleAcopDisplayer.DISPLAYER_PARAMETERS_PROPERTY, old, getDisplayerParameters());
224 }
225
226
227
228
229
230
231 public void addConnectionParameters(ConnectionParameters parameters) throws CommonException, PropertyVetoException {
232
233 addDisplayerParameters(new AcopGraphParameters(parameters));
234 }
235
236 private AcopGraphParameters synchronizeGraphParameters(AcopGraphParameters parameters) {
237
238 Color color = null;
239 if (parameters.getColor() != null)
240 color = parameters.getColor();
241 else
242 color = colorManager.previewNextColor();
243
244 if (parameters.getDrawStyle() != -1)
245 setDrawStyle(parameters.getDrawStyle());
246 int graphStyle = getDrawStyle();
247
248 if (parameters.getFFT() != -1)
249 setFFT(parameters.getFFT());
250 int fft = getFFT();
251
252 if (parameters.getMode() != -1)
253 setDisplayMode(parameters.getMode());
254 int mode = getDisplayMode();
255
256 int width = parameters.getWidth();
257 setDrawWidth(width);
258
259 ConnectionParameters cp =parameters.getConnectionParameters();
260 if (parameters.isTrend())
261 cp = cp.deriveWithPropertySize(1);
262 return new AcopGraphParameters(new AcopDisplayerParameters(
263 cp,
264 parameters.getArrayIndex(), parameters.getMinimum(),
265 parameters.getMaximum(), parameters.getUnits(),parameters.getFormat()),
266 color,fft,graphStyle,mode,width,parameters.isTrend(),parameters.getTrendLength(),
267 parameters.getConverter());
268 }
269
270
271
272
273
274
275 public AcopGraphParameters[] getDisplayerParameters() {
276 AcopGraphParameters[] params = new AcopGraphParameters[connections.keySet().size()];
277 return connections.keySet().toArray(params);
278 }
279
280
281
282
283
284
285 public ConnectionParameters[] getConnectionParameters() {
286
287 AcopGraphParameters[] agp = getDisplayerParameters();
288 ConnectionParameters[] cp = new ConnectionParameters[agp.length];
289 for (int i = 0; i < agp.length; i++) {
290 cp[i] = agp[i].getConnectionParameters();
291 }
292 return cp;
293 }
294
295
296
297
298
299 public DataSource removeDisplayerParameters(AcopGraphParameters parameters) {
300
301 AcopGraphParameters[] old = getDisplayerParameters();
302 AdapterFactory factory = AdapterFactoryService.getInstance().getAdapterFactory();
303 AcopChartConsumer consumer = connections.remove(parameters);
304 if (consumer == null) return null;
305 DataSource ds = factory.releaseDataSource(parameters.getConnectionParameters());
306 if (parameters.getConverter() != null) {
307 ds.removeConsumer(parameters.getConverter());
308 parameters.getConverter().removeConsumer(consumer);
309 } else {
310 ds.removeConsumer(consumer);
311 }
312 releaseConsumer(consumer);
313
314 firePropertyChange(MultipleAcopDisplayer.DISPLAYER_PARAMETERS_PROPERTY, old, getDisplayerParameters());
315 return ds;
316
317 }
318
319
320
321
322
323
324 public DataSource removeConnectionParameters(ConnectionParameters parameters) {
325
326 return removeDisplayerParameters(new AcopGraphParameters(parameters, getForeground(),getFFT(), getDrawStyle(), getDisplayMode(), getDrawWidth(), false, 100, null));
327 }
328
329
330
331
332
333 public void setDisplayerParameters(AcopGraphParameters[] parameters) throws CommonException, PropertyVetoException {
334 AcopGraphParameters[] old = getDisplayerParameters();
335 ArrayList<AcopGraphParameters> toBeRemoved = new ArrayList<AcopGraphParameters>();
336 Iterator<AcopGraphParameters> it = connections.keySet().iterator();
337 while(it.hasNext()) {
338 toBeRemoved.add(it.next());
339 }
340
341 ArrayList<AcopGraphParameters> toBeAdded = new ArrayList<AcopGraphParameters>();
342
343 for (AcopGraphParameters p : parameters) {
344 if (toBeRemoved.contains(p)) {
345 toBeRemoved.remove(p);
346 } else {
347 toBeAdded.add(p);
348 }
349 }
350
351 for(AcopGraphParameters p : toBeRemoved) {
352 removeDisplayerParameters(p);
353 }
354
355 for(AcopGraphParameters p : toBeAdded) {
356 addDisplayerParameters(p);
357 }
358
359 firePropertyChange(MultipleAcopDisplayer.DISPLAYER_PARAMETERS_PROPERTY, old, parameters);
360 }
361
362
363
364
365
366 public void setConnectionParameters(ConnectionParameters[] parameters) throws CommonException, PropertyVetoException {
367
368 AcopGraphParameters[] agp = new AcopGraphParameters[parameters.length];
369 for (int i = 0; i < parameters.length; i++) {
370 agp[i] = new AcopGraphParameters(parameters[i]);
371 }
372 setDisplayerParameters(agp);
373 }
374
375
376
377
378
379
380
381 public void updateYScale(AcopChartConsumer consumer) {
382 if (!consumers.values().contains(consumer)) return;
383 double max;
384 double min;
385 if (getConsumers().length == 1) {
386 max = consumer.getPreferredYMax();
387 min = consumer.getPreferredYMin();
388 } else {
389 max = Math.max(getYMax(), consumer.getPreferredYMax());
390 min = Math.min(getYMin(), consumer.getPreferredYMin());
391 }
392 setYMax(max);
393 setYMin(min);
394 }
395
396 private void updateYScaleOnRemove(AcopChartConsumer consumer) {
397 if (!(consumer.getPreferredYMax() < getYMax() || consumer.getPreferredYMin() > getYMin())) {
398 return;
399 }
400 Iterator<AcopChartConsumer> it = consumers.values().iterator();
401 double max;
402 double min;
403 if (it.hasNext()) {
404 AcopChartConsumer c = it.next();
405 max = c.getPreferredYMax();
406 min = c.getPreferredYMin();
407 } else {
408 return;
409 }
410 while (it.hasNext()) {
411 AcopChartConsumer c = it.next();
412 max = Math.max(max, c.getPreferredYMax());
413 min = Math.min(min, c.getPreferredYMin());
414 }
415 setYMax(max);
416 setYMin(min);
417
418 }
419
420
421
422
423
424
425
426 public void updateXScale(AcopChartConsumer consumer) {
427 if (!consumers.values().contains(consumer)) return;
428 double max;
429 if (getConsumers().length == 1) {
430 max = consumer.getArraySize();
431 } else {
432 max = Math.max(getXMax(), consumer.getArraySize());
433 }
434 setXMax(max);
435 }
436
437 private void updateXScaleOnRemove(AcopChartConsumer consumer) {
438 if (!(consumer.getArraySize() < getXMax())) {
439 return;
440 }
441 Iterator<AcopChartConsumer> it = consumers.values().iterator();
442 double max;
443 if (it.hasNext()) {
444 AcopChartConsumer c = it.next();
445 max = c.getArraySize();
446 } else {
447 return;
448 }
449 while (it.hasNext()) {
450 AcopChartConsumer c = it.next();
451 max = Math.max(max, c.getArraySize());
452 }
453 setXMax(max);
454 }
455
456
457
458
459
460
461
462 public void setDragEnabled(boolean enabled) {
463 if (getTransferHandler() instanceof CosyTransferHandler) {
464 if (((CosyTransferHandler)getTransferHandler()).isExportEnabled() == enabled) return;
465
466 ((CosyTransferHandler)getTransferHandler()).setExportEnabled(enabled, this);
467 }
468 }
469
470
471
472
473
474
475 public boolean isDragEnabled() {
476 if (getTransferHandler() instanceof CosyTransferHandler) {
477 return ((CosyTransferHandler)getTransferHandler()).isExportEnabled();
478 } else {
479 return getTransferHandler() != null;
480 }
481 }
482
483
484
485
486
487
488
489 public void setDropEnabled(boolean enabled) {
490 if (getTransferHandler() instanceof CosyTransferHandler) {
491 if (((CosyTransferHandler)getTransferHandler()).isReceiveEnabled() == enabled) return;
492
493 ((CosyTransferHandler)getTransferHandler()).setReceiveEnabled(enabled, this);
494 }
495 }
496
497
498
499
500
501
502 public boolean isDropEnabled() {
503 if (getTransferHandler() instanceof CosyTransferHandler) {
504 return ((CosyTransferHandler)getTransferHandler()).isReceiveEnabled();
505 } else {
506 return getTransferHandler() != null;
507 }
508 }
509
510
511
512
513
514
515 public AcopMultipleDisplayerInfoDialog getInfoDialog() {
516 if (dialog == null) {
517 dialog = new AcopMultipleDisplayerInfoDialog(this);
518 }
519 return dialog;
520 }
521
522
523
524
525
526 @Override
527 public PopupManager getPopupManager()
528 {
529 if (popupManager == null) {
530 popupManager = super.getPopupManager();
531 popupManager.addAction(new AbstractAction("Info...") {
532 private static final long serialVersionUID = 1L;
533
534 public void actionPerformed(ActionEvent e)
535 {
536 getInfoDialog().setVisible(true);
537 }
538 });
539 }
540
541 return popupManager;
542 }
543
544
545
546
547
548 public void setPropertiesPopupEnabled(boolean enable) {
549 Action[] actions = getPopupManager().getActions();
550 for (Action a : actions) {
551 if (a != null && "Preferences...".equals(a.getValue(Action.NAME))) {
552 a.setEnabled(enable);
553 return;
554 }
555 }
556 }
557
558
559
560
561
562 public boolean isPropertiesPopupEnabled() {
563 Action[] actions = getPopupManager().getActions();
564 for (Action a : actions) {
565 if (a != null && "Preferences...".equals(a.getValue(Action.NAME))) {
566 return a.isEnabled();
567 }
568 }
569 return false;
570 }
571
572 }