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.AbstractDisplayerPanel;
34  import com.cosylab.gui.components.LabelledWheelswitch;
35  import com.cosylab.gui.components.util.PopupManager;
36  import com.cosylab.gui.displayers.ConvertibleDisplayer;
37  import com.cosylab.gui.displayers.DataConsumer;
38  import com.cosylab.gui.displayers.DataSource;
39  import com.cosylab.gui.displayers.DataSourceSupport;
40  import com.cosylab.gui.displayers.DataState;
41  import com.cosylab.gui.displayers.DisplayerUtilities;
42  import com.cosylab.gui.displayers.DoubleConsumer;
43  import com.cosylab.gui.displayers.DoubleConsumerMulticaster;
44  import com.cosylab.gui.displayers.DoubleDisplayer;
45  import com.cosylab.gui.displayers.NonblockingNumberConsumer;
46  
47  
48  /**
49   * <code>WheelswitchDisplayer</code> is simple implementation of
50   * <code>Displayer</code> interface based on <code>LabelledWheelswitch</code>.
51   *
52   * @author <a href="mailto:igor.kriznar@cosylab.com">Igor Kriznar</a>
53   * @version $Id: WheelswitchDisplayer.java,v 1.12 2008-04-22 12:31:02 jbobnar Exp $
54   *
55   * @since Nov 24, 2003.
56   */
57  public class WheelswitchDisplayer extends LabelledWheelswitch
58  	implements DoubleDisplayer, DataSource, ConvertibleDisplayer
59  {
60  	private static final long serialVersionUID = 1L;
61  	private DataState dataState = new DataState(DataState.UNDEFINED);
62  	@SuppressWarnings("unchecked")
63  	private DataSourceSupport support = new DataSourceSupport(new Class[]{
64  			    NonblockingNumberConsumer.class
65  		    });
66  	private int suspendCount = 0;
67  	private DataSource dataSource;
68  	private Converter converter;
69  	private InfoDialog infoDialog;
70  	private PopupManager popupManager;
71  
72  	/**
73  	 * Creates WheelswitchDisplayer displayer.
74  	 *
75  	 * @param newValue
76  	 */
77  	public WheelswitchDisplayer(double newValue)
78  	{
79  		super(newValue);
80  		initialize();
81  	}
82  
83  	/**
84  	 * Creates WheelswitchDisplayer displayer.
85  	 */
86  	public WheelswitchDisplayer()
87  	{
88  		super();
89  		initialize();
90  	}
91  
92  	private void initialize()
93  	{
94  		// adds set listener, which fires data source updates
95  		addSetListener(new SetListener() {
96  				public void setPerformed(SetEvent e)
97  				{
98  					try {
99  						double value = e.getDoubleValue();
100 
101 						DataConsumer[] d = getConsumers();
102 
103 						for (int i = 0; i < d.length; i++) {
104 							NonblockingNumberConsumer dd = (NonblockingNumberConsumer)d[i];
105 
106 							if (dd != null) {
107 								dd.updateNonblocking(new Double(value));
108 							}
109 						}
110 					} catch (Exception ex) {
111 						ex.printStackTrace();
112 					}
113 				}
114 			});
115 		internalCleanup();
116 	}
117 
118 	/* (non-Javadoc)
119 	 * @see com.cosylab.gui.displayers.DataConsumer#getDataConsumer(java.lang.Class)
120 	 */
121 	public DataConsumer getDataConsumer(Class type)
122 	{
123 		if (type == DoubleConsumer.class) {
124 			return this;
125 		}
126 
127 		return DoubleConsumerMulticaster.createDataConsumer(type, this);
128 	}
129 
130 	/* (non-Javadoc)
131 	 * @see com.cosylab.gui.displayers.DataConsumer#getDefaultDataConsumer()
132 	 */
133 	public DataConsumer getDefaultDataConsumer()
134 	{
135 		return this;
136 	}
137 
138 	/* (non-Javadoc)
139 	 * @see com.cosylab.gui.displayers.DataConsumer#updateDataState(com.cosylab.gui.displayers.DataState)
140 	 */
141 	public void updateDataState(DataState state)
142 	{
143 		DataState old = dataState;
144 		dataState = state;
145 		firePropertyChange(DATA_STATE, old, dataState);
146 	}
147 
148 	/* (non-Javadoc)
149 	 * @see com.cosylab.gui.displayers.DataConsumer#setAttributes(java.util.Map)
150 	 */
151 	public void setCharacteristics(Map characteristics)
152 	{
153 		if (characteristics == null) {
154 			throw new NullPointerException("characteristics");
155 		}
156 
157 		DisplayerUtilities.setCharacteristics(characteristics, this);
158 	}
159 
160 	/* (non-Javadoc)
161 	 * @see com.cosylab.gui.displayers.CommonDisplayer#getDataState()
162 	 */
163 	public DataState getDataState()
164 	{
165 		return dataState;
166 	}
167 
168 	/* (non-Javadoc)
169 	 * @see com.cosylab.gui.displayers.CommonDisplayer#cleanup()
170 	 */
171 	public void cleanup()
172 	{
173 		internalCleanup();
174 		updateDataState(new DataState(DataState.NOT_INITIALIZED));
175 	}
176 
177 	private void internalCleanup()
178 	{
179 		setEnhanced(true);
180 		setResizable(true);
181 		setMaximum(100);
182 		setMinimum(0);
183 		setValue(0);
184 		setTitle("Wheelswitch");
185 		setUnits(null);
186 		setFormat("%3.2f");
187 		setLayoutOrientation(AbstractDisplayerPanel.DYNAMIC_LAYOUT);
188 		setBoundsVisible(false);
189 		setUnitsVisible(true);
190 		setTitleVisible(true);
191 		setEditable(true);
192 	}
193 
194 	/* (non-Javadoc)
195 	 * @see com.cosylab.gui.displayers.CommonDisplayer#suspend()
196 	 */
197 	public void suspend()
198 	{
199 		setEnabled(false);
200 		suspendCount++;
201 	}
202 
203 	/* (non-Javadoc)
204 	 * @see com.cosylab.gui.displayers.CommonDisplayer#resume()
205 	 */
206 	public void resume()
207 	{
208 		if (suspendCount > 0) {
209 			suspendCount--;
210 		}
211 
212 		if (suspendCount == 0) {
213 			setEnabled(true);
214 		}
215 	}
216 
217 	/* (non-Javadoc)
218 	 * @see com.cosylab.gui.displayers.CommonDisplayer#isSuspended()
219 	 */
220 	public boolean isSuspended()
221 	{
222 		return suspendCount > 0;
223 	}
224 
225 	/* (non-Javadoc)
226 	 * @see com.cosylab.gui.displayers.CommonDisplayer#getSupportedAttributes()
227 	 */
228 	public String[] getSupportedCharacteristics()
229 	{
230 		return DisplayerUtilities.COMMON_NUMERIC_DISPLAYER_CHARACTERISTICS;
231 	}
232 
233 	/* (non-Javadoc)
234 	 * @see com.cosylab.gui.displayers.DoubleConsumer#updateValue(long, double)
235 	 */
236 	public void updateValue(long timestamp, double value)
237 	{
238 		setValue(value);
239 	}
240 
241 	/**
242 	 * Accepts only consumers, which support
243 	 * <code>NonblockingNumberConsumer</code> which is used for receiving
244 	 * updates from user.
245 	 *
246 	 * @see com.cosylab.gui.displayers.DataSource#addConsumer(com.cosylab.gui.displayers.DataConsumer)
247 	 */
248 	public void addConsumer(DataConsumer consumer) throws PropertyVetoException
249 	{
250 		if (consumer == null) {
251 			throw new NullPointerException("consumer");
252 		}
253 
254 		NonblockingNumberConsumer c = (NonblockingNumberConsumer)consumer
255 			.getDataConsumer(NonblockingNumberConsumer.class);
256 
257 		if (c == null) {
258 			throw new PropertyVetoException("Consumer '" + consumer
259 			    + "' must support NonblockingNumberConsumer.", null);
260 		}
261 
262 		support.addConsumer(c);
263 	}
264 
265 	/* (non-Javadoc)
266 	 * @see com.cosylab.gui.displayers.DataSource#getConsumers()
267 	 */
268 	public DataConsumer[] getConsumers()
269 	{
270 		return support.getConsumers();
271 	}
272 
273 	/* (non-Javadoc)
274 	 * @see com.cosylab.gui.displayers.DataSource#removeConsumer(com.cosylab.gui.displayers.DataConsumer)
275 	 */
276 	public void removeConsumer(DataConsumer consumer)
277 	{
278 		support.removeConsumer(consumer);
279 	}
280 
281 	/* (non-Javadoc)
282 	 * @see com.cosylab.gui.displayers.DataSource#getSupportedConsumersTypes()
283 	 */
284 	@SuppressWarnings("unchecked")
285 	public Class[] getAcceptableConsumerTypes()
286 	{
287 		return support.getAcceptableConsumerTypes();
288 	}
289 
290 	/* (non-Javadoc)
291 	 * @see com.cosylab.gui.core.CosyComponent#destroy()
292 	 */
293 	public void destroy()
294 	{
295 		cleanup();
296 		support.removeAllConsumers();
297 		dataState = null;
298 	}
299 
300 	/* (non-Javadoc)
301 	 * @see com.cosylab.gui.displayers.DataConsumer#getSupportedConsumerTypes()
302 	 */
303 	@SuppressWarnings("unchecked")
304 	public Class[] getSupportedConsumerTypes()
305 	{
306 		return DoubleConsumerMulticaster.PREFERED_CONSUMER_TYPES;
307 	}
308 
309 	/* (non-Javadoc)
310 	 * @see com.cosylab.gui.displayers.Displayer#getDataSource()
311 	 */
312 	public DataSource getDataSource()
313 	{
314 		return dataSource;
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 	 * (non-Javadoc)
332 	 * @see com.cosylab.gui.displayers.ConvertibleDisplayer#getConverter()
333 	 */
334 	public Converter getConverter() {
335 		return converter;
336 	}
337 
338 	/*
339 	 * (non-Javadoc)
340 	 * @see com.cosylab.gui.displayers.ConvertibleDisplayer#setConverter(com.cosylab.gui.adapters.Converter)
341 	 */
342 	public void setConverter(Converter converter) throws PropertyVetoException {
343 		if (this.converter != null && this.converter.equals(converter) ||
344 				(this.converter == null && converter == null)) return;
345 		DisplayerUtilities.prepareNewConverter(converter,this);
346 		
347 		Converter old= this.converter;
348 		this.converter = converter;
349 		
350 		firePropertyChange(CONVERTER_PROPERTY,old,this.converter);
351 	}
352 
353 	/* (non-Javadoc)
354 	 * @see com.cosylab.gui.displayers.DataSource#removeAllConsumers()
355 	 */
356 	public void removeAllConsumers() {
357 		support.removeAllConsumers();
358 	}
359 	
360 	/**
361 	 * Returns the InfoDialog hooked to this Displayer.
362 	 * 
363 	 * @return
364 	 */
365 	public InfoDialog getInfoDialog() {
366 		if (infoDialog == null) {
367 			infoDialog = new InfoDialog(this);
368 		}
369 		return infoDialog;
370 	}
371 	
372 	/*
373 	 * (non-Javadoc)
374 	 * @see com.cosylab.gui.components.LabelledWheelswitch#getPopupManager()
375 	 */
376 	public PopupManager getPopupManager()
377 	{
378 		if (popupManager == null) {
379 			popupManager = super.getPopupManager();
380 			popupManager.addAction(new AbstractAction("Info...") {
381 				private static final long serialVersionUID = 1L;
382 
383 					public void actionPerformed(ActionEvent e)
384 					{
385 						getInfoDialog().setVisible(true);
386 					}
387 				});
388 		}
389 		
390 		return popupManager;
391 	}
392 	
393 	/**
394 	 * @param arg0
395 	 */
396 	public static void main(String[] arg0) {
397 		JFrame f = new JFrame();
398 		f.getContentPane().setLayout(new BorderLayout());
399 		WheelswitchDisplayer disp = new WheelswitchDisplayer();
400 		disp.setPopupEnabled(false);
401 		f.getContentPane().add(disp);
402 		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
403 		f.setVisible(true);
404 		
405 	}
406 }
407 
408 /* __oOo__ */