View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans.
5    *
6    * CosyBeans is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * CosyBeans is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with CosyBeans.  If not, see <http://www.gnu.org/licenses/>.
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   * DialKnob implemented as <code>Displayer</code>.
54   *
55   * @author <a href="mailto:jernej.kamenik@cosylab.com">Jernej Kamenik</a>
56   * @version $id$
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  	//private InitializationValuePolicy ivp = new InitializationValuePolicy();
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  	//protected DisplayerSupport delegate = new DisplayerSupport();
79  	//private SetterSupport setter = null;
80  	//private int requests = 0;
81  	//private SetMode setMode = SetMode.SYNCHRONOUS;
82  
83  	/**
84  						 *
85  						 */
86  	public DialKnobDisplayer()
87  	{
88  		super();
89  		initialize();
90  	}
91  
92  	/* (non-Javadoc)
93  	 * @see com.cosylab.gui.displayers.DataConsumer#setCharacteristics(java.util.Map)
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 	/* (non-Javadoc)
105 	 * @see com.cosylab.gui.displayers.DataSource#getConsumers()
106 	 */
107 	public DataConsumer[] getConsumers()
108 	{
109 		return support.getConsumers();
110 	}
111 
112 	/* (non-Javadoc)
113 	 * @see com.cosylab.gui.displayers.DataConsumer#getDataConsumer(java.lang.Class)
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 	/* (non-Javadoc)
125 	 * @see com.cosylab.gui.displayers.CommonDisplayer#getDataState()
126 	 */
127 	public DataState getDataState()
128 	{
129 		return dataState;
130 	}
131 
132 	/* (non-Javadoc)
133 	 * @see com.cosylab.gui.displayers.DataConsumer#getDefaultDataConsumer()
134 	 */
135 	public DataConsumer getDefaultDataConsumer()
136 	{
137 		return this;
138 	}
139 
140 	/* (non-Javadoc)
141 	 * @see com.cosylab.gui.displayers.DataConsumer#getSupportedCharacteristics()
142 	 */
143 	public String[] getSupportedCharacteristics()
144 	{
145 		return DisplayerUtilities.COMMON_NUMERIC_DISPLAYER_CHARACTERISTICS;
146 	}
147 
148 	/* (non-Javadoc)
149 	 * @see com.cosylab.gui.displayers.DataSource#getSupportedConsumersTypes()
150 	 */
151 	public Class[] getAcceptableConsumerTypes()
152 	{
153 		return support.getAcceptableConsumerTypes();
154 	}
155 
156 	/* (non-Javadoc)
157 	 * @see com.cosylab.gui.displayers.CommonDisplayer#isSuspended()
158 	 */
159 	public boolean isSuspended()
160 	{
161 		return isEnabled();
162 	}
163 
164 	/* (non-Javadoc)
165 	 * @see com.cosylab.gui.displayers.DataSource#addConsumer(com.cosylab.gui.displayers.DataConsumer)
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 	/* (non-Javadoc)
185 	 * @see com.cosylab.gui.displayers.CommonDisplayer#cleanup()
186 	 */
187 	public void cleanup()
188 	{
189 		internalCleanup();
190 		updateDataState(new DataState(DataState.NOT_INITIALIZED));
191 	}
192 
193 	/* (non-Javadoc)
194 	 * @see com.cosylab.gui.core.CosyComponent#destroy()
195 	 */
196 	public void destroy()
197 	{
198 		cleanup();
199 		support.removeAllConsumers();
200 		support = null;
201 		dataState = null;
202 	}
203 
204 	/* (non-Javadoc)
205 	 * @see com.cosylab.gui.displayers.DataSource#removeConsumer(com.cosylab.gui.displayers.DataConsumer)
206 	 */
207 	public void removeConsumer(DataConsumer consumer)
208 	{
209 		support.removeConsumer(consumer);
210 	}
211 
212 	/* (non-Javadoc)
213 	 * @see com.cosylab.gui.displayers.CommonDisplayer#resume()
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 	/* (non-Javadoc)
227 	 * @see com.cosylab.gui.displayers.CommonDisplayer#suspend()
228 	 */
229 	public void suspend()
230 	{
231 		suspendCount++;
232 		setEnabled(false);
233 	}
234 
235 	/* (non-Javadoc)
236 	 * @see com.cosylab.gui.displayers.DataConsumer#updateDataState(com.cosylab.gui.displayers.DataState)
237 	 */
238 	public void updateDataState(DataState state)
239 	{
240 		DataState old = dataState;
241 		dataState = state;
242 		firePropertyChange(DATA_STATE, old, dataState);
243 	}
244 
245 	/* (non-Javadoc)
246 	 * @see com.cosylab.gui.displayers.DoubleConsumer#updateValue(long, double)
247 	 */
248 	public void updateValue(long timestamp, double value)
249 		throws CommonException
250 	{
251 		setValue(value);
252 		/*
253 		 * Bug fix for RT 5053
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 	/* (non-Javadoc)
308 	 * @see com.cosylab.gui.displayers.DataConsumer#getSupportedConsumerTypes()
309 	 */
310 	@SuppressWarnings("unchecked")
311 	public Class[] getSupportedConsumerTypes()
312 	{
313 		return DoubleConsumerMulticaster.PREFERED_CONSUMER_TYPES;
314 	}
315 
316 	/* (non-Javadoc)
317 	 * @see com.cosylab.gui.displayers.Displayer#setDataSource(com.cosylab.gui.displayers.DataSource)
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 	 * Returns the converter.
333 	 * @return Returns the converter.
334 	 */
335 	public Converter getConverter() {
336 		return converter;
337 	}
338 
339 	
340 	/**
341 	 * Sets new converter.
342 	 * @param converter The converter to set.
343 	 * @throws PropertyVetoException if set fails
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 	/* (non-Javadoc)
357 	 * @see com.cosylab.gui.displayers.DataSource#removeAllConsumers()
358 	 */
359 	public void removeAllConsumers()
360 	{
361 		support.removeAllConsumers();
362 	}
363 	
364 	/* (non-Javadoc)
365 	 * @see com.cosylab.gui.displayers.Displayer#getDataSource()
366 	 */
367 	public DataSource getDataSource() {
368 		return dataSource;
369 	}
370 	
371 
372 	/**
373 	 * Loads the default
374 	 * <code>com.cosylab.gui.components.customizer.Customizer</code> for this
375 	 * displayer and returns it.
376 	 *
377 	 * @return the Customizer intance for this displayer
378 	 */
379 	public AbstractCustomizerPanel getCustomizer()
380 	{
381 		if (customizer == null) {
382 			customizer = AbstractCustomizerPanel.findCustomizer(this);
383 		}
384 
385 		return customizer;
386 	}
387 	
388 	/**
389 	 * Returns the info dialog that belongs to this displayer.
390 	 * 
391 	 * @return
392 	 */
393 	public InfoDialog getInfoDialog() {
394 		if (infoDialog == null) {
395 			infoDialog = new InfoDialog(this);
396 		}
397 		return infoDialog;
398 	}
399 	
400 	/*
401 	 * (non-Javadoc)
402 	 * @see com.cosylab.gui.components.DialKnob#getPopupManager()
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 	 * @param arg0
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 /* __oOo__ */