📄 nov01_ericg.txt
字号:
J 2 M E T E C H T I P S
TIPS, TECHNIQUES, AND SAMPLE CODE
WELCOME to the Java Developer Connection(sm) (JDC)
Java(tm) 2 Platform, Micro Edition (J2ME(tm))
Tech Tips, for November 14, 2001. This issue covers:
* Dealing With Dates and Times in MIDP Applications
* Developing Custom Components for the Mobile Information
Device Profile
The J2ME Tech Tips are written by Eric Giguere
(http://www.ericgiguere.com), an engineer at iAnywhere
Solutions, inc. Eric is the author of the book "Java 2 Micro
Edition: Professional Developer's Guide" and co-author of the
upcoming "Mobile Information Device Profile for Java 2 Micro
Edition," both books in John Wiley & Sons' Professional
Developer's Guide series.
You can view this issue of the J2ME Tech Tips on the Web at
http://java.sun.com/jdc/J2METechTips/2001/tt1114.html
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DEALING WITH DATES AND TIMES IN MIDP APPLICATIONS
Parsing and displaying dates and times is often complicated
because of formatting and locale issues. Java 2 Platform,
Standard Edition (J2SE(tm)) provides several classes to simplify
date and time handling -- classes such as java.util.Calendar,
java.util.Date, java.util.TimeZone, and java.text.DateFormat. By
comparison, the Mobile Information Device Profile (MIDP) defines
only subsets of the Calendar, Date and TimeZone classes, and does
not include any form of DateFormat. How, then, can your MIDP
applications properly handle dates and times?
The answer lies in the javax.microedition.lcdui.DateField class,
part of the MIDP high-level user interface API. DateField is an
interactive user interface component that displays a date, time,
or both. It also allows you to edit the date and time. DateField
extends the Item class. This means that DateField components can
be placed on Form objects. So the first step in using a DateField
is to create a Form and place the DateField on the form:
Form f = new Form( "A Form" );
f.append( df );
As with any Item, the DateField is displayed only when the form
is made active by calling Display.setCurrent.
The DateField class defines two constructors:
public DateField( String label, int mode );
public DateField( String label, int mode,
java.util.TimeZone zone );
To properly display dates and times, a DateField instance needs
to know which time zone to use. The two-argument constructor uses
the device's default time zone. The three-argument constructor
lets you specify an explicit time zone if the default is
inappropriate. Note that you can't change the displayed time zone
without creating a new instance of DateField.
The first two arguments are identical in both constructors. The
first argument is the label to display alongside the field -- use
null if there is no label. The second argument is the input mode
of the field. There are three possible modes, these are declared
as constants in the DateField class:
public static final int DATE = 1;
public static final int TIME = 2;
public static final int DATE_TIME = 3;
The input mode controls what the field displays: a date only,
a time only, or a combined date and a time. You can change the
input mode at any time by calling the setInputMode method.
When you create a new DateField instance, you do not have to set
a date or time. The following code, for example, displays an
uninitialized date:
Display display = ....; // initialized elsewhere
Form f = new Form( "An Empty Date" );
DateField df = new DateField( "Date:",
DateField.DATE );
f.append( df );
display.setCurrent( f );
To initialize the field to a particular date or time, call
setDate and pass in a java.util.Date object initialized to the
correct value:
Calendar c = Calendar.getInstance();
c.set( Calendar.MONTH, Calendar.OCTOBER );
c.set( Calendar.DAY_OF_MONTH, 18 );
c.set( Calendar.YEAR, 1996 );
c.set( Calendar.HOUR_OF_DAY, 16 );
c.set( Calendar.MINUTE, 39 );
c.set( Calendar.SECOND, 45 );
c.set( Calendar.MILLISECOND, 0 );
Date moment = c.getTime();
DateField df = new DateField( null,
DateField.DATE_TIME );
df.setTime( moment );
A Date object represents a moment in time (in coordinated
universal time, or UTC, to be exact) as the number of
milliseconds since midnight, January 1, 1970. Use a Calendar
instance to create a Date instance, as shown above.
Note that a DateField in TIME input mode requires the date
portion to be set to January 1, 1970. Two useful routines for
clearing out the date portion of a Date and for combining two
Date objects into a single object are as follows:
// Return a Date with the time intact but the date
// set to January 1, 1970
public static Date clearDate( Date d ){
Calendar c = Calendar.getInstance();
c.setTime( d );
c.set( Calendar.MONTH, Calendar.JANUARY );
c.set( Calendar.DAY_OF_MONTH, 1 );
c.set( Calendar.YEAR, 1970 );
return c.getTime();
}
// Combine a date and time into a single
// Date instance
public static Date combineDateTime(
Date date, Date time ){
Calendar cd = Calendar.getInstance();
Calendar ct = Calendar.getInstance();
cd.setTime( date );
ct.setTime( time );
ct.set( Calendar.MONTH,
cd.get( Calendar.MONTH ) );
ct.set( Calendar.DAY_OF_MONTH,
cd.get( Calendar.DAY_OF_MONTH ) );
ct.set( Calendar.YEAR,
cd.get( Calendar.YEAR ) );
return ct.getTime();
}
Always do your date manipulation using the Calendar class, not
using the raw milliseconds value stored in a Date object.
After a DateField is displayed, the system will allow the user to
select the object and edit the date, time or both, depending on
the input mode. Whenever you need to obtain the new date/time,
call the getDate method:
DateField df = ....;
Date editedDate = df.getDate();
Here is a simple MIDlet that lets you view and edit dates and
times using all three input modes.
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
/**
* Demonstration of time/date editing using the MIDP
* DateField class.
*/
public class DateFieldTest extends MIDlet {
private Display display;
// Define our Command objects
private Command exitCommand =
new Command( "Exit", Command.EXIT, 1 );
private Command okCommand =
new Command( "OK", Command.OK, 1 );
private Command cancelCommand =
new Command(
"Cancel", Command.CANCEL, 1 );
public DateFieldTest(){
}
protected void destroyApp( boolean unconditional )
throws MIDletStateChangeException {
exitMIDlet();
}
protected void pauseApp(){
}
protected void startApp()
throws MIDletStateChangeException {
if( display == null ){ // first time called...
initMIDlet();
}
}
private void initMIDlet(){
display = Display.getDisplay( this );
testList = new TestList();
display.setCurrent( testList );
}
public void exitMIDlet(){
notifyDestroyed();
}
// Return a Date with the time intact but the date
// set to January 1, 1970
public static Date clearDate( Date d ){
Calendar c = Calendar.getInstance();
c.setTime( d );
c.set( Calendar.MONTH, Calendar.JANUARY );
c.set( Calendar.DAY_OF_MONTH, 1 );
c.set( Calendar.YEAR, 1970 );
return c.getTime();
}
// Combine a date and time into a single
// Date instance
public static Date combineDateTime( Date date,
Date time ){
Calendar cd = Calendar.getInstance();
Calendar ct = Calendar.getInstance();
cd.setTime( date );
ct.setTime( time );
ct.set( Calendar.MONTH,
cd.get( Calendar.MONTH ) );
ct.set( Calendar.DAY_OF_MONTH,
cd.get( Calendar.DAY_OF_MONTH ) );
ct.set( Calendar.YEAR,
cd.get( Calendar.YEAR ) );
return ct.getTime();
}
// The list of tests we can perform, arranged
// in threes so that ( index % 3 ) == one
// of DATE, TIME or DATE_TIME
static final String[] testLabels = {
"Current date",
"Current time",
"Current date/time",
"Edit date",
"Edit time",
"Edit date/time",
};
private TestList testList;
private Date editDate;
//
// Displays the list of actions
//
class TestList extends List
implements CommandListener {
public TestList(){
super( "DateField Tests", IMPLICIT,
testLabels, null );
addCommand( exitCommand );
setCommandListener( this );
}
public void commandAction( Command c,
Displayable d ){
if( c == exitCommand ){
exitMIDlet();
} else if( c == List.SELECT_COMMAND ){
// Figure out which date to display
// and what the input mode is
int which = getSelectedIndex();
String label = getString( which );
int mode = ( which % 3 ) + 1;
boolean save = ( which > 2 );
display.setCurrent(
new Edit( save, label, mode ) );
}
}
}
//
// Edit a date, time or date/time, optionally
// saving the value.
//
class Edit extends Form
implements CommandListener {
public Edit( boolean save, String label,
int mode ){
super( label );
this.save = save;
Date d = editDate;
if( !save ){
d = new Date();
}
dateField = new DateField( null, mode );
append( dateField );
if( d != null ){
if( mode == DateField.TIME ){
d = clearDate( d );
}
dateField.setDate( d );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -