View Javadoc

1   /*
2    *  MicroEmulator
3    *  Copyright (C) 2001 Bartek Teodorczyk <barteo@barteo.net>
4    *  Copyright (C) 2005 Andres Navarro
5    *
6    *  This library is free software; you can redistribute it and/or
7    *  modify it under the terms of the GNU Lesser General Public
8    *  License as published by the Free Software Foundation; either
9    *  version 2.1 of the License, or (at your option) any later version.
10   *
11   *  This library 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 GNU
14   *  Lesser General Public License for more details.
15   *
16   *  You should have received a copy of the GNU Lesser General Public
17   *  License along with this library; if not, write to the Free Software
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20   
21  package javax.microedition.lcdui;
22  
23  import java.util.TimeZone;
24  import java.util.Calendar;
25  import java.util.Date;
26  
27  
28  public class DateField extends Item
29  {
30  
31    public static final int DATE = 1;
32    public static final int TIME = 2;
33    public static final int DATE_TIME = 3;
34    
35    Date date;
36    Date time;
37    String label;
38    int mode;
39  
40    ChoiceGroup dateTime;
41    DateCanvas dateCanvas;
42    TimeCanvas timeCanvas;
43  	static Command saveCommand = new Command("Save", Command.OK, 0);
44  	static Command backCommand = new Command("Back", Command.BACK, 0);
45    CommandListener dateTimeListener = new CommandListener()
46    {
47      
48      public void commandAction(Command c, Displayable d)
49      {
50        if (c == backCommand) {
51          getOwner().currentDisplay.setCurrent(owner);
52        } else if (c == saveCommand) {
53  			Calendar from = Calendar.getInstance();
54  			Calendar to = Calendar.getInstance();
55  			to.setTime(new Date(0L));
56  			
57  			if (d == dateCanvas) {
58  				from.setTime(dateCanvas.getTime());
59  	            to.set(Calendar.DAY_OF_MONTH, from.get(Calendar.DAY_OF_MONTH));
60  	            to.set(Calendar.MONTH, from.get(Calendar.MONTH));
61  	            to.set(Calendar.YEAR, from.get(Calendar.YEAR));
62  				date = to.getTime();
63  			} else {
64  				from.setTime(timeCanvas.getTime());
65  				to.set(Calendar.HOUR_OF_DAY, from.get(Calendar.HOUR_OF_DAY));
66  	            to.set(Calendar.MINUTE, from.get(Calendar.MINUTE));
67  				time = to.getTime();
68  			}
69  
70  
71              updateDateTimeString();
72  			getOwner().currentDisplay.setCurrent(owner);
73        }
74      }
75    };
76  
77  
78    public DateField(String label, int mode)
79    {
80      this(label, mode, null);
81    }
82  
83  
84    public DateField(String label, int mode, TimeZone timeZone)
85    {
86  	  // why not super(label)??
87      super(null);
88      
89      this.label = label;
90  // TODO this is ignoring TimeZone!! 
91      setInputMode(mode);
92      
93      dateCanvas = new DateCanvas();
94      dateCanvas.addCommand(saveCommand);
95      dateCanvas.addCommand(backCommand);
96      dateCanvas.setCommandListener(dateTimeListener);
97  
98      timeCanvas = new TimeCanvas();
99      timeCanvas.addCommand(saveCommand);
100     timeCanvas.addCommand(backCommand);
101     timeCanvas.setCommandListener(dateTimeListener);
102 }
103 
104 
105   public Date getDate()
106   {
107     return date;
108   }
109 
110 
111   public void setDate(Date date)
112   {
113     this.date = date;
114     // TODO change the Canvas!!
115     updateDateTimeString();
116   }
117 
118 
119   public int getInputMode()
120   {
121     return mode;
122   }
123 
124 
125   public void setInputMode(int mode)
126   {
127     if (mode < 1 || mode > 3) {
128       throw new IllegalArgumentException();
129     }
130     
131     this.mode = mode;
132 
133     dateTime = new ChoiceGroup(label, Choice.IMPLICIT, false);
134     if ((mode & DATE) != 0) {
135       dateTime.append("[date]", null);
136     }
137     if ((mode & TIME) != 0) {
138       dateTime.append("[time]", null);
139     }
140   }
141 
142 
143 	boolean isFocusable()
144 	{
145 		return true;
146 	}
147 
148     
149   int getHeight()
150 	{
151 		return super.getHeight() + dateTime.getHeight();
152 	}
153 
154 
155   int paint(Graphics g)
156   {
157     super.paintContent(g);
158     
159     g.translate(0, super.getHeight());
160 		dateTime.paint(g);
161 		g.translate(0, -super.getHeight());
162 
163     
164     return getHeight();
165   }
166 
167   
168 	void setFocus(boolean state)
169 	{
170     super.setFocus(state);
171 
172     dateTime.setFocus(state);
173   }
174 
175   
176   boolean select()
177   {
178     dateTime.select();
179 
180     if (dateTime.getSelectedIndex() == 0 && (mode & DATE) != 0) {
181       if (date != null) {
182           dateCanvas.setTime(date);
183       } else {
184           dateCanvas.setTime(new Date());
185       }
186       getOwner().currentDisplay.setCurrent(dateCanvas);
187     } else {
188       if (time != null) {
189           timeCanvas.setTime(time);
190       } else {
191     	  Calendar cal = Calendar.getInstance();
192     	  cal.set(Calendar.YEAR, 1970);
193     	  cal.set(Calendar.MONTH, Calendar.JANUARY);
194     	  cal.set(Calendar.DAY_OF_MONTH, 1);
195     	  cal.set(Calendar.HOUR_OF_DAY, 12);
196     	  cal.set(Calendar.MINUTE, 0);
197     	  cal.set(Calendar.SECOND, 0);
198           timeCanvas.setTime(cal.getTime());
199       }
200       getOwner().currentDisplay.setCurrent(timeCanvas);
201     }
202       
203     return true;
204   }
205   
206   
207   int traverse(int gameKeyCode, int top, int bottom, boolean action)
208 	{
209 		return dateTime.traverse(gameKeyCode, top, bottom, action);
210 	}
211   
212   private String formatDate() {
213 	  if (date == null)
214 		  return "[date]";
215 	  Calendar cal = Calendar.getInstance();
216 	  cal.setTime(date);
217 	  
218 	  int day =  cal.get(Calendar.DAY_OF_MONTH);
219 	  int month =  cal.get(Calendar.MONTH) + 1;
220 	  int year =  cal.get(Calendar.YEAR);
221 	  
222 	  return Integer.toString(day) + "-" + month + "-" + year;
223   }
224 
225   private String formatTime() {
226 	  if (time == null)
227 		  return "[time]";
228 	  Calendar cal = Calendar.getInstance();
229 	  cal.setTime(time);
230 	  
231 	  int hours =  cal.get(Calendar.HOUR_OF_DAY);
232 	  int minutes =  cal.get(Calendar.MINUTE);
233 	  
234 	  return Integer.toString(hours) + ":" + (minutes < 10? "0" : "") + minutes;
235   }
236 
237   void updateDateTimeString()
238   {
239     if ((mode & DATE) != 0) {
240       dateTime.set(0, formatDate(), null);
241     }
242     if ((mode & TIME) != 0) {
243         dateTime.set((((mode & DATE) != 0)? 1 : 0), formatTime(), null);
244     }
245   } 
246   
247 }
248 
249 class DateCanvas extends Canvas {
250 	Calendar cal;
251 
252     private int month, day, year;
253     private int selected;
254 	
255 	public DateCanvas() {
256 		cal = Calendar.getInstance();
257 	}
258 
259 	public Date getTime() {
260 		cal.set(Calendar.YEAR, year);
261 		cal.set(Calendar.MONTH, month);
262 		cal.set(Calendar.DAY_OF_MONTH, day);
263 		return cal.getTime();
264 	}
265 
266 	public void setTime(Date time) {
267 		this.cal.setTime(time);
268 		year = cal.get(Calendar.YEAR);
269 		month = cal.get(Calendar.MONTH);
270 		day = cal.get(Calendar.DAY_OF_MONTH);
271 		repaint();
272 	}
273 
274 	public void paint(Graphics g) {
275         int w = this.getWidth();
276         int h = this.getHeight();
277 
278         g.setColor(0xffffff);
279         g.fillRect(0, 0, w, h);
280         
281         Font font = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, 
282                 Font.SIZE_MEDIUM);
283 
284         String dayStr = Integer.toString(day);
285         if (day < 10)
286             dayStr = "0" + dayStr;
287         String monthStr = Integer.toString(month+1);
288         if (month+1 < 10)
289             monthStr = "0" + monthStr;
290         String yearStr = Integer.toString(year);
291         String delimiterStr = "/";
292         
293         int y = (h - font.getHeight()) >>> 1;
294 
295         int dayW = font.stringWidth(dayStr);
296         int monthW = font.stringWidth(monthStr);
297         int yearW = font.stringWidth(yearStr);
298         int delimiterW = font.stringWidth(delimiterStr);
299 
300         int stringWidth = dayW + monthW + yearW + (delimiterW << 1);
301         int offset = (w - stringWidth) >>> 1;
302         int dOff = offset;
303         int del1Off = dOff + dayW;
304         int mOff = del1Off + delimiterW;
305         int del2Off = mOff + monthW;
306         int yOff = del2Off + delimiterW;
307         
308         g.setColor(0);
309         g.setFont(font);
310         // draw the delimiter 
311         g.drawString(delimiterStr, del1Off, y, Graphics.LEFT | Graphics.TOP);
312         g.drawString(delimiterStr, del2Off, y, Graphics.LEFT | Graphics.TOP);
313         
314         // draw the rectangles 
315         
316         // colors  
317         int colorR, colorT;
318 
319         if (selected == 0) {
320             colorR = 0x000000;
321             colorT = 0xffffff;
322         } else {
323             colorR = 0xffffff;
324             colorT = 0x000000;
325         }
326         
327         g.setColor(colorR);
328         g.fillRect(dOff, y, dayW, font.getHeight());
329         g.setColor(colorT);
330         g.drawString(dayStr, dOff, y, Graphics.LEFT | Graphics.TOP);
331 
332         if (selected == 1) {
333             colorR = 0x000000;
334             colorT = 0xffffff;
335         } else {
336             colorR = 0xffffff;
337             colorT = 0x000000;
338         }
339 
340         g.setColor(colorR);
341         g.fillRect(mOff, y, monthW, font.getHeight());
342         g.setColor(colorT);
343         g.drawString(monthStr, mOff, y, Graphics.LEFT | Graphics.TOP);
344 
345         if (selected == 2) {
346             colorR = 0x000000;
347             colorT = 0xffffff;
348         } else {
349             colorR = 0xffffff;
350             colorT = 0x000000;
351         }
352 
353         g.setColor(colorR);
354         g.fillRect(yOff, y, yearW, font.getHeight());
355         g.setColor(colorT);
356         g.drawString(yearStr, yOff, y, Graphics.LEFT | Graphics.TOP);
357 	}
358 
359 	public synchronized void keyPressed(int keycode) {
360         int k = getGameAction(keycode);
361         
362         if (k == Canvas.LEFT && selected > 0) {
363             selected--;
364             repaint();
365         } else if (k == Canvas.RIGHT && selected < 2) {
366             selected++;
367             repaint();
368         } else if (k == Canvas.UP) {
369             Calendar cal = Calendar.getInstance();
370 
371             switch (selected) {
372                 case 0:  // day
373                 	cal.set(Calendar.YEAR, year);
374                 	cal.set(Calendar.MONTH, month);
375                 	cal.set(Calendar.DAY_OF_MONTH, day);
376                 	cal.set(Calendar.HOUR_OF_DAY, 1);
377                 	
378                 	cal.setTime(cal.getTime());
379                 	cal.add(Calendar.DAY_OF_MONTH, 1);
380                 	if(cal.get(Calendar.MONTH) == month)
381                 		day++;
382                 	else 
383                 		day = 1;
384                 	break;
385                 case 1: // month
386                 	if (month == Calendar.DECEMBER)
387                 		month = Calendar.JANUARY;
388                 	else 
389                 		month++;
390 
391                 	cal.set(Calendar.YEAR, year);
392                 	cal.set(Calendar.MONTH, month);
393                 	cal.set(Calendar.DAY_OF_MONTH, 28);
394                 	cal.set(Calendar.HOUR_OF_DAY, 1);
395                 	
396                 	cal.setTime(cal.getTime());
397                 	cal.add(Calendar.DAY_OF_MONTH, 4);
398                 	int daysInMonth = 28+(4-cal.get(Calendar.DAY_OF_MONTH));
399                 	
400                 	if (day > daysInMonth)
401                 		day = daysInMonth;
402                 	break;
403                 case 2: // year
404                 	// arbitrary limit
405                 	if (year < 5000) {
406                 		year++;
407                 		
408                 		// here i simply use the fact that there
409                 		// were nor will be two lenient years in
410                 		// a row
411 	                	if (day == 29 && month == Calendar.FEBRUARY)
412 	                		day = 28;
413                 	}
414                 	break;
415             }
416             repaint();
417         } else if (k == Canvas.DOWN) {
418             Calendar cal = Calendar.getInstance();
419 
420             switch (selected) {
421                 case 0:  // day
422                 	if(day > 1)
423                 		day--;
424                 	else {
425                     	cal.set(Calendar.YEAR, year);
426                     	cal.set(Calendar.MONTH, month);
427                     	cal.set(Calendar.DAY_OF_MONTH, 28);
428                     	cal.set(Calendar.HOUR_OF_DAY, 1);
429                     	
430                     	cal.setTime(cal.getTime());
431                     	cal.add(Calendar.DAY_OF_MONTH, 4);
432                     	int daysInMonth = 28+(4-cal.get(Calendar.DAY_OF_MONTH));
433                     	day = daysInMonth;
434                 	}
435                 	break;
436                 case 1: // month
437                 	if (month == Calendar.JANUARY)
438                 		month = Calendar.DECEMBER;
439                 	else 
440                 		month--;
441 
442                 	cal.set(Calendar.YEAR, year);
443                 	cal.set(Calendar.MONTH, month);
444                 	cal.set(Calendar.DAY_OF_MONTH, 28);
445                 	cal.set(Calendar.HOUR_OF_DAY, 1);
446                 	
447                 	cal.setTime(cal.getTime());
448                 	cal.add(Calendar.DAY_OF_MONTH, 1);
449                 	int daysInMonth = 28+(4-cal.get(Calendar.DAY_OF_MONTH));
450                 	
451                 	if (day > daysInMonth)
452                 		day = daysInMonth;
453                 	break;
454                 case 2: // year
455                 	// arbitrary limit
456                 	if (year > 1000) {
457                 		year--;
458                 		// here i simply use the fact that there
459                 		// were nor will be two lenient years in
460                 		// a row
461 	                	if (day == 29 && month == Calendar.FEBRUARY)
462 	                		day = 28;
463                 	}
464                 	break;
465             }
466             repaint();
467         }
468     }
469 }
470 
471 class TimeCanvas extends Canvas {
472 	Calendar cal;
473 	private int minutes, hours;
474 	private int selected;
475 	
476 	public TimeCanvas() {
477 		cal = Calendar.getInstance();
478 	}
479 
480 	public Date getTime() {
481 		this.cal.set(Calendar.HOUR_OF_DAY, hours);
482 		this.cal.set(Calendar.MINUTE, minutes);
483 		return cal.getTime();
484 	}
485 
486 	public void setTime(Date time) {
487 		this.cal.setTime(time);
488 		this.hours = cal.get(Calendar.HOUR_OF_DAY);
489 		this.minutes = cal.get(Calendar.MINUTE);
490 		repaint();
491 	}
492 
493     public void paint(Graphics g) {
494         int w = this.getWidth();
495         int h = this.getHeight();
496 
497         g.setColor(0xffffff);
498         g.fillRect(0, 0, w, h);
499         
500         Font font = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, 
501                 Font.SIZE_MEDIUM);
502 
503         String hoursStr = Integer.toString(hours);
504         if (hours < 10)
505             hoursStr = "0" + hoursStr;
506         String minutesStr = Integer.toString(minutes);
507         if (minutes < 10)
508             minutesStr = "0" + minutesStr;
509         String delimiterStr = " : ";
510         
511         int y = (h - font.getHeight()) >>> 1;
512 
513         int hoursW = font.stringWidth(hoursStr);
514         int minutesW = font.stringWidth(minutesStr);
515         int delimiterW = font.stringWidth(delimiterStr);
516 
517         int stringWidth = hoursW + minutesW + delimiterW;
518         int offset = (w - stringWidth) >>> 1;
519         int hOff = offset;
520         int dOff = offset + hoursW;
521         int mOff = dOff + delimiterW;
522         
523         g.setColor(0);
524         g.setFont(font);
525         // draw the delimiter 
526         g.drawString(delimiterStr, dOff, y, Graphics.LEFT | Graphics.TOP);
527         
528         // draw the rectangles 
529         
530         // colors  
531         int colorR, colorT;
532 
533         if (selected == 0) {
534             colorR = 0x000000;
535             colorT = 0xffffff;
536         } else {
537             colorR = 0xffffff;
538             colorT = 0x000000;
539         }
540         
541         g.setColor(colorR);
542         g.fillRect(hOff, y, hoursW, font.getHeight());
543         g.setColor(colorT);
544         g.drawString(hoursStr, hOff, y, Graphics.LEFT | Graphics.TOP);
545 
546         if (selected == 1) {
547             colorR = 0x000000;
548             colorT = 0xffffff;
549         } else {
550             colorR = 0xffffff;
551             colorT = 0x000000;
552         }
553 
554         g.setColor(colorR);
555         g.fillRect(mOff, y, minutesW, font.getHeight());
556         g.setColor(colorT);
557         g.drawString(minutesStr, mOff, y, Graphics.LEFT | Graphics.TOP);
558     }
559 
560     public synchronized void keyPressed(int keycode) {
561         int k = getGameAction(keycode);
562         
563         if (k == Canvas.LEFT && selected > 0) {
564             selected--;
565             repaint();
566         } else if (k == Canvas.RIGHT && selected < 1) {
567             selected++;
568             repaint();
569         } else if (k == Canvas.UP) {
570             switch (selected) {
571                 case 0:  // hours
572                     hours++;
573                     if (hours > 23)
574                         hours = 0;
575                     break;
576                 case 1: // minutes
577                     minutes++;
578                     if (minutes > 59)
579                         minutes = 0;
580                     break;
581             }
582             repaint();
583         } else if (k == Canvas.DOWN) {
584             switch (selected) {
585                 case 0:  // hours
586                     hours--;
587                     if (hours < 0)
588                         hours = 23;
589                     break;
590                 case 1: // minutes
591                     minutes--;
592                     if (minutes < 0)
593                         minutes = 59;
594                     break;
595             }
596             repaint();
597         }
598     }
599 }