/* * * * Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */ package javax.microedition.lcdui; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; /** * A <code>DateField</code> is an editable component for presenting * date and time (calendar) * information that may be placed into a <code>Form</code>. Value for * this field can be * initially set or left unset. If value is not set then the UI for the field * shows this clearly. The field value for "not initialized * state" is not valid * value and <code>getDate()</code> for this state returns <code>null</code>. * <p> * Instance of a <code>DateField</code> can be configured to accept * date or time information * or both of them. This input mode configuration is done by * <code>DATE</code>, <code>TIME</code> or * <code>DATE_TIME</code> static fields of this * class. <code>DATE</code> input mode allows to set only * date information and <code>TIME</code> only time information * (hours, minutes). <code>DATE_TIME</code> * allows to set both clock time and date values. * <p> * In <code>TIME</code> input mode the date components of * <code>Date</code> object * must be set to the "zero epoch" value of January 1, 1970. * <p> * Calendar calculations in this field are based on default locale and defined * time zone. Because of the calculations and different input modes date object * may not contain same millisecond value when set to this field and get back * from this field. * @since MIDP 1.0 */ public class DateField extends Item { /** * Input mode for date information (day, month, year). With this mode this * <code>DateField</code> presents and allows only to modify date * value. The time * information of date object is ignored. * * <P>Value <code>1</code> is assigned to <code>DATE</code>.</P> */ public static final int DATE = 1; /** * Input mode for time information (hours and minutes). With this mode this * <code>DateField</code> presents and allows only to modify * time. The date components * should be set to the "zero epoch" value of January 1, 1970 and * should not be accessed. * * <P>Value <code>2</code> is assigned to <code>TIME</code>.</P> */ public static final int TIME = 2; /** * Input mode for date (day, month, year) and time (minutes, hours) * information. With this mode this <code>DateField</code> * presents and allows to modify * both time and date information. * * <P>Value <code>3</code> is assigned to <code>DATE_TIME</code>.</P> */ public static final int DATE_TIME = 3; /** * Creates a <code>DateField</code> object with the specified * label and mode. This call * is identical to <code>DateField(label, mode, null)</code>. * * @param label item label * @param mode the input mode, one of <code>DATE</code>, <code>TIME</code> * or <code>DATE_TIME</code> * @throws IllegalArgumentException if the input <code>mode's</code> * value is invalid */ public DateField(String label, int mode) { this(label, mode, null); } /** * Creates a date field in which calendar calculations are based * on specific * <code>TimeZone</code> object and the default calendaring system for the * current locale. * The value of the <code>DateField</code> is initially in the * "uninitialized" state. * If <code>timeZone</code> is <code>null</code>, the system's * default time zone is used. * * @param label item label * @param mode the input mode, one of <code>DATE</code>, <code>TIME</code> * or <code>DATE_TIME</code> * @param timeZone a specific time zone, or <code>null</code> for the * default time zone * @throws IllegalArgumentException if the input <code>mode's</code> value * is invalid */ public DateField(String label, int mode, java.util.TimeZone timeZone) { super(label); synchronized (Display.LCDUILock) { if ((mode != DATE) && (mode != TIME) && (mode != DATE_TIME)) { throw new IllegalArgumentException("Invalid input mode"); } this.mode = mode; if (timeZone == null) { timeZone = TimeZone.getDefault(); } this.currentDate = Calendar.getInstance(timeZone); itemLF = dateFieldLF = LFFactory.getFactory().getDateFieldLF(this); } // synchronized } /** * Returns date value of this field. Returned value is * <code>null</code> if field * value is * not initialized. The date object is constructed according the rules of * locale specific calendaring system and defined time zone. * * In <code>TIME</code> mode field the date components are set to * the "zero * epoch" value of January 1, 1970. If a date object that presents * time beyond one day from this "zero epoch" then this field * is in "not * initialized" state and this method returns <code>null</code>. * * In <code>DATE</code> mode field the time component of the calendar is * set to zero when constructing the date object. * * @return date object representing time or date depending on input mode * @see #setDate */ public java.util.Date getDate() { synchronized (Display.LCDUILock) { // NOTE: // defensive copy of the Date object is necessary // because CLDC's Calendar returns a reference to an internal, // shared Date object. See bugID: 4479408. // original: // return (initialized ? // new java.util.Date(currentDate.getTime().getTime()) : null); if (initialized) { java.util.Date retDate = dateFieldLF.lGetDate(); if (retDate == null) { return new java.util.Date(currentDate.getTime().getTime()); } else { return retDate; } } return null; } // synchronized } /** * Sets a new value for this field. <code>null</code> can be * passed to set the field * state to "not initialized" state. The input mode of * this field defines * what components of passed <code>Date</code> object is used.<p> * * In <code>TIME</code> input mode the date components must be set * to the "zero * epoch" value of January 1, 1970. If a date object that presents * time * beyond one day then this field is in "not initialized" state. * In <code>TIME</code> input mode the date component of * <code>Date</code> object is ignored and time * component is used to precision of minutes.<p> * * In <code>DATE</code> input mode the time component of * <code>Date</code> object is ignored.<p> * * In <code>DATE_TIME</code> input mode the date and time * component of <code>Date</code> are used but * only to precision of minutes. * * @param date new value for this field * @see #getDate */ public void setDate(java.util.Date date) { synchronized (Display.LCDUILock) { setDateImpl(date); dateFieldLF.lSetDate(date); } // synchronized } /** * Gets input mode for this date field. Valid input modes are * <code>DATE</code>, <code>TIME</code> and <code>DATE_TIME</code>. * * @return input mode of this field * @see #setInputMode */ public int getInputMode() { // SYNC NOTE: return of atomic value, no locking necessary return mode; } /** * Set input mode for this date field. Valid input modes are * <code>DATE</code>, <code>TIME</code> and <code>DATE_TIME</code>. * * @param mode the input mode, must be one of <code>DATE</code>, * <code>TIME</code> or <code>DATE_TIME</code> * @throws IllegalArgumentException if an invalid value is specified * @see #getInputMode */ public void setInputMode(int mode) { if ((mode != DATE) && (mode != TIME) && (mode != DATE_TIME)) { throw new IllegalArgumentException("Invalid input mode"); } synchronized (Display.LCDUILock) { if (this.mode != mode) { this.mode = mode; // While the input mode is changed // some irrelevant values for new mode could be lost. // Currently that is allowed by the spec. // So for TIME mode we make sure that time is set // on a zero epoch date // and for DATE mode we zero out hours and minutes if (mode == TIME) { currentDate.set(Calendar.YEAR, 1970); currentDate.set(Calendar.MONTH, Calendar.JANUARY); currentDate.set(Calendar.DATE, 1); } else if (mode == DATE) { currentDate.set(Calendar.HOUR, 0); currentDate.set(Calendar.HOUR_OF_DAY, 0); currentDate.set(Calendar.MINUTE, 0); } dateFieldLF.lSetInputMode(mode); } } // synchronized } // package private /** * Sets the date. * @param date the date value to set to. */ void setDateImpl(java.util.Date date) { if (date == null) { initialized = false; } else { currentDate.setTime(date); if (mode == TIME) { if (currentDate.getTime().getTime() >= 24*60*60*1000) { initialized = false; } else { currentDate.set(Calendar.YEAR, 1970); currentDate.set(Calendar.MONTH, Calendar.JANUARY); currentDate.set(Calendar.DATE, 1); initialized = true; } } else { // Currently spec does not prohibit from losing // irrelevant for that mode information // so we always zero out hours and minutes // NOTE: the specification doesn't prohibit // the loss of information irrelevant to // the current input mode, so we always zero out the // hours and minutes. if (mode == DATE) { currentDate.set(Calendar.HOUR, 0); currentDate.set(Calendar.HOUR_OF_DAY, 0); currentDate.set(Calendar.MINUTE, 0); } initialized = true; } // always ignore seconds and milliseconds currentDate.set(Calendar.SECOND, 0); currentDate.set(Calendar.MILLISECOND, 0); } } /** * Return whether the Item takes user input focus. * * @return Always return <code>true</code> */ boolean acceptFocus() { return true; } /** * The look&feel associated with this DateField. * Set in the constructor. */ DateFieldLF dateFieldLF; // = null /** * A flag indicating the initialization state of this DateField */ boolean initialized; // = false; /** * The mode of this DateField */ int mode; /** * The last saved date. * This is used for making the last saved date bold. */ Calendar currentDate; }