View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans-Common.
5    *
6    * CosyBeans-Common 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-Common 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-Common.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package com.cosylab.gui.components;
21  
22  import java.awt.Color;
23  import java.awt.GridBagConstraints;
24  import java.awt.GridBagLayout;
25  import java.awt.event.ActionEvent;
26  import java.beans.PropertyChangeEvent;
27  import java.beans.PropertyChangeListener;
28  import java.util.Calendar;
29  import java.util.Date;
30  import java.util.GregorianCalendar;
31  import java.util.TimeZone;
32  
33  import javax.swing.AbstractAction;
34  import javax.swing.JFrame;
35  import javax.swing.JLabel;
36  import javax.swing.JPanel;
37  import javax.swing.border.LineBorder;
38  
39  import com.cosylab.gui.components.customizer.AbstractCustomizerPanel;
40  import com.cosylab.gui.components.util.PopupManageable;
41  import com.cosylab.gui.components.util.PopupManager;
42  
43  
44  /**
45   * Class specialized for entering the time. All fields are validated and allow
46   * only entry of valid time. The interface to application is provided through
47   * <code>java.util.Date</code> class. After creation, the component will be set
48   * to current time. 
49   *
50   * @author <a href="mailto:ales.pucelj@cosylab.com">Ales Pucelj</a>
51   * @version $id$
52   */
53  public class SimpleTimeSelector extends JPanel implements PopupManageable 
54  {
55  	private static final long serialVersionUID = 1L;
56  	private JLabel separator1;
57  	private JLabel separator2;
58  	private JLabel hourLabel;
59  	private JLabel minuteLabel;
60  	private JLabel secondsLabel;
61  	private Calendar calendar;
62  	private NumberField hourChooser;
63  	private NumberField minuteChooser;
64  	private NumberField secondChooser;
65  	
66  	private PopupManager popupManager;
67  	private AbstractCustomizerPanel customizer;
68  
69  	/**
70  	 * Listens for changes to fields and updates selection accordingly.
71  	 */
72  	private class NumberChangeListener implements PropertyChangeListener
73  	{
74  		/**
75  		 * Listens for changes to fields and updates selection accordingly.
76  		 *
77  		 * @param e PropertyChangeEvent
78  		 *
79  		 * @see java.beans.PropertyChangeListener#propertyChange(PropertyChangeEvent)
80  		 */
81  		public void propertyChange(PropertyChangeEvent e)
82  		{
83  			SimpleTimeSelector owner = SimpleTimeSelector.this;
84  			Date old = owner.getTime();
85  			if (e.getPropertyName().equals("value")) {
86  				int newValue = ((Number)e.getNewValue()).intValue();
87  
88  				if (e.getSource() == owner.hourChooser) {
89  					owner.setHour(newValue);
90  					firePropertyChange("time",old,owner.getTime());
91  				}
92  
93  				if (e.getSource() == owner.minuteChooser) {
94  					owner.setMinute(newValue);
95  					firePropertyChange("time",old,owner.getTime());
96  				}
97  
98  				if (e.getSource() == owner.secondChooser) {
99  					owner.setSeconds(newValue);
100 					firePropertyChange("time",old,owner.getTime());
101 				}
102 			}
103 		}
104 	}
105 
106 	/**
107 	 * SimpleTimeSelector constructor comment.
108 	 */
109 	public SimpleTimeSelector()
110 	{
111 		super(new GridBagLayout());
112 
113 		calendar = new GregorianCalendar();
114 
115 		createComponents();
116 
117 		updateDisplay();
118 	}
119 
120 	/*
121 	 * Creates and layouts the components that represent this panel.
122 	 */
123 	protected void createComponents()
124 	{
125 		NumberChangeListener cl = new NumberChangeListener();
126 
127 		hourLabel = new JLabel("Hours");
128 		add(hourLabel, createConstraints(0, 0, 0, 4, -2));
129 
130 		hourChooser = new NumberField(new Long(0), "%2d");
131 		hourChooser.addPropertyChangeListener(cl);
132 		add(hourChooser, createConstraints(0, 1, 1.0, 4, 4));
133 		hourChooser.setMinimum(new Long(0));
134 		hourChooser.setMaximum(new Long(23));
135         hourChooser.setColumns(2);
136 
137 		separator1 = new JLabel(":");
138 		add(separator1, createConstraints(1, 1, 0, 2, 6));
139 
140 		minuteLabel = new JLabel("Minutes");
141 		add(minuteLabel, createConstraints(2, 0, 0, 4, -2));
142 
143 		minuteChooser = new NumberField(new Long(0), "%2d");
144 		minuteChooser.addPropertyChangeListener(cl);
145 		add(minuteChooser, createConstraints(2, 1, 1.0, 4, 4));
146 		minuteChooser.setMinimum(new Long(0));
147 		minuteChooser.setMaximum(new Long(59));
148         minuteChooser.setColumns(2);
149 
150 		separator2 = new JLabel(":");
151 		add(separator2, createConstraints(3, 1, 0, 2, 6));
152 
153 		secondsLabel = new JLabel("Seconds");
154 		add(secondsLabel, createConstraints(4, 0, 0, 4, -2));
155 
156 		secondChooser = new NumberField(new Long(0), "%2d");
157 		secondChooser.addPropertyChangeListener(cl);
158 		add(secondChooser, createConstraints(4, 1, 1.0, 4, 4));
159 		secondChooser.setMinimum(new Long(0));
160 		secondChooser.setMaximum(new Long(59));
161 		secondChooser.setColumns(2);
162 	}
163 
164 	protected GridBagConstraints createConstraints(int x, int y, double ratio,
165 	    int top, int bottom)
166 	{
167 		GridBagConstraints constraints = new GridBagConstraints();
168 		constraints.gridx = x;
169 		constraints.gridy = y;
170 		constraints.weightx = ratio;
171 		constraints.weighty = 0.0;
172 		constraints.fill = GridBagConstraints.HORIZONTAL;
173 
174 		//	constraints.fill = GridBagConstraints.NONE;
175 		constraints.insets = new java.awt.Insets(top, x==0?4:2, bottom, x==4?4:2);
176 		constraints.anchor = GridBagConstraints.WEST;
177 
178 		return constraints;
179 	}
180 	
181 	/**
182 	 * Creates a customizer for this component.
183 	 * 
184 	 * @return costomizer
185 	 */
186 	public AbstractCustomizerPanel getCustomizer()
187 	{
188 		if (customizer == null) {
189 			customizer = AbstractCustomizerPanel.findCustomizer(this);
190 		}
191 
192 		return customizer;
193 	}
194 		
195 	/*
196 	 * (non-Javadoc)
197 	 * @see com.cosylab.gui.components.util.PopupManageable#getPopupManager()
198 	 */
199 	public PopupManager getPopupManager()
200 	{
201 		if (popupManager == null) {
202 			popupManager = new PopupManager(this, true);
203 			popupManager.addAction(new AbstractAction("Settings") {
204 				private static final long serialVersionUID = 1L;
205 				public void actionPerformed(ActionEvent e)
206 				{
207 					getCustomizer().showDialog();
208 				}
209 
210 			});
211 		}
212 
213 		return popupManager;
214 	}
215 
216 	/**
217 	 * Returns the currently selected hour. The value returned is between 0 and
218 	 * 23 inclusively.
219 	 *
220 	 * @return int
221 	 */
222 	public int getHour()
223 	{
224 		return calendar.get(Calendar.HOUR_OF_DAY);
225 	}
226 
227 	/**
228 	 * Returns the currently selected minute. The value is in range 0..59
229 	 * inclusively.
230 	 *
231 	 * @return int
232 	 */
233 	public int getMinute()
234 	{
235 		return calendar.get(Calendar.MINUTE);
236 	}
237 
238 	/**
239 	 * Returns the currently selected seconds. The value is in range 0..59
240 	 * inclusively.
241 	 *
242 	 * @return int
243 	 */
244 	public int getSeconds()
245 	{
246 		return calendar.get(Calendar.SECOND);
247 	}
248 
249 	/**
250 	 * Returns the currently selected time. Only hour, minute and second
251 	 * portions of the result are defined.
252 	 *
253 	 * @return java.util.Date
254 	 */
255 	public Date getTime()
256 	{
257 		return calendar.getTime();
258 	}
259 
260 	/**
261 	 * Sets the enabled state of this component.
262 	 *
263 	 * @param how boolean
264 	 */
265 	public void setEnabled(boolean how)
266 	{
267 		hourChooser.setEnabled(how);
268 		minuteChooser.setEnabled(how);
269 		secondChooser.setEnabled(how);
270 	}
271 	
272 	
273 	/**
274 	 * Returns true if hours label is enabled.
275 	 * 
276 	 * @param hour
277 	 */
278 	public boolean getHourStatus(){
279 		return hourLabel.isEnabled();
280 	}
281 	
282 	/**
283 	 * Enables/disables the hour label.
284 	 * 
285 	 * @param status
286 	 */
287 	public void setHourStatus(boolean status){
288 		hourLabel.setEnabled(status);	
289 	}
290 
291 	/**
292 	 * Sets the hour. The value will be cropped to the 0..23 range.
293 	 *
294 	 * @param hour int
295 	 */
296 	public void setHour(int hour)
297 	{
298 		if (hour == getHour()) {
299 			return;
300 		}
301 
302 		hour = Math.max(hour, 0);
303 		hour = Math.min(hour, 23);
304 
305 		calendar.set(Calendar.HOUR_OF_DAY, hour);
306 
307 		hourChooser.setLongValue(hour);
308 	}
309     
310     /**
311      * Sets the visibility of the labels above the text fields.
312      * The labels are visible by default. 
313      *  
314      * @param visible
315      */
316     public void setLabelsVisible(boolean visible) {
317         hourLabel.setVisible(visible);
318         minuteLabel.setVisible(visible);
319         secondsLabel.setVisible(visible);
320     }
321     
322 	/**
323 	 * Sets the minutes of the current time. New value will be cropped to the
324 	 * 0..59 range.
325 	 *
326 	 * @param minute int
327 	 */
328 	public void setMinute(int minute)
329 	{
330 		if (minute == getMinute()) {
331 			return;
332 		}
333 
334 		minute = Math.max(minute, 0);
335 		minute = Math.min(minute, 59);
336 
337 		calendar.set(Calendar.MINUTE, minute);
338 
339 		minuteChooser.setLongValue(minute);
340 	}
341 
342 	/**
343 	 * Sets the seconds of the current time. New value will be cropped to the
344 	 * 0..59 range.
345 	 *
346 	 * @param seconds int
347 	 */
348 	public void setSeconds(int seconds)
349 	{
350 		if (seconds == getSeconds()) {
351 			return;
352 		}
353 
354 		seconds = Math.max(seconds, 0);
355 		seconds = Math.min(seconds, 59);
356 
357 		calendar.set(Calendar.SECOND, seconds);
358 
359 		secondChooser.setLongValue(seconds);
360 	}
361 
362 	/**
363 	 * Sets the time to display. Only the hour, minute and second portion of
364 	 * the date will be used.
365 	 *
366 	 * @param date Date
367 	 */
368 	public void setTime(Date date)
369 	{
370 		calendar.setTime(date);
371 		updateDisplay();
372 	}
373 
374 	/**
375 	 * Updates the displayed values after manually setting the time.
376 	 */
377 	protected void updateDisplay()
378 	{
379 		hourChooser.setLongValue(getHour());
380 		minuteChooser.setLongValue(getMinute());
381 		secondChooser.setLongValue(getSeconds());
382 	}
383 
384 	/**
385 	 * Sets the time zone.
386 	 *
387 	 * @param zone
388 	 */
389 	public void setTimeZone(TimeZone zone)
390 	{
391 		calendar.setTimeZone(zone);
392 	}
393 
394 	/**
395 	 * Returns currently used time zone
396 	 *
397 	 * @return currently used time zone
398 	 */
399 	public TimeZone getTimeZone()
400 	{
401 		return calendar.getTimeZone();
402 	}
403 	
404 
405 	public static void main(String[] args)
406 	{
407 		JFrame dialog = new JFrame();
408 		//dialog.setModal(true);
409 		dialog.setSize(200, 100);
410 		dialog.getContentPane().setLayout(new GridBagLayout());
411 
412 		SimpleTimeSelector dc = new SimpleTimeSelector();
413         dc.setBorder(new LineBorder(Color.RED));
414         //dc.setLabelsVisible(false);
415 
416 		GridBagConstraints gbc = dc.createConstraints(0, 0, 1.0, 0, 0);
417 		gbc.fill = GridBagConstraints.BOTH;
418 		dialog.getContentPane().add(dc, gbc);
419 		dialog.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
420 		//dialog.show();
421 		dialog.setVisible(true);
422 
423 		//System.exit(0);
424 	}
425 
426 	
427 }
428 
429 /* __oOo__ */