1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.gui;
21
22 import java.awt.BorderLayout;
23 import java.awt.event.ActionEvent;
24 import java.beans.PropertyVetoException;
25 import java.util.Map;
26
27 import javax.swing.AbstractAction;
28 import javax.swing.JFrame;
29
30 import com.cosylab.events.SetEvent;
31 import com.cosylab.events.SetListener;
32 import com.cosylab.gui.adapters.Converter;
33 import com.cosylab.gui.components.DialKnob;
34 import com.cosylab.gui.components.customizer.AbstractCustomizerPanel;
35 import com.cosylab.gui.components.range2.TrimValuePolicy;
36 import com.cosylab.gui.components.util.ColorHelper;
37 import com.cosylab.gui.components.util.CosyUIElements;
38 import com.cosylab.gui.components.util.PopupManager;
39 import com.cosylab.gui.displayers.ConvertibleDisplayer;
40 import com.cosylab.gui.displayers.DataConsumer;
41 import com.cosylab.gui.displayers.DataSource;
42 import com.cosylab.gui.displayers.DataSourceSupport;
43 import com.cosylab.gui.displayers.DataState;
44 import com.cosylab.gui.displayers.DisplayerUtilities;
45 import com.cosylab.gui.displayers.DoubleConsumer;
46 import com.cosylab.gui.displayers.DoubleConsumerMulticaster;
47 import com.cosylab.gui.displayers.DoubleDisplayer;
48 import com.cosylab.gui.displayers.NonblockingNumberConsumer;
49 import com.cosylab.util.CommonException;
50
51
52
53
54
55
56
57
58 public class DialKnobDisplayer extends DialKnob implements DoubleDisplayer,
59 DataSource, ConvertibleDisplayer
60 {
61 private static final long serialVersionUID = 1L;
62
63 @SuppressWarnings("unchecked")
64 private DataSourceSupport support = new DataSourceSupport(new Class[]{
65 NonblockingNumberConsumer.class
66 });
67
68
69 private DataState dataState = new DataState(DataState.UNDEFINED);
70 private int suspendCount = 0;
71 private DataSource dataSource;
72 private boolean flag;
73 private Converter converter;
74 private AbstractCustomizerPanel customizer;
75 private InfoDialog infoDialog;
76 private PopupManager popupManager;
77
78
79
80
81
82
83
84
85
86 public DialKnobDisplayer()
87 {
88 super();
89 initialize();
90 }
91
92
93
94
95 public void setCharacteristics(Map characteristics)
96 {
97 if (characteristics == null) {
98 throw new NullPointerException("characteristics");
99 }
100
101 DisplayerUtilities.setCharacteristics(characteristics, this);
102 }
103
104
105
106
107 public DataConsumer[] getConsumers()
108 {
109 return support.getConsumers();
110 }
111
112
113
114
115 public DataConsumer getDataConsumer(Class type)
116 {
117 if (type == DoubleConsumer.class) {
118 return this;
119 }
120
121 return DoubleConsumerMulticaster.createDataConsumer(type, this);
122 }
123
124
125
126
127 public DataState getDataState()
128 {
129 return dataState;
130 }
131
132
133
134
135 public DataConsumer getDefaultDataConsumer()
136 {
137 return this;
138 }
139
140
141
142
143 public String[] getSupportedCharacteristics()
144 {
145 return DisplayerUtilities.COMMON_NUMERIC_DISPLAYER_CHARACTERISTICS;
146 }
147
148
149
150
151 public Class[] getAcceptableConsumerTypes()
152 {
153 return support.getAcceptableConsumerTypes();
154 }
155
156
157
158
159 public boolean isSuspended()
160 {
161 return isEnabled();
162 }
163
164
165
166
167 public void addConsumer(DataConsumer consumer) throws PropertyVetoException
168 {
169 if (consumer == null) {
170 throw new NullPointerException("consumer");
171 }
172
173 NonblockingNumberConsumer c = (NonblockingNumberConsumer)consumer
174 .getDataConsumer(NonblockingNumberConsumer.class);
175
176 if (c == null) {
177 throw new PropertyVetoException("Consumer '" + consumer
178 + "' must support NonblockingNumberConsumer.", null);
179 }
180
181 support.addConsumer(c);
182 }
183
184
185
186
187 public void cleanup()
188 {
189 internalCleanup();
190 updateDataState(new DataState(DataState.NOT_INITIALIZED));
191 }
192
193
194
195
196 public void destroy()
197 {
198 cleanup();
199 support.removeAllConsumers();
200 support = null;
201 dataState = null;
202 }
203
204
205
206
207 public void removeConsumer(DataConsumer consumer)
208 {
209 support.removeConsumer(consumer);
210 }
211
212
213
214
215 public void resume()
216 {
217 if (suspendCount > 0) {
218 suspendCount--;
219 }
220
221 if (suspendCount == 0) {
222 setEnabled(true);
223 }
224 }
225
226
227
228
229 public void suspend()
230 {
231 suspendCount++;
232 setEnabled(false);
233 }
234
235
236
237
238 public void updateDataState(DataState state)
239 {
240 DataState old = dataState;
241 dataState = state;
242 firePropertyChange(DATA_STATE, old, dataState);
243 }
244
245
246
247
248 public void updateValue(long timestamp, double value)
249 throws CommonException
250 {
251 setValue(value);
252
253
254
255
256 if (flag) {
257 synchronize();
258 flag = false;
259 }
260 }
261
262 private void initialize()
263 {
264 setBorder(new CosyUIElements.PanelFlushBorder());
265 setBackground(ColorHelper.getCosyControl());
266 addSetListener(new SetListener() {
267 public void setPerformed(SetEvent e)
268 {
269 try {
270 double value = e.getDoubleValue();
271
272 DataConsumer[] d = getConsumers();
273
274 for (int i = 0; i < d.length; i++) {
275 NonblockingNumberConsumer dd = (NonblockingNumberConsumer)d[i];
276
277 if (dd != null) {
278 dd.updateNonblocking(new Double(value));
279 }
280 }
281 } catch (Exception ex) {
282 ex.printStackTrace();
283 }
284 }
285 });
286 setPopupEnabled(true);
287 internalCleanup();
288 }
289
290 private void internalCleanup()
291 {
292 setTitle("Dialknob");
293 setTitleVisible(true);
294 setUnits(null);
295 setUnitsVisible(true);
296 getRangedValue().setValue(0, 100, 0);
297 getUserRangedValue().setValue(0, 100, 0);
298 setValuePolicy(new TrimValuePolicy());
299 setEditable(true);
300 setFormat("%3.2f");
301 setEnhanced(true);
302 setResizable(true);
303 setTiltingEnabled(true);
304 flag = true;
305 }
306
307
308
309
310 @SuppressWarnings("unchecked")
311 public Class[] getSupportedConsumerTypes()
312 {
313 return DoubleConsumerMulticaster.PREFERED_CONSUMER_TYPES;
314 }
315
316
317
318
319 public void setDataSource(DataSource dataSource)
320 throws PropertyVetoException
321 {
322 DisplayerUtilities.prepareNewDataSource(dataSource,this);
323
324 DataSource old= this.dataSource;
325 this.dataSource = dataSource;
326
327 firePropertyChange(DATA_SOURCE,old,dataSource);
328 }
329
330
331
332
333
334
335 public Converter getConverter() {
336 return converter;
337 }
338
339
340
341
342
343
344
345 public void setConverter(Converter converter) throws PropertyVetoException {
346 if (this.converter != null && this.converter.equals(converter) ||
347 (this.converter == null && converter == null)) return;
348 DisplayerUtilities.prepareNewConverter(converter,this);
349
350 Converter old= this.converter;
351 this.converter = converter;
352
353 firePropertyChange(CONVERTER_PROPERTY,old,this.converter);
354 }
355
356
357
358
359 public void removeAllConsumers()
360 {
361 support.removeAllConsumers();
362 }
363
364
365
366
367 public DataSource getDataSource() {
368 return dataSource;
369 }
370
371
372
373
374
375
376
377
378
379 public AbstractCustomizerPanel getCustomizer()
380 {
381 if (customizer == null) {
382 customizer = AbstractCustomizerPanel.findCustomizer(this);
383 }
384
385 return customizer;
386 }
387
388
389
390
391
392
393 public InfoDialog getInfoDialog() {
394 if (infoDialog == null) {
395 infoDialog = new InfoDialog(this);
396 }
397 return infoDialog;
398 }
399
400
401
402
403
404 public PopupManager getPopupManager()
405 {
406 if (popupManager == null) {
407 popupManager = super.getPopupManager();
408 popupManager.addAction(new AbstractAction("Info...") {
409
410 private static final long serialVersionUID = 1L;
411
412 public void actionPerformed(ActionEvent e)
413 {
414 getInfoDialog().setVisible(true);
415 }
416 });
417 }
418
419 return popupManager;
420 }
421
422
423
424
425
426 public static void main(String[] arg0) {
427 JFrame f = new JFrame();
428 f.getContentPane().setLayout(new BorderLayout());
429 DialKnobDisplayer disp = new DialKnobDisplayer();
430 disp.setPopupEnabled(true);
431 f.getContentPane().add(disp);
432 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
433 f.setVisible(true);
434
435 }
436 }
437
438