Learning Wireless Java PDF
Learning Wireless Java PDF
Most Internet technologies are designed for desktop computers or enterprise servers
running on reliable networks with relatively high bandwidth. Handheld wireless
devices, on the other hand, have a more constrained computing environment. They
tend to have less memory, less powerful CPs, different input devices, and smaller
displays.
!ince the mid"#$$%s, various architectures and protocols have been introduced to deal
with these constraints. The &ireless 'pplication Protocol (or &'P), which is a
specification developed by the &'P *orum (http+,,www.wapforum.org), takes
advantage of several data"handling approaches already in use. -eveloping wireless
applications using &'P technologies is similar to developing &eb pages with a
markup language (e.g., HTM. or /M.) because &'P technologies are browser"
based.
'nother approach to developing wireless applications is to use the 0ava 1 Platform,
Micro 2dition (01M2 ). The 0ava programming language already plays an
important role in modern programming. &ith &'P, you can use 0ava servlets and
0ava!erver Pages to generate &ireless Markup .anguage (&M.) pages
dynamically. However, with 01M2, you can now write applications in 0ava and store
them directly on a cell phone. This adds a whole new dimension to wireless
programming.
Audience
This book is about programming with 01M2 on wireless devices. If you3re already
familiar with the architecture, you probably noticed that the Connected .imited
-evice Configuration (C.-C) and the Mobile Information -evice Profile (MI-P)
classes are not large. Therefore, this book is correspondingly compact in si4e. The
book acts as a 5uick guide for programmers who are familiar with the 0ava 1 !tandard
2dition (01!2 ) and want to get up to speed 5uickly with the 01M2. &e assume that
you are familiar with 0ava programming and have worked with the 01!2 classes. In
addition, we assume that you are familiar with setting up 0ava to work under various
environments (&indows or ni6 platforms), as well as compiling and running 0ava
applications.
The book also serves as a 5uick reference for 0ava programmers who are interested in
developing wireless software applications. The e6amples presented throughout the
book are a good starting point for working with all the MI-P features, including user
interface, networking, and databases. However, we should point out that this book is
not a rehash of the entire 01!2 class library. !everal of the classes of java.io,
java.lang, and java.net are included in the C.-C and MI-P libraries, but are less
bulky than their 01!2 counterparts. &e assume that you already know how to use
these classes, although we have included them in the 'PI reference for completeness.
Contents of This Book
This book is divided into three parts. Part I gives an overview of the 01M2 and
includes information about its architectural components+ namely, configurations and
profiles. Part I also presents detailed coverage of the C.-C and the MI-P.
Chapter 1
This chapter introduces the 01M2 environment and also e6plains
configurations and profiles. In addition, it shows you how to set up the 01M2
&ireless Toolkit to compile, preverify, and run a simple MI-let using the
command line with the &ireless Toolkit emulator.
Chapter 2
This chapter discusses the C.-C, including its re5uirements, limitations, and
the differences between its classes and the classes of the 01!2. In addition, it
looks briefly at the standalone C.-C and 78M distribution.
Chapter 3
This chapter introduces the re5uirements, limitations, and classes of the MI-P,
as well as introducing MI-lets and their associated 0ava 'pplication
-escriptor (0'-) files.
Part II contains programming details of the MI-P. It shows you how to program the
phone interface, handle events, make network connections, and work with databases.
Chapter 4
This chapter picks up where Chapter 9 left off, e6plaining the MI-let lifecycle
methods, the 0ava application manager, and showing how to use the 7Toolbar
application inside the 01M2 &ireless Toolkit to simplify MI-let development.
&e also discuss how to deploy MI-lets and include step"by"step instructions
on how to download a MI-let into a Motorola i:;s or i;%6 01M2"enabled
phone.
Chapter 5
This chapter introduces the MI-P <I model and its associated classes. In
addition, it gives detailed coverage of both the high"level and low"level MI-P
<I 'PIs.
Chapter 6
This chapter continues the discussion of the MI-P <I 'PIs by describing
how various events take place surrounding the graphical components and
commands. In addition, we cover the CommandListener and
ItemStateListener interfaces, as well as low"level event handling.
Chapter 7
This chapter discusses the <eneric Connection *ramework provided by the
C.-C and shows how to implement an HTTP connection across the Internet,
using a MI-let. The chapter also includes e6amples of how to send data to
C<I scripts and 0ava servlets across a network. *inally, the chapter briefly
discusses wireless session tracking and security for MI-let data traveling
across the airwaves.
Chapter 8
This chapter introduces the concept of data stores, which are simple databases
that MI-P applications can use to store persistent data beyond the lifetime of
the MI-let that created them. In addition, the chapter includes a MI-let that
can be used to download stock information from a remote web site.
Chapter 9
This chapter gives a 5uick introduction to the MI-P implementation on the
Palm Connected =rgani4ers, including step"by"step instructions on how to
deploy MI-lets to a PalmPilot.
Part III contains several chapters that are 5uick references for the 01M2 C.-C and
MI-P 'PIs. There is also an appendi6 that contains bibliographic information and
>.s to 01M2 specifications, white papers, wireless software development kits, and
other information that is important to developers.
Conventions Used in This Book
This book uses the following typographical conventions+
' Constant Width font is used for+
'nything that might appear in a 0ava program, including keywords, data types,
constants, method names, ob?ects, variables, class names, and interface names
'll 0ava code e6amples
'ttributes that might appear in a manifest or 0'- file
'n italic font is used for+
@ew terms where they are defined
Pathnames, filenames, directory names, and program names (unless the
program name is the name of a 0ava classA then it appears in constant width,
like other class names)
Internet addresses, such as domain names, >.s, and email addresses
' boldface font is used for+
26ample lines of 0ava code to which we wish to draw attention
Acknowledgments
I am deeply grateful to my editor, >obert 2ckstein, for all his comments, suggestions,
and guidelines throughout the development of this book. I did not know about all the
contributions an editor can make to a book until I worked with Bob. Thanks, BobC
Thanks also to the production team at =3>eilly for their hard work on this book.
!pecial thanks also to Monica Pawlan, 0enny Pratt, -ana @ouri, and .aureen Hudson
of the 0ava -eveloper Connection (0-C), who either provided comments or edited
some of the e6amples used in this book when they first appeared on the 0-C. 'lso,
thanks to the thousands of 0-C members who sent in comments and suggestions
regarding my articles. Thanks also to the following people who reviewed the contents
of this book for accuracy+ Ben <riffin, Marc .oy, and 0eff Cunningham.
I would also like to thank my family for their support during my studies, especially
my brother, -r. Mohammad H. Hamdan, for teaching me the value of hard work.
*inally, thanks to my wife, >eema, for her love, support, tolerance, and coffee, and
my baby son Dusef, who was born on =ctober #E, 1%%#, for providing a fun home
environment while I finished this book.
Part I: Introducing Java 2 Platform, icro
!dition "J2!#
Part I is an introduction to the 0ava 1 Micro 2dition (01M2) and 01M2
programming. These chapters will give you an overview of the 01M2,
and 5uickly teach you everything you need to know to get started with
01M2 programming.
Chapter #
Chapter 1
Chapter 9
Cha$ter %& 'verview of J2!
This book is about wireless 0ava programming with the 0ava 1 Platform, Micro
2dition (01M2). !un Microsystems, Inc. introduced 01M2 at the 0ava=ne conference
in 0une #$$$ as the younger sibling of both the 0ava 1 !tandard 2dition (01!2) and
the 0ava 1 2nterprise 2dition (0122). 't the time, distributed programming was taking
the 0ava developer community by storm, so most of the participants at the show were
more interested in what 0122 had to offer. However, over the ne6t two years,
developers also reali4ed that there was tremendous value in having small components
running 0ava. Two years later, at the 1%%# 0ava=ne conference, !un devoted an entire
track for individuals seeking to master the once arcane 01M2. .uckily, you don3t need
to attend 0ava=ne to learn about 01M2. Instead, this book will help you through the
myriad details of understanding 01M2 architecture and programming 01M2
applications.
In this chapter, we will present an overview of 01M23s primary components, including
virtual machines, configurations, and profiles. &e3ll then present a few short e6amples
of 01M2"enabled applications to whet your appetite and to show you how easy it is to
get started with 01M2.
%&% (hat Is J2!)
01M2 is a version of !un Microsystems3 0ava that is aimed at the consumer and
embedded devices market, which includes electronic commodities such as cellular
telephones, pagers, Personal -igital 'ssistants (P-'s), set"top bo6es, and other small
devices. !ince its release, over F%% companies have ?oined the development effort,
including large corporations such as Palm, @okia, Motorola, and >IM. However, the
direction that 01M2 travels is not shrouded in secrecy behind closed corporate doors.
Instead, development of 01M2 is handled through the 0ava Community Process (0CP),
which allows anyone with an Internet connection to get involved.
01M2 provides a complete set of solutions for creating state"of"the"art networked
applications for small devices. It also promises to enable device manufacturers,
service providers, and application developers to deploy new applications and services
to their customers. However, in doing so, it does not sacrifice some of the founding
guidelines of 0ava, which have become increasingly important these days, namely
cross"platform compatibility and security.
%&%&% A *igh+,evel -iew
*rom a high"level view, 01M2 defines the following components+
' series of 0ava virtual machines, each for use on different types of small
devices, each with different re5uirements
' group of libraries and 'PIs that can be run under each of the virtual
machinesA these are known as configurations and profiles
8arious tools for deployment and device configuration
The first two components make up the J2ME runtime environment . *igure #"#
provides a relational view of the runtime environment. 't its heart is a 0ava virtual
machine, which runs on top of a device3s host operating system. 'bove that is a
specific 01M2 configuration, which consists of programming libraries that provide
basic functionality based on the resource re5uirements of the device. =n top of the
configuration are one or more 01M2 profiles, which are additional programming
libraries that take advantage of kindred functionalities on similar devices.
.igure %+%& The high+level architecture of J2! runtime environment
If you haven3t worked with 01M2 before, you3re probably wondering about the top
two layers. It3s important to distinguish between a configuration and a profile in the
01M2 world, so let3s introduce them now.
%&%&2 Configurations
Cellular telephones, pagers, organi4ers, and other small devices are diverse in form,
functionality, and feature. However, they often use similar processors and have similar
amounts of memory. *or these reasons, the 01M2 designers created configurations.
Configurations define a hori4ontal grouping of products based on the available
memory budget and processing power of each device. =nce this information is
known, the configuration then outlines the following+
The 0ava programming language features supported
The 0ava virtual machine features supported
The basic 0ava libraries and 'PIs supported
Currently, there are two standard configurations in the 01M2 world+ the Connected
Limited Device Configuration (C.-C) and the Connected Device Configuration
(C-C). .et3s look at the C-C first.
%&%&2&% The C/C
The C-C is targeted toward powerful devices that are intermittently connected to a
network, including set"top bo6es, Internet T8s, home appliances, and car navigation
systems. The C-C contains a full"featured 0ava virtual machine, similar to that in use
today with the 01!2. The difference lies in the respective devices3 memory and
display capabilities.
Here are the resource re5uirements for C-C devices, as given by the official 01M2
specifications+
G#H
G#H
The 01M2 C-C specifications are located on the 0ava Community Process web site as 0!>"9F, which can be
found at http+,,www.?cp.org,?sr,detail,9F.?sp.
The device is powered by a 91"bit processor.
The device has 1 megabytes or more of total memory available for 0ava. This
includes both >'M and flash memory or >=M.
The device re5uires the full functionality of the 0ava 1 IBlue BookI virtual
machine.
The device has connectivity to some kind of network, often with a wireless,
intermittent connection and with limited (often $F%% bps or less) bandwidth.
The device may have a user interface with some degree of sophistication, but a
user interface is not mandatory.
%&%&2&2 The C,/C
The second type of configuration is more prevalent in the 01M2 world+ the C.-C.
This configuration specifies a much smaller footprint for consumer and embedded
devices than the C-C. The C.-C was first distributed in =ctober #$$$ with the idea
of creating a Ilowest common denominatorI 0ava platform for embedded devices,
specifically in terms of networking, I,=, security, and core libraries. Today, some of
the devices that you might find powered by the C.-C include mobile cell phones,
two"way pagers, personal digital assistants (P-'s), and personal organi4ers.
Here are the re5uirements for the 01M2 C.-C, again from the official 01M2
specifications+J
The device can have between #F% and ;#1 kilobytes of total memory available
for the 0ava platform, including both >'M and flash memory or >=M.
The device can have limited power, such as battery"powered operation.
The device has connectivity to some kind of network, often with a wireless,
intermittent connection and with limited (often $F%% bps or less) bandwidth.
G1H
G1H
@ote that C.-C stands for Connected Limited Device Configuration, not Connectivity".imited
-evice Configuration. The difference between the C.-C and the C-C is not in the type or speed of
the network connection.
In addition, the device may have a user interface with some degree of
sophistication, but a user interface is not mandatory.
The two products3 configurations, along with some of their respective products, are
shown in *igure #"1.
.igure %+2& J2! architecture
@ote that although the two product groups are supported by different configurations,
the line between the two configurations is somewhat blurred. In the future,
technological advances will likely make this boundary more and more cloudy.
However, for the moment, the important thing to remember is that the boundary
between the C.-C and the C-C is defined in terms of the target device3s memory
budget, battery usage, and the presence or absence of a user interface.
%&%&0 -irtual achines
's mentioned above, the C.-C and C-C configurations each define their own set of
supported features from the 0ava virtual machine. Conse5uently, each re5uires its own
0ava virtual machine. The C.-C virtual machine is far smaller than the virtual
machine re5uired by the C-C, since it supports fewer features. The virtual machine
for the C.-C is called the 7ilo 8irtual Machine (78M), and the virtual machine for
the C-C is called the C8M.
%&%&0&% The 1-
The 78M is a complete 0ava runtime environment for small devices. It3s a true 0ava
virtual machine as defined by the 0ava 8irtual Machine !pecification, e6cept for some
specific deviations that are necessary for proper functioning on small devices. It is
specifically designed from the ground up for small, resource"constrained devices with
a few hundred kilobytes3 total memory.
The 78M was originally created as a research pro?ect called I!potlessI at the !un
Microsystems .aboratories. The aim of the virtual machine was to implement a 0ava
virtual machine for the resource"constrained Palm Connected =rgani4er.
G9H
G9H
In fact, early incarnations of the 78M contained several I libraries based on the IspotlessI graphical toolkit.
%&%&0&2 The C-
The C8M is designed for larger consumer and embedded devices., such as those
found with the C-C. It supports all 0ava 1 8ersion #.9 virtual machine features and
libraries for items such as security, weak references, 0@I, and >emote Method
Invocation (>MI). The reference implementation, currently available from !un
Microsystems, runs on .inu6 and 86&orks. Dou can download the reference
implementation through the 01M2 web site at http+,,?ava.sun.com,?1me,.
Initially, C8M was an acronym for ICompactI 8irtual Machine. However, engineers
at !un Microsystems reali4ed that snappy marketers (or poor spellers) may confuse
the IcompactI in C8M with the 7 in 78M. !o, at present, the C does not stand for
anything at allKit is simply known as the C8M.
%&%&2 Profiles
01M2 makes it possible to define 0ava platforms for vertical product markets by
introducing profiles. 't the implementation level, a profile is a set of 'PIs that reside
on top of a configuration that offers the program access to device"specific capabilities.
*ollowing are some e6amples of profiles that are currently offered through 01M2.
%&%&2&% The I/P
The MI-P is designed to be used with the C.-C, and provides a set of 'PIs for use
by mobile devices, such as cellular phones and two"way pagers. The MI-P contains
classes for user interface, persistence storage, and networking. It also includes a
standardi4ed runtime environment that allows new applications to be IdownloadedI to
end user devices. !mall applications that run under the MI-P are called MI-lets.
!ince this profile is already released, the vast ma?ority of this book is dedicated to the
MI-P.
%&%&2&2 The P/A $rofile
The P-' profile is based on the C.-C and provides user interface 'PIs (which are
e6pected to be a subset of the '&T) and data storage 'PIs for handheld devices. 's
of this writing, the P-' profile is still in the works and no reference implementation
is available yet.
%&%&2&0 The .oundation $rofile
The *oundation profile e6tends the 'PIs provided by the C-C, but it does not provide
any user interface 'PIs. 's the name IfoundationI implies, this profile is meant to
serve as a foundation for other profiles, such as the Personal profile and the >MI
profile.
%&%&2&2 The Personal $rofile
The Personal profile e6tends the *oundation profile to provide a graphical user
interface (<I) capable of running 0ava &eb applets. !ince Personal0ava is being
redefined as the Personal profile, it will be backward compatible with Personal0ava
#.# and #.1 applications. 's of this writing, no reference implementation of the
Personal profile is available.
%&%&2&3 The 4I $rofile
The >MI profile e6tends the *oundation profile to provide >MI for devices. !ince it
e6tends the *oundation profile, the >MI profile is meant to be used with the
C-C,*oundation and not the C.-C,MI-P. The >MI profile will be compatible with
01!2 >MI 'PI #.1.6 or higher. However, as of this writing, no reference
implementation is available yet.
*igure #"9 shows a global snapshot of current and future 01M2 technologies.
.igure %+0& J2! environment
%&2 /ownloading the J2! (ireless Toolkit
@ow that you know your way around the 01M2 landscape, let3s get started with 01M2.
However, before we can compile and run any 01M2 programs, we need to download
and install the 01M2 &ireless Toolkit. Dou can obtain the 01M2 &ireless Toolkit at
the following >.+ http+,,?ava.sun.com,products,?1mewtoolkit.
The version that we use in this book is #.%.9 beta. It is available for the Microsoft
&indows $:,M2 and 1%%% platforms, as well as .inu6 and !un !olaris operating
systems. The toolkit re5uires the presence of at least 8ersion #.9 of the 0ava
-evelopment 7it (0-7) for the host operating environment.
=nce you3ve downloaded the &ireless Toolkit, double"click on it or e6ecute the
resulting binary (depending on your platform) to activate the e6traction. This will
uncompress the files needed to install the &ireless Toolkit. @ote that you may be
directed to specify an e6isting 0-7 installation on your system. If so, choose the latest
stable release of the 0-7 that you currently have on your system.
GEH
In addition, the
distribution may also ask you if you would like to install a version of the toolkit that
interfaces with *orte for 0ava. If you would like to develop your 01M2 applications
in the *orte for 0ava Integrated -evelopment 2nvironment, choose the corresponding
option. Be sure that *orte is already installed on your system before doing so.
GEH
Try to use a 0-7 instead of ?ust a 0ava >untime 2nvironment (0>2). It3s important that you have the javac
compiler to create 01M2 applications.
In this case, we3re going to install the 0ava &ireless Toolkit on a &indows platform
into the directory C:\j2mewtk. 'fter the installation is completed, this directory will
contain all the re5uired classes and tools to run the MI-P applications. (If the
installation program asks you to run the ktoolbar program, ?ust ignore it for the
moment.) However, we need to do a few more things before we can get started with
our e6amples.
*irst, we need to add the wireless toolkit binaries to your system path. Dou can do that
on &indows with the following command (again, we3ve assumed that the 0ava
&ireless Toolkit is installed at C:\j2mewtk)+
SET PATH=PATH!C"#j$me%tk#bin
If you edit your C:\!"#E$EC.%" file to add this to the default system path, as
shown below, and restart your machine, then you will not have to repeatedly perform
this step each time you restart your system.
&ith .inu6 and !olaris, the e5uivalent command is+
e&'ort PATH=(PATH"install_directory)j$me%tk)bin
=nce you3ve added that directory to your system path, you should be able to run the
0ava &ireless Toolkit tools from any directory on your system. 'n easy way to test it
is to e6ecute the 'reveri*+ command, without any arguments. Dou should see output
similar to the following+
C"#, 'reveri*+
-sage" P.E/E.I01.E2E 3o'tions4 classnames5dirnames ...
%here o'tions incl6de"
7class'ath 8directories se'arated b+ 9!9,
:irectories in %hich to look *or classes
7d 8director+, :irector+ in %hich o6t'6t is %ritten
;8*ilename, .ead command line arg6ments *rom a te&t *ile.
In order for the toolkit to work properly, you3ll need to have the 01!2 tools (notably
javac) available on your system e6ecutable path as well. Instructions on how to do
this are bundled with the 0-7, although it really boils down to adding the binary path
of the 01!2 binaries to your system path.
If you3re familiar with the 01M2 &ireless Toolkit already, you3re
likely wondering why we3re not using 7Toolbar. &e3ll cover
7Toolbar in Chapter E. In the meantime, it helps to see how
01M2 works under the hood.
To compile and run 01M2 programs from the command line, enter the following
commands. 'gain, feel free to set these system environment variables on the
command line, or edit the !"#E$EC.%" file (or similar) on your system for
convenience.
SET <$=EWT>?H@=E=C"#j$me%tk
SET =I:PAPI=<$=EWT>?H@=E#lib#mid'a'i.Ai'
SET <$=ECLASSPATH=<$=EWT>?H@=E#%tklib#kenv.Ai'!
<$=EWT>?H@=E#%tklib#kvem.jar!<$=EWT>?H@=E#%tklib#lime.jar
=n the .inu6 and !olaris side, the following could be added to your .'ro*ile (or
e5uivalent)+
e&'ort <$=EWT>?H@=E=)home)Bmahmo6d)j$me%tk
e&'ort =I:PAPI=(<$=EWT>?H@=E)lib)mid'a'i.Ai'
e&'ort <$=ECLASSPATH=(<$=EWT>?H@=E)%tklib)kenv.Ai'"
(<$=EWT>?H@=E)%tklib)kvem.jar"(<$=EWT>?H@=E)%tklib)lime.jar
@ote the that final line in either case is really one lineA it3s been continued here for
clarity.
%&0 A 5im$le !6am$le
The e6amples that we3re going to demonstrate here, and throughout the rest of the
book, are called MI-lets. If you3ve programmed with 0ava applets or servlets before,
then you3ll likely recogni4e the similarities in the Ifill"in"the"methodI program
structure. This first e6ample, Hello=idlet.java, shown in 26ample #"#, creates a
te6t bo6 and then prints the archetypal IHello &orldI in a te6t bo6.
!6am$le %+%& 7*ello (orld7
im'ort java&.microedition.midlet.C!
im'ort java&.microedition.lcd6i.C!
'6blic class Hello=idlet e&tends =I:let D
)) The dis'la+ *or this =I:let
'rivate :is'la+ dis'la+!
)) Te&tEo& to dis'la+ te&t
Te&tEo& bo& = n6ll!
'6blic Hello=idletF G D
H
'6blic void startA''F G D
dis'la+ = :is'la+.get:is'la+FthisG!
bo& = ne% Te&tEo&FISim'le E&am'leIJ IHello WorldIJ $KJ KG!
dis'la+.setC6rrentFbo&G!
H
)CC
C Pa6se is a no7o' since there are no backgro6nd activities or
C record stores that need to be closed.
C)
'6blic void 'a6seA''F G D
H
)CC
C :estro+ m6st clean6' ever+thing not handled b+ the garbage
C collector. In this case there is nothing to clean6'.
C)
'6blic void destro+A''Fboolean 6nconditionalG D
H
H
This MI-let consists of a public class definition that e6tends the =I:let class found
in java&.microedition.midlet. This superclass forms the base of all MI-lets in
01M2. =ur Hello=idlet class contains a constructor, as well as the startA''FG,
'a6seA''F G, and destro+A''F G methods that have been inherited from the =I:let
class. @ote that there is no mainFG method in this program. Instead, the startA''FG,
'a6seA''F G, and destro+A''F G methods are called by the underlying framework
to start up the MI-let, to pause it, or to destroy it.
.et3s start off by compiling our program on the command line. sing the command
line is a bit more comple6 than the 7Toolbar application that comes with the &ireless
Toolkit, so in order to simplify it, be sure that you have entered the additional
environment variables shown above. However, there are several steps that we need to
perform when compiling 01M2 applications, and it3s important to see each of the steps
as they occur.
's you would e6pect, the program must be saved in a file called Hello=idlet.java.
However, before you compile it, create a directory called tmpclasses. Then use the
following command to compile the MI-let from the command line in &indows+
C"#midlets, javac 7g"none 7d tm'classes 7bootclass'ath =I:PAPI
7class'ath
<$=ECLASSPATH Hello=idlet.java
In .inu6 and !olaris, the command looks like the following+
,javac 7g"none 7d tm'classes 7bootclass'ath (=I:PAPI 7class'ath
(<$=ECLASSPATH
Hello=idlet.java
This command compiles the 0ava source file without any debugging info, and sets the
appropriate boot and 01M2 classpaths to ensure that we don3t pick up any 01!2
classes. The end result of this command is the creation of the Hello=idlet.class
file in the tmpclasses directory.
&ith the 01!2, a class file was all you needed to run the application. However, all
MI-let classes must be preverified before they can be run on a target device. &hy is
this necessaryL >emember that one of the tasks of the standard 0ava virtual machine
(the one that comes with the 01!2) is to perform &'tecode verification. Bytecode
verification is one of the most important steps of the 0ava security model. It performs
such tasks as ensuring that the bytecodes of a 0ava class (and their operands) are all
validA that the code does not overflow or underflow the 8M stackA that local variables
are not used before they are initiali4edA that field, method, and class access control
modifiers are respected, and other important tasks. However, most of the bytecode
verifier is not included with the 78M due to si4e constraints. The preverifier ensures
that the e5uivalent security checks still take place.
Before you run the preverifier, create another directory called classes. Then, use this
command to preverify the Hello=idlet class+
C"#midlets, 'reveri*+ 7class'ath =I:PAPI!tm'classes 7d classes
tm'classes
=r on !olaris and .inu6+
, 'reveri*+ 7class'ath (=I:PAPI"tm'classes 7d classes tm'classes
The resulting output should look something like this+
3@6t'6t director+ *or veri*ied classes" classes4
This command takes all the classes inside the tmpclasses directory (of which
Hello=idlet.class is the only one) and preverifies them, writing the resulting
classes to the classes directory. @ote that the names of the preverified classes remain
e6actly the same, which is why we created two separate directories to hold them.
If you received an IIllegal constant pool inde6I class loading
error and you3re using 0-7 #.E, try using 0-7 #.9 until this issue
is resolved.
The ne6t step is to compress all the classes in the program (again, we have only one)
as well as their resources, into a 0ava 'rchive (0'>) file. Dou can use the 01!2 jar
command to create a 0'> file. Make sure you are in the classes directory to e6ecute
the following command+
, jar cv* Hello=idlet.jar Hello=idlet.class
The program will compress the Hello=idlet class into a 0'> file, creating a
manifest for it as well.
@ote that with the javac compiler, you can create MI-lets of practically any si4e.
However, that doesn3t guarantee that they will fit on the target device for which you3re
writing the MI-let. It would nice if there were a way to check if the target device can
handle the MI-let and run it before it is downloaded. =bviously, if a device can3t
handle the MI-let, there is no reason to even attempt a download.
To accomplish this, we need a file that manually specifies some pre"download
properties, including the si4e of the MI-let and its storage re5uirements. This can be
accomplished by creating a 0ava 'pplication -escriptor (0'-) file with your favorite
te6t editor. 26ample #"1 shows a sample 0'- file that we can use. @ote that you will
need to change the MI-let"0ar"!i4e entry to correspond to the si4e of the 0'> file that
you ?ust created. (In Chapter 9, we will e6plain the 0'- file synta6 in more detail.)
!6am$le %+2& *elloidlet&8ad
=I:let7L" HelloJJHello=idlet
=I:let7Mame" Hello=idlet
=I:let7/ersion" L.K
=I:let7/endor" @.A
=I:let7<ar7-.L" Hello=idlet.jar
=I:let7<ar7SiAe" NOP
.et3s save this e6ample 0'- file as (elloMidlet.jad, again in the classes directory that
holds the 0'> file. *inally, to run this MI-let, invoke !un3s MI-P emulator to point
at the 0'- file using the following command+
, em6lator 72descri'tor"Hello=idlet.jad
If everything worked correctly, you should see a phone similar to *igure #"E, although
the display may be different. Here, the HelloMidlet is running in the default phone
that comes with the 0ava &ireless Toolkit. If you click on the MI-let on the menu
(use the directional arrow pad to move the cursor and the button in the middle to
select), and instruct it to I.aunchI using the soft button on the lower right, you should
see output similar to *igure #"E. CongratulationsC Dou ?ust created your first 0ava
MI-letC
.igure %+2& *elloidlet
The gist of this program is in the startA''F G method. Here, we obtain the current
display that the device uses, then create a te6t bo6 with the words IHello &orldI
inside of it. *inally, we show the te6t bo6 on the current display. -on3t worry if you
don3t understand these ob?ects yetA the architecture of MI-lets will become clearer as
we move through the book.
%&0&% A ,ogin I/let
.et3s move to a more advanced MI-let. 26ample #"9 shows a MI-let with a
hypothetical login screen that prompts the user to log in. If the login is incorrect, the
program will repeatedly ask the user to try again.
!6am$le %+0& A login I/let
im'ort java&.microedition.midlet.=I:let!
im'ort java&.microedition.lcd6i.C!
'6blic class Login=idlet e&tends =I:let im'lements CommandListener D
'rivate :is'la+ dis'la+!
'rivate Te&t0ield 6serMame!
'rivate Te&t0ield 'ass%ord!
'rivate 0orm *orm!
'rivate Command cancel!
'rivate Command login!
'6blic Login=idletF G D
6serMame = ne% Te&t0ieldFILoginI:"IJ IIJ LKJ Te&t0ield.AM1G!
'ass%ord = ne% Te&t0ieldFIPass%ord"IJ IIJ LKJ
Te&t0ield.PASSW@.:G!
*orm = ne% 0ormFISign inIG!
cancel = ne% CommandFICancelIJ Command.CAMCELJ $G!
login = ne% CommandFILoginIJ Command.@>J $G!
H
'6blic void startA''F G D
dis'la+ = :is'la+.get:is'la+FthisG!
*orm.a''endF6serMameG!
*orm.a''endF'ass%ordG!
*orm.addCommandFcancelG!
*orm.addCommandFloginG!
*orm.setCommandListenerFthisG!
dis'la+.setC6rrentF*ormG!
H
'6blic void 'a6seA''F G D
H
'6blic void destro+A''Fboolean 6nconditionalG D
noti*+:estro+edF G!
H
'6blic void validate-serFString nameJ String 'ass%ordG D
i* Fname.eB6alsFIBmIG QQ 'ass%ord.eB6alsFIj$IGG D
men6F G!
H else D
tr+AgainF G!
H
H
'6blic void men6F G D
List services = ne% ListFIChoose oneIJ Choice.E2CL-SI/EG!
services.a''endFICheck =ailIJ n6llG!
services.a''endFICom'oseIJ n6llG!
services.a''endFIAddressesIJ n6llG!
services.a''endFI@'tionsIJ n6llG!
services.a''endFISign @6tIJ n6llG!
dis'la+.setC6rrentFservicesG!
H
'6blic void tr+AgainF G D
Alert error = ne% AlertFILogin IncorrectIJ IPlease tr+ againIJ
n6llJ
AlertT+'[email protected]!
[email protected]/E.G!
6serMame.setStringFIIG!
'ass%ord.setStringFIIG!
dis'la+.setC6rrentFerrorJ *ormG!
H
'6blic void commandActionFCommand cJ :is'la+able dG D
String label = c.getLabelF G!
i*Flabel.eB6alsFICancelIGG D
destro+A''Ftr6eG!
H else i*Flabel.eB6alsFILoginIGG D
validate-serF6serMame.getStringFGJ 'ass%ord.getStringF GG!
H
H
H
'gain, don3t worry if you can3t understand the entire program at this pointA this
e6ample is ?ust meant to give you a flavor of MI-P programming and some sample
applications to compile and run. Chapter ; and Chapter F will e6plain the <I classes
(such as :is'la+, 0orm, and Te&t0ield), as well as the event"handling classes (such
as Command) in much more detail.
That being said, let3s present a beginner3s overview of how this MI-let works. 's in
the previous e6ample, Login=idlet e6tends the =I:let abstract class. It also
implements the CommandListener interface by providing an implementation for the
commandActionF G method. In this method, there are two commands+ Login and
Cancel. The label of the command is checked+ if it is Cancel, the .oginMidlet is
destroyed, and if it is Login, then the username and passwords are validated.
In the .oginMidlet3s constructor, a 0orm ob?ect, two Te&t0ield ob?ects, and two
Command ob?ects are created. The Te&t0ield and Command ob?ects are added to the
form in the startA''FG method. In addition, 'a6seA''FG and destro+A''F G
perform minimal tasks.
Here is how the program operates+ if the Login command is given, the application
calls the validate-serF G method to validate the username and password. If they are
valid (in this case, they are hardcoded into the program for simplicity), then the men6F
G method is called to simulate a list of Iuseful services.I =therwise, the tr+AgainF G
is called to display an error message and to allow the user to reenter their name and
password.
If you are using the command line to compile and e6ecute, save this file named
LoginMidlet.java, make sure that you have a classes and a tmpclasses directory, and
use javac+
C"#midlets, javac 7g"none 7d tm'classes 7bootclass'ath =I:PAPI
7class'ath
<$=ECLASSPATH Login=idlet.java
If you are using !olaris or .inu6, the command becomes+
,javac 7g"none 7d tm'classes 7bootclass'ath (=I:PAPI 7class'ath
(<$=ECLASSPATH
Login=idlet.java
@e6t, remember that we must preverify the resulting class+
C"#midlets, 'reveri*+ 7class'ath =I:PAPI!tm'classes 7d classes
tm'classes
or
, 'reveri*+ 7class'ath (=I:PAPI"tm'classes 7d classes tm'classes
'gain, the preverified class is saved to the classes subdirectory in the current
directory. @e6t, compress the resulting class into a 0'> file+
jar cv* Login=idlet.jar Login=idlet.class
'nd finally, create a 0'- file that describes the resulting 0'> file in detail, as shown
in 26ample #"E.
!6am$le %+2& ,oginidlet&8ad
=I:let7L" LoginJJLogin=idlet
=I:let7Mame" Login=idlet
=I:let7/ersion" L.K
=I:let7/endor" @.A
=I:let7<ar7-.L" Login=idlet.jar
=I:let7<ar7SiAe" LRNO
'gain, don3t forget to change the si4e of the 0'> file to match the si4e of the
LoginMidlet.jar file after you create it.
't this point, the MI-let can be run as in the previous e6ample, using the MI-P
emulator of the 0ava &ireless Toolkit, with the following command+
em6lator 72descri'tor"Login=idlet.jad
In addition, the MI-let can be run with any other emulator you may have available.
*or e6ample, to whet your appetite, *igure #"; shows the .oginMidlet running on the
Motorola i:;s emulator (the i:;s is a 01M2"enabled cell phone available from
Motorola and @e6tel).
.igure %+3& ,oginidlet running in the otorola i93s emulator "cro$$ed#
%&0&2 (orking with the !mulator
@ote that the ob?ects represented by the Command class are shown above the two Isoft
buttonsI on the phone (the buttons with the black circles). If a soft button below the
command is pressed, the command immediately above it is e6ecuted. Here, if the user
enters the correct username and matching password and presses the .ogin button, the
menu of services will be displayed. =therwise, the alert will be displayed and the user
can try again.
'lso, you might be caught off guard the first time you try to enter te6t with your
computer keyboard. It doesn3t workC That3s because you must use the input keys on
the phone to enter the te6t. In this case, to enter the letter I<I, press the number IE.I
To enter the letter I7I, press the number I;I twice. @ote how each time you press a
numeral, the system IcyclesI through the letter corresponding to that number. To
move down to entering te6t for the password, use the down arrow.
&ell, that3s itC Dou3ve ?ust created two professional MI-lets using 01M2C In the ne6t
two chapters, we3re going to take a much closer look at the C.-C and the MI-P, two
e6citing new areas of wireless 0ava development.
Cha$ter 2& The Connected ,imited /evice
Configuration "C,/C#
The Connected .imited -evice Configuration (C.-C) defines a standard, minimum"
footprint 0ava platform for small, resource"constrained devices. 's we mentioned in
Chapter #, the C.-C was designed as a lowest common denominator of 0ava that can
be applicable to a wide variety of devices. However, features specific to a certain
vertical market, such as cell phones or pagers, are not found in the C.-C but are
instead defined in profiles that sit above it. Configurations primarily target devices
with similar amounts of memory and processing power.
This leads to a very important point about the C.-C+ there are no optional features.
2verything that the C.-C provides is usable on the devices that support it. 'fter all,
the primary goal of the C.-C is to ensure portability and interoperability between
applications running on various kinds of resource"constrained devices, which is the
main ob?ective of programming in 0ava. In this chapter, we discuss the C.-C and its
virtual machine, the 78M, in detail.
2&% !6amining the C,/C in /etail
.et3s start off with some specifics. 'ccording to the specification, the devices targeted
by the C.-C have the following characteristics+
160 KB to 512 KB of total memory
't a minimum, a C.-C device should have #1: 7B of non"volatile memory
for the 0ava 8M and the C.-C libraries, and at least 91 7B of volatile
memory for the 8M to use at runtime, independent of any applications.
16-bit or 32-bit processor with at least 25 Mhz speed
These types of processors are pretty typical in today3s handheld devices.
Connectiity to some !ind of networ!in"
&ith C.-C, this is often a two"way wireless connection with limited
bandwidth.
#ow power cons$mption
C.-C devices often operate under battery power. Hence, they have very low
power consumption.
-evices that fit these characteristics come in all shapes and si4es. Cell phones and
pagers immediately come to mind, but one could also install 0ava on bar code
scanners, video and audio e5uipment, navigation systems, and other wireless devices
yet to come. In fact, as the nature of these devices changes, you can e6pect that the
base specifications for the C.-C will change as well.
<iven the constraints listed above, the C.-C currently provides the following
functionality to its devices+
' subset of 0ava language and virtual machine features
' subset of core 0ava libraries (java.lang and java.6til)
Basic input,output (java.io)
Basic networking support (java&.microedition.io)
!ecurity
@ote, however, that the C.-C does not address application life cycle management,
user interfaces, event handling, or the interaction between the user and the application.
'gain, these features fall into the domain of profiles, such as the MI-P, which are
implemented on top of the C.-C and add to its functionality.
2&%&% (hat:s /ifferent A;out the Java -irtual achine)
&e mentioned that the C.-C does not have any optional features. 's you might
e6pect, this means that a number of features have been eliminated from 0ava virtual
machines that support the C.-C, either because they are too e6pensive (in terms of
memory or processing capability) to implement, or because their presence would
impose security problems. Therefore, if you3re new to programming with the C.-C,
you should be aware of the following limitations in C.-C 8Ms+
%o floatin" point s$pport
The C.-C does not support floating point numbersA therefore, C.-C"based
applications cannot use floating point types such as *loat or do6ble. This
decision was made because most C.-C target devices do not have floating
point support in their underlying hardware.
%o finalization
The C.-C 'PI currently does not include the @bject.*inaliAeF G methodA
you cannot perform final cleanup operations on ob?ect dataK"such as closing
resourcesKbefore an ob?ect is garbage"collected.
#imited error handlin"
>untime errors are handled in an implementation"specific manner. The C.-C
defines only three error classes+ java.lang.Error,
java.lang.@6t@*=emor+Error, and java.lang./irt6al=achineError.
@on"runtime errors are handled in a device"dependent manner that often
involves terminating the application or even resetting the device.
%o &aa %atie 'nterface (&%')
' 0ava virtual machine supporting the C.-C does not implement the 0@I.
There are actually two good reasons for this+ security, and the fact that
implementing 0@I is e6pensive, given the memory constraints of C.-C target
devices.
%o $ser-defined class loaders
' 0ava virtual machine supporting the C.-C must have a built"in class loader
that cannot be overridden or replaced by the user. This is for security reasons.
%o s$pport for reflection
C.-C applications do not have the ability to use the reflection 'PIs on their
ob?ects or classes. Because reflection is not supported, there is also no support
for ob?ect seriali4ation or >MI.
%o thread "ro$ps or daemon threads
&hile a 0ava virtual machine that supports the C.-C will implement
multithreading, it cannot support thread groups or daemon threads. If you want
to perform thread operations for groups of threads, use the collection ob?ects
to store the thread ob?ects at the application level.
%o wea! references
@o application built on a 0ava virtual machine supporting the C.-C can
re5uire weak references.
2&%&2 The 1-
The 78M, which was introduced in the previous chapter, is a complete 0ava runtime
environment for small devices. It is a true 0ava virtual machine as defined by the 0ava
8irtual Machine !pecification, e6cept for some deviations that are necessary for
proper functioning on small devices. The 78M was specifically designed for small,
resource"constrained devices that have only a few hundred kilobytes total memory.
The 01M2 white paper
G#H
describes the 78M as+
G#H
!ee also the 78M white paper, located at http+,,?ava.sun.com,products,cldc,wp,78Mwp.pdf, for much more
detail on the 78M.
-esigned for both #F"bit and 91"bit CI!C or >I!C processors and clocked at
processors as low as 1; Mh4
!mall, with a static memory footprint of ;% to :% 7B
Highly portable, modular, and customi4able
's complete and fast as possible, without sacrificing the other design goals
listed above
The 78M was derived from a research pro?ect called !potless at !un Microsystems
.aboratories. The aim of the pro?ect was to implement a 0ava system for the Palm
Connected =rgani4er.
G1H
The 78M is written in the C programming language (using
about 1E,%%% lines of code), so it can be easily ported to various platforms for which a
C"language compiler is available. *inally, like a regular 08M, the 78M can load
classes from a class path directory as well as from a 0'> file.
G1H
If you attended 0ava=ne #$$$, you3ll remember that this was a ma?or attraction. They even held a contest to see
who could design the best 78M application.
2&%&2&% Class -erification
In the 01!2 0ava virtual machine, the class verifier is responsible for re?ecting invalid
class files at runtime. ' 08M supporting C.-C must be able to re?ect invalid class
files as well. The class verification process, however, is e6pensive and time"
consuming+ it typically takes anywhere from 9; to ##% 7B of runtime memory. !ince
the target si4e of the 78M is ;% to :% 7B of memory, including a class verifier inside
it would violate its si4e constraints.
The 78M designers decided to move most of the verification work off the device and
onto the desktop, where the class files are compiled, or onto the server machine, from
which applications are downloaded. This step (off"device class verification) is
referred to as preverificationA that3s why we had to run the 'reveri*+ command on
the e6amples in Chapter #. =nce the preverification is completed, the resulting class
files often include e6tra information to ensure that the runtime verifier can perform its
?ob with only minimal effort and memory. (That3s why the preverified version of the
Login=idlet.class in Chapter # is slightly larger than the raw class generated by
the javac compiler.)
The additional output of the preverification process is the addition of a stack map
attribute that maps out critical areas of a class. This additional attribute is used by the
runtime verifier to pinpoint critical areas inside the class that must be checked. 'lso,
the preverifier will inline all subroutines in the bytecodes of the class file to prevent
any problems at runtime. -on3t worry, however. 2ven with the additional information,
the preverified class files can still work with a regular 0ava runtime verifier.
&ith the help of the preverification, the C.-C device is only responsible for running
a 5uick scan on the preverified class file to ensure that it was verified and does not
contain any illegal instructions. This cuts down significantly on the amount of
memory needed for the runtime verifier+ only #%% bytes or so.
2&%&2&2 5ecurit<
The C.-C security model is more strict than what you3re likely used to with the
01!2. This new security model is primarily concerned with two areas+
*irt$al machine-leel sec$rity
'n application e6ecuted by the 78M must not be able to harm the device in
which it is running. This is guaranteed by the class verifier, which ensures that
the class bytecodes cannot contain references to invalid memory locations. It
also ensures that the classes loaded cannot e6ecute in a way that is not allowed
by the 0ava 8irtual Machine !pecification. 's we mentioned, class verification
for the C.-C,78M is a two"step process+ off"device preverification in
con?unction with a minimal in"device verification. In addition, native methods
cannot be invoked at runtime.
+pplication-leel sec$rity
nlike the 01!2, the C.-C,78M combination does not allow the
customi4ation of a security manager. ' 08M supporting C.-C provides a
simple sandbo6 security model that enforces security by ensuring that
applications run in a closed environment, and that applications may only call
classes supported by the device.
2&%&0 (hat:s /ifferent A;out the Core Java ,i;raries)
The first thing that you3ll probably notice when working with the C.-C is that only a
bare minimum of 0ava 'PIs have been included. The reason for this is obvious if you
download the 0ava 1 !-7+ the standard edition 'PIs re5uire close to 1% megabytes of
memoryC This is memory that most small devices simply do not have. Hence, one of
the primary goals in designing the core C.-C libraries was to boil the 01!2 'PIs off
into a minimum set of libraries that could still be used for meaningful application and
profile development.
&ith that in mind, it3s helpful to think of the C.-C library 'PIs as divided into two
categories+ classes that are a subset of the 01!2 'PIs and new classes that are specific
to the C.-C. .et3s look at the former group first.
2&%&0&% Classes inherited from J25!
The C.-C uses only thirty"seven classes from the 01!2 platform. These classes come
from the java.lang, java.io, and java.6til packages, which are derived from
0-7 #.1 'PIs. @ote that according to the 01M2 specification, I2ach class that has the
same name and package name as a 01!2 class must be identical to, or a subset of, the
corresponding 01!2 class. The semantics of the classes and methods cannot be
changed, and the classes cannot add any '6blic or 'rotected methods or fields that
are not available in the corresponding 01!2 class libraries.I In other words, you
cannot add, but you can take away. 'nd many classes have functionality taken away.
The inherited classes and interfaces (not including e6ceptions) from the 01!2 platform
are shown in Table 1"#.
Ta;le 2+%& Inherited, non+e6ce$tional classes
Package Classes
?ava.lang
Boolean, Byte, Character, Class, Integer, .ong, Math, =b?ect, >unnable, >untime, !hort,
!tring, !tringBuffer, !ystem, Thread, Throwable
?ava.io Byte'rrayInput!tream, Byte'rray=utput!tream, -ataInput, -ata=utput, -ataInput!tream,
-ata=utput!tream, Input!tream, =utput!tream, Input!tream>eader, =utput!tream&riter,
Print!tream, >eader, &riter
?ava.util Calendar, -ate, 2numeration, Hashtable, >andom, !tack, TimeMone, 8ector
Because all inherited classes must throw precisely the same e6ceptions as regular
01!2 classes, the following 1$ e6ception and error classes shown in Table 1"1 also
derive from the 01!2 'PIs.
Ta;le 2+2& Inherited e6ce$tion and error classes
Package Class
?ava.lang
'rithmetic26ception, 'rrayInde6=ut=fBounds26ception, 'rray!tore26ception,
ClassCast26ception, Class@ot*ound26ception, 2rror, 26ception, Illegal'ccess26ception,
Illegal'rgument26ception, IllegalMonitor!tate26ception, IllegalThread!tate26ception,
Inde6=ut=fBounds26ception, Instantiation26ception, Interrupted26ception,
=ut=fMemory26ception, @egative'rray!i4e26ception, @umber*ormat26ception,
@ullPointer26ception, >untime26ception, !ecurity26ception,
!tringInde6=ut=fBounds26ception, 8irtualMachine2rror
?ava.io
2=*26ception, I=26ception, InterruptedI=26ception, nsupported2ncoding26ception,
T*-ata*ormat26ception
?ava.util 2mpty!tack26ception, @o!uch2lement26ception
&hen programming with the C.-C, there are many internal modifications to the
01!2 classes you3re used to. Here are some of the more common classes that may
cause problems.
2&%&0&2 5tring and 5tringBuffer
The following methods have been removed from the ubi5uitous java.lang.String
class, either because they refer to floating"point data types or because their presence is
redundant+
'6blic void val6e@*F*loat *G
'6blic void val6e@*Fdo6ble dG
'6blic int com'areToIgnoreCaseFString strG
'6blic boolean eB6alsIgnoreCaseFString anotherStrG
'6blic static co'+/al6e@*Fchar34 dataG
'6blic static String co'+/al6e@*Fchar34 dataJ int o**setJ
int co6ntG
'6blic String internF G
'6blic int lastInde&@*FString strG
'6blic int lastInde&@*FString strJ int *romInde&G
'6blic boolean region=atchesFint to**setJ String otherJ
int oo**setJ int lenG
'6blic String toLo%erCaseFjava.6til.Locale localeG
'6blic String to-''erCaseFjava.6til.Locale localeG
*or the same reasons, the following methods have been eliminated from the
java.lang.StringE6**er class.
'6blic StringE6**er a''endF*loat *G
'6blic StringE6**er a''endFdo6ble dG
'6blic StringE6**er insertFint o**setJ *loat *G
'6blic StringE6**er insertFint o**setJ do6ble dG
'6blic StringE6**er insertFint inde&J char34 strJ
int o**setJ int lenG
'6blic StringE6**er re'laceFint startJ int endJ String strG
'6blic String s6bstringFint startG
'6blic String s6bstringFint startJ int endG
2&%&0&0 4untime
The java.lang..6ntime class has eliminated most of its methods for the C.-C.
Here, only the following subset of methods is now available+
'6blic void e&itFint stat6sG!
'6blic native long *ree=emor+F G!
'6blic native void gcF G!
'6blic static .6ntime get.6ntimeF G!
'6blic native long total=emor+F G!
2&%&0&2 5<stem
In addition, the java.lang.S+stem class only has the following fields and methods
available to it+
'6blic static *inal PrintStream err!
'6blic static *inal PrintStream o6t!
'6blic static native void arra+co'+F@bject srcJ
int src?'ositionJ @bject dstJ int dst?'ositionJ int lengthG!
'6blic static native long c6rrentTime=illisF G!
'6blic static void e&itFint stat6sG!
'6blic static void gcF G!
'6blic static String
getPro'ert+FString ke+G!
'6blic static native int identit+HashCodeF@bject &G!
2&%&0&3 ath
*inally, as you might e6pect, the java.lang.=ath class has eliminated all methods
dealing with comple6 floating"point operations (which was the vast ma?ority of
methods in that class), and now only has the following methods+
'6blic static int absFint aG!
'6blic static long absFlong aG!
'6blic static int ma&Fint aJ int bG!
'6blic static long ma&Flong aJ long bG!
'6blic static int minFint aJ int bG!
'6blic static long minFlong aJ long bG!
In many cases, the absence of these methods are only a minor inconvenience and
suitable workarounds can be used. 01M2 functionalities that re5uire the use of
floating"point values, however, may have to e6pand their floating"point values to
integers with an implied decimal point and improvise with the more limited set of
integer operations.
2&%&2 (hat:s /ifferent A;out I=' and >etworking)
>ecall that the 01!2 provides the java.io and java.net packages for I,= and
network connectivity. The C.-C inherits some of the classes in the java.io package.
However, the ma?or difference is that it does not inherit classes related to file I,=. *or
e6ample, the popular 0ileIn'6tStream and 0ile@6t'6tStream classes are not
present. In addition, the 0ile.eader and 0ileWriter classes are not offered for
reading and writing te6t data. This is because not all C.-C devices support the
concept of a filesystem.
's for the java.net package, the 01!2 provides several classes for network
connectivity. However, none of these classes have been inherited because not all
devices re5uire TCP,IP or -P,IP. (!ome devices may not even have an IP stack.)
Instead, the C.-C e6pert group decided to define a more generic set of classes for
01M2 I,= and network connectivity. These classes are known as the )eneric
Connection *ramework+ and are found in the java&.microedition.io package.
2&%&2&% The ?eneric Connection .ramework
The <eneric Connection *ramework is a platform"independent framework that
provides its functionality without any dependence on the specific features of a device.
In fact, this framework is so generic that it doesn3t implement any of the I,= or
network connectivity interfacesA rather, the profile above it provides such
implementation.
Here3s a 5uick rundown of how the <eneric Connection *ramework works+ all
connections are created using the static o'enF G method from the *actor+
Connector class. If successful, this method returns an ob?ect that implements one of
the generic connection interfaces for the host device. If you3re a 01!2 programmer,
this will be much different than what you3re used to. However, it will also be much
easier. To give you a taste of what this is like, here are some e6ample connections
from the 01M2 specification that you might re5uest from a C.-C application and the
appropriate synta6 to implement them+
,--. connection
Connector.o'enFIhtt'"))%%%.ora.com"'ortIG!
/oc!et connection
Connector.o'enFIsocket"))%%%.ora.com"'ortIG!
Comm$nication with a port
Connector.o'enFIcomm"K!ba6drate=SOKKIG!
The goal of the above synta6 is to isolate any differences in the protocol that you3re
attempting to connect with into a simple string. This way, most of the application3s
code remains the same, regardless of the protocol you use. The <eneric Connection
*ramework is discussed in more detail in Chapter N.
2&%&3 /ifferences with Pro$ert< 5u$$ort in the C,/C
8irtual machines that support the C.-C, such as the 78M, do not implement the
java.6til.Pro'erties class, which follows from the lack of filesystem
functionality that we mentioned above. However, four system properties are supported
for each 01M2,C.-C device, and can be accessed by using the method
S+stem.getPro'ert+FString ke+G. The four properties available are described in
Table 1"9.
Ta;le 2+0& 5<stem $ro$erties
System property Description Default value
microedition.'lat*orm @ame of the host platform or device n6ll
microedition.encoding -efault character encoding II!=::;$O#I
microedition.con*ig6ration @ame and version of the support configuration IC.-C"#.%I
microedition.'ro*iles @ame of the supported profiles n6ll
There3s very little to say here, e6cept that you can use these properties to ensure that
you3re indeed on a C.-C device that supports the proper encoding and profiles for
your application. The MI-P profile defines some additional properties, which we will
discuss in Chapter 9.
2&2 Using the 5tandalone C,/C and 1-
If you want to e6periment with the raw 78M and C.-C classes, you can download
the standalone C.-C and 78M. 's of this writing, the latest edition of the C.-C
itself is version #.%.1. The C.-C #.%.1 contains an updated version of the 78M. The
78M code has been rewritten to improve performance and includes a faster bytecode
interpreter, better garbage collection, 0ava"level debugging 'PIs, preverifier
improvements, and several bug fi6es. If you wish to download the standalone C.-C
and 78M, you can find it at the following address+ http+,,?ava.sun.com,products,kvm.
@ote that this is different than the 01M2 &ireless Toolkit that we
used in Chapter #. This distribution does not contain any MI-P
classes, nor does it contain a MI-P emulator. Hence, it will only
e6ecute programs that adhere to the base C.-C specification and
not any MI-P functionality. If you are solely interested in
writing applications for the MI-P, you can ?ust read through this
section without taking any action.
This distribution contains 78M implementations for &indows, !olaris, and .inu6
operating systems, as well as the C.-C classes that can be used to compile and run
applications. 'fter downloading and uncompressing the distribution, you should have
a series of directories, as shown in Table 1"E.
Ta;le 2+2& C,/C=1- directories
Directory Description
a'i The 0ava classes and source code for the C.-C
bin Binaries for each of the target platforms
b6ild tility that builds directories and makefiles for each target platform
docs P-* documentation, as well as compressed ?avadocs
jam
0ava 'pplication Manager, which can be used to dynamically download classes into the
78M
kvm !ource and build files pertaining to the 78M
sam'les !ample code that can be used with the C.-C
tools !ource for the various tools used with the C.-C
*eel free to look through the api directory to see what you have. It3s not much,
compared to the 01!2. In any case, there are some interesting things that we can show
you with the 78M and the C.-C in this distribution. *irst, create a simple program
that can be run with the C.-C as follows+
'6blic class CL:CTest D
'6blic static void mainFString34 argsG D
S+stem.o6t.'rintlnFIHello CL:CTIG!
H
H
Then, try compiling the program with the standard javac compiler. In the e6ample
below, we use a command line, similar to that in the first chapter, in order to ensure
that only the C.-C classes are used. @ote that the subse5uent series of commands
assumes that you are in the base directory of the C.-C,78M distribution+
javac 7bootclass'ath a'i)classes.Ai' CL:CTest.java
>emember that we must preverify our resulting class before running it with the 78M,
like we did in Chapter #. Dou can do so with the following command+
bin)3target@S4)'reveri*+ 7class'ath a'i)classes.Ai'". CL:CTest
's before, this should create a separate directory, here called output, where the
preverified class has been stored. Dou can now run this class with the 78M, using the
following command+
bin)3target@S4)kvm 7class'ath a'i)classes.Ai'"o6t'6t CL:CTest
Hello CL:CT
@e6t, try modifying the source code so that it adds a declaration of the float variable+
'6blic class CL:CTest D
*loat *!
'6blic static void mainFString34 argsG D
S+stem.o6t.'rintlnFIHello CL:CTIG!
H
H
'nd again, try recompiling it and preverifying it with the above commands. If you try
running the resulting program, the 78M will flag the inclusion of a floating"point
field in the class as an error+
ALE.T" Ead *ield signat6re
&hy didn3t the compiler flag the use of the floating"point variable as an errorL
>emember that you3re using the javac compiler from 01!2 to compile your 01M2
programs, and that compiler is all too familiar with the use of floating"point variables.
Hence, it will assume that the primitive data types that it knows about are fine for use
with whatever 08M is on the other side of the compilation. In addition, the preverifier
will not search for floating"point variables because its ?ob (at least, on the desktop
side) is to look for security issues within classes, not to hunt down invalid primitive
data types. (>emember we mentioned earlier that preverified class files must work
under the regular 01!2.) Hence, the 78M itself has to tell us that one of our fields is
not supported in the virtual machine, which it does by scanning through the class files
before e6ecuting them. There3s an important lesson here+ ?ust because the compiler
and preverifier successfully translated a source file to a class with only the C.-C
classes on its bootclasspath doesn3t mean that it will still run. Dou should always test it
with the 78M as well, to see if the code has any 8M issues.
That3s not to say that if we used a method that is no longer in the C.-C classes, the
compiler wouldn3t notice. *or e6ample, assume that we modified our code to be the
following+
'6blic class CL:CTest D
static String s = IHello CL:CTI!
static int r = s.com'areToIgnoreCaseFIHELL@ CL:CTIG!
'6blic static void mainFString34 argsG D
S+stem.o6t.'rintlnFs U I"I U rG!
H
H
This yields the following compiler error+
CL:CTest.java"V" cannot resolve s+mbol
s+mbol" method com'areToIgnoreCaseFjava.lang.StringG
location" class java.lang.String
Here, the compiler flagged an error because the String class that was located on its
bootclasspath does not contain the method in 5uestion, com'areToIgnoreCaseF G.
's we mentioned earlier in the chapter, this method has been omitted in the C.-C
subset of java.lang.String.
2&0 C,/C >e6t ?eneration
*inally, let3s briefly mention the C.-C @e6t <eneration (@<). The C.-C @< is a
specification that is currently in development and that aims to define a revised version
of the C.-C. The goal of the C.-C @< is to make the C.-C more compliant with
the 0ava language and virtual machine specifications by reintroducing features such as
floating"point support and improved error"handling capabilities.
!ome other goals of the C.-C @< will be to+
Maintain backward compatibility with C.-C #.%.
Maintain small footprint (limit 'PI growth).
Continue focus on small, resource"constrained, connected devices.
Investigate the possibility of adding a minimal security manager.
@ote, however, that not many new 'PIs will be reintroduced to the C.-C with this
revision. -evices that re5uire significantly more complete 0ava libraries should use
the Connected -evice Configuration (C-C) instead. Dou can follow the progress of
the C.-C @< at the 0ava Community Process web site at+ http+,,www.?cp.org,.
Cha$ter 0& The o;ile Information/evice Profile
"I/P#
The Mobile Information -evice Profile (MI-P) is built on top of the C.-C, and
defines an open application development environment for what !un calls Mo&ile
,nformation Devices (MI-s). In simpler terms, MI-P is the 01M2 profile that is used
for wireless devices, such as mobile phones and pagers. This chapter e6pands on the
previous chapter by introducing some of the fundamental concepts of MI-P and
offering programming guidelines that are used throughout the remainder of this book.
's we mentioned in Chapter #, the MI-P is governed by the 0ava Community
Process. The MI-P is 0!> 9N, which is part of the 0ava Community Process. .ike the
C.-C, the MI-P is an ever"changing standard that actively solicits input from
corporations and the general programming community. Dou can find more
information on the MI-P at the following >.+ http+,,?ava.sun.com,products,midp.
0&% o;ile Information /evices
'gain, let3s start off with some specifics. The MI-P standard defines a MI- as a
device with the following minimum characteristics+
0isplay
' screen si4e of at least $F 6 ;E pi6els with at least a #"bit display depth
'np$t
' one"handed keyboard, two"handed keyboard, or touch screen
Memory
91 7B of volatile memory for the 0ava runtime (heap)A #1: 7B of non"volatile
memory for the MI-P componentsA and : 7B of non"volatile memory for
application"created persistent data
%etwor!in"
' two"way intermittent connection, usually wireless, with limited bandwidth
Because the MI-P is built on top of the C.-C, it addresses the following areas that
are omitted by the C.-C+
+pplication #ife Cycle Mana"ement
The MI-P includes the java&.microedition.midlet package, which
contains classes and methods for starting, pausing, and destroying applications
in the host environment.
1ser 'nterface and 2ents
The MI-P also provides the java&.microedition.lcd6i packages, which
include classes and interfaces for creating <I components for applications.
%etwor! Connectiity
The MI-P e6tends the ContentConnection interface of the <eneric
Connection *ramework by providing the Htt'Connection interface, as well
as a subset implementation of the HTTP protocol.
/torin" 0ata on 0eice
The MI-P also provides the java&.microedition.rms package, which
implements a record"based database management system. This provides
applications with the capability to store data on the device.
The MI-P has received wide corporate backing, from companies such as '=., --I,
2ricsson, *u?itsu, Hitachi, Matsushita, Mitsubishi, Motorola, @2C, @okia, @TT
-oCoMo, Palm, >esearch in Motion (>IM), !amsung, !harp, !iemens, !ony, !print,
and !ymbian. In the second 5uarter of 1%%#, Motorola released the first MI-P"
enabled cellular phones, the i;%6 and the i:;s.
G#H
=ver the ne6t year or two, you3ll
likely see an impressive amount of MI-P"enabled devices reach the market.
G#H
The service for the i;%6 and i:;s phones is provided in the nited !tates and Canada by @e6tel, Inc.
0&%&% Class Additions
The MI-P adds the following packages to those available through the C.-C, as
shown in Table 9"#.
Ta;le 0+%& >ew $ackages in the I/P
Package Description
?ava6.microedition.lcdui <raphical interface components and events
?ava6.microedition.midlet 'pplication life cycle
?ava6.microedition.rms >ecord storage
Here are the classes that are included with each of the new packages. The first
package, java&.microedition.lcd6i, contains interfaces and classes, listed in Table
9"1, that are used to build graphical interfaces on the limited displays of C.-C
devices. These classes are discussed in detail in Chapter ; and Chapter F.
Classes and interfaces in the ?ava6.microedition.lcdui package
Name Type
Choice Interface
CommandListener Interface
ItemStateListener Interface
Alert Class
AlertT+'e Class
Canvas Class
ChoiceWro6' Class
Command Class
:ate0ield Class
:is'la+ Class
:is'la+able Class
0ont Class
0orm Class
Wa6ge Class
Wra'hics Class
Image Class
ImageItem Class
Item Class
List Class
Screen Class
StringItem Class
Te&tEo& Class
Te&t0ield Class
Ticker Class
The ne6t package, java&.microedition.midlet (see Gclick hereH), adds only one
class that serves as the base class for all MI-lets. This class can only throw one
e6ception as well, which notifies listeners of a state change in the MI-let. This class
is discussed in detail in Chapter E.
Class and e6ception in the ?ava6.microedition.midlet package
Name Type
=I:let Class
=I:letStateChangeE&ce'tion 26ception
*inally, the java&.microedition.rms package provides four interfaces, one class,
and five e6ceptions (see Table 9"E) for performing persistent data storage on MI-P
devices. The four interfaces allow you to create implementing classes that customi4e
how the record store compares, enumerates through, filters, and handles events that
occur with data records. These classes are discussed in detail in Chapter :.
The classes, interfaces, and e6ceptions in the ?ava6.microedition.rms package
Name Type
.ecordCom'arator Interface
.ecordEn6meration Interface
>ecord*ilter Interface
>ecord.istener Interface
>ecord!tore Class
Invalid.ecordI:E&ce'tion 26ception
.ecordStoreE&ce'tion 26ception
.ecordStore06llE&ce'tion 26ception
.ecordStoreMot0o6ndE&ce'tion 26ception
.ecordStoreMot@'enE&ce'tion 26ception
In addition to these packages, the MI-P also adds two classes and one e6ception to
those classes in the java.lang and java.6til packages of the C.-C. These classes
are similar to those found in the 0ava !-7 #.9.
java.lang.IllegalStateE&ce'tion (e6ception)
java.6til.Timer (class)
java.6til.TimerTask (class)
's you can see, there aren3t many classes in the MI-P. However, that3s not
une6pected, given that we need to fit MI-P programs in such a limited space. But
don3t worry. &e3ll discuss each of the new classes, interfaces, and e6ceptions of the
MI-P as we progress through the remainder of the book.
0&%&2 5<stem Pro$erties
The MI-P defines two additional property values (in addition to the eight in the
previous chapter) that can be retrieved using the
java.lang.S+stem.getPro'ert+F G method. These are shown in Table 9"1+
Ta;le 0+2& 5<stem $ro$erties defined ;< the I/P
System property Description
microedition.local The current locale of the device (default+ n6ll)
microedition.'ro*iles Must contain at least IMI-P"#.%I
The microedition.local property consists of the language and country code
separated by a dash I"I. *or e6ample, Ien7CAI for 2nglish Canada and Ien7-SI for
2nglish !'. @ote that the language code must be lowercase, and the country code
must be uppercase.
0&2 ore A;out I/lets
In Chapter #, we introduced you to MI-lets, applications that run on MI-P devices.
MI-lets are written as one or more 0ava classes whose ob?ects are compressed into a
0'> file. .ike 0ava applets, MI-P applications have an application life cycle while
running on a mobile device. !pecifically, a MI-let can be in one of three states+
Paused
'ctive
-estroyed
*igure 9"# shows the rules for transitioning between states.
.igure 0+%& I/let transition states
Here is a 5uick rundown of how MI-P applications change state+ when a MI-let is
first started, it is placed in the paused state. 'fter it3s ready, the controlling software
will then place the MI-let in the active state. 't this point, the MI-let is running and
the user can interact with it. The application can be placed back in the paused state by
either the MI-P system or the program itself. In addition, the MI-P can be moved to
the destroyed state from either the paused or the active state, again by either the MI-P
system or the programmer. In the destroyed state, the MI-let should release all of the
resources it currently has back to the MI-P system.
&e3ll cover this in more detail in the following chapter, where we create and e6ecute a
MI-let with multiple states. In the meantime, this 5uick introduction brings us to the
point where we must first introduce some important concepts.
0&2&% (hat Is a I/let 5uite)
' M,Dlet suite is simply two or more MI-lets that are packaged in a 0'> file.
MI-lets within the same suite can use the classes and resources contained in the 0'>
file, much like any standard 0ava application, the classes of which are loaded by the
same class loader.
0&2&%&% The JA4 anifest
The 0'> file of a MI-let suite often contains a manifest file with MI-let attributes
defined. These attributes describe the contents of the 0'> file, which is in turn used
by the application management software to identify and install the MI-let suite. The
attributes defined by the MI-P specification are listed in Table 9"9.
Ta;le 0+0& JA4 manifest attri;utes
Attribute name Required Description
=icroEdition7
Con*ig6ration
Des
The name and version of the 01M2 configuration re5uired. This uses
the same format as the =icroEdition.con*ig6ration system
property (for e6ample, IC.-C"#.%I).
=icroEdition7
Pro*ile
Des
The name and version of the 01M2 profile re5uired. This uses the same
format as the microedition.'ro*iles system property (for
e6ample, IMI-P"#.%I).
=I:let7n Des
The name, icon, and class, separated by commas, of the nth MI-let in
the MI-let suite.
=I:let7:ata7
SiAe
@o
The minimum number of bytes of persistent storage that the MI-let
re5uires. The default is 4ero.
=I:let7
:escri'tion
@o ' description of the =I:let suite.
=I:let7Icon @o
The pathname of a P@< file within the 0'> file to identify the MI-let
suite (not the individual MI-lets). It is used by the application
management software to display an icon to identify the suite.
=I:let7In*o7
-.L
Des
' pointer to a >. containing a detailed description of the MI-let
suite.
=I:let7Mame Des The name of the MI-let suite.
=I:let7/endor Des The name of the organi4ation (or vendor) providing the suite.
=I:let7/ersion Des
The version number of the MI-let suite presented in the format
//.DD.MM, where // is the ma?or, DD is the minor, and MM is the
micro. If the micro is omitted, the default is 4ero. Therefore, the micro
is optional. This information is used by the application management
software for install and upgrade uses.
26ample 9"# shows a sample manifest for a MI-let suite (in this case, only two
MI-lets) for a shopping MI-let.
!6am$le 0+%& A sam$le manifest
=I:let7Mame" Sho'@nLine
=I:let7/ersion" L.K
=I:let7/endor" SEL>@=
=I:let7:escri'tion" a sho''ing =I:let
=I:let7In*o7-.L" htt'"))%%%.selkom.com)sho'
=I:let7:ata7SiAe" XKK
=I:let7L" E6+=I:letJ )icons)b6+.'ngJ com.selkom.E6+=I:let
=I:let7$" Pa+=I:letJ )icons)sell.'ngJ com.selkom.Sell=I:let
=icroEdition7Pro*ile" =I:P7L.K
=icroEdition7Con*ig6ration" CL:C7L.K
0&2&2 Java A$$lication /escri$tor "JA/#
sing a manifest to describe the MI-lets in the suite is a bit problematic. In Chapter
#, we mentioned that before downloading a MI-let or a MI-let suite to a device, the
0ava 'pplication Manager should check to make sure there is enough space for it.
sing a manifest, however, means that the 0ava 'pplication Manager should
download the 0'> file in order to read the manifest. Imagine downloading a MI-let
suite only to discover it cannot be installed on your device because it re5uires the ne6t
generation MI-P. To avoid these problems, the MI-P specification also defines the
0ava 'pplication -escriptor (0'-).
' 0'- file is a te6t file that is similar to a manifest. nlike a manifest, however, it is
not packaged in the 0'> file. !imilar to a manifest, it consists of a series of attributes
used to describe a MI-let suite. The possible attributes are shown in Table 9"E.
Ta;le 0+2& JA/ attri;utes
Attribute name Required Description
=I:let7Mame Des The name of the MI-let suite.
=I:let7
/ersion
Des
The version number of the MI-let suite. The format is //.DD or
//.DD.MM, where // is the ma?or, DD is the minor, and MM is the micro
that is optional. If the micro is omitted, the default is 4ero.
=I:let7/endor Des The vendor of the MI-let suite.
=I:let7<ar7
-.L
Des The >. from which to download the MI-let suite.
=I:let7<ar7
SiAe
Des The si4e of the MI-let suite in bytes.
=I:let7
:escri'tion
@o ' description of the MI-let suite.
=I:let7Icon @o
The pathname of a P@< file for the suite. The icon is used to identify the
suite.
=I:let7In*o7
-.L
@o ' >. that describes the MI-let suite in greater detail.
=I:let7:ata7
SiAe
@o
The minimum number of bytes of persistent storage the MI-let suite
re5uires. If not specified, the default is 4ero.
's you can see from Table 9"1 and Table 9"9, there are some common attributes
between the manifest and the 0'- file. The mandatory attributes that must be
duplicated in both the manifest and the 0'- file are+ =I:let7Mame, =I:let7/ersion,
and =I:let7/endor.
26ample 9"1 shows a 0'- file for the same hypothetical MI-let suite.
!6am$le 0+2& A sam$le JA/ file
=I:let7Mame" Sho'@nLine
=I:let7/ersion" L.K
=I:let7/endor" SEL>@=
=I:let7<ar7-.L"
http://www.selkom.com/shop/mid.jar
=I:let7<ar7SiAe" PXVV
=I:let7:ata7SiAe" XKK
'nd that3s the difference between a 0'> manifest file and a 0'- file in a MI-let
suite.
0&2&0 Programming ?uidelines
Before we start programming with MI-lets, let3s briefly discuss some guidelines that
are useful when developing applications for mobile information devices such as cell
phones and P-'s that you likely haven3t considered before.
0&2&0&% Performance
&hen programming for mobile devices with a small memory footprint, it is crucial to
make your applications run faster. The less time your application takes to run, the
happier your customers will be. *or the 01!2 programmer, here are some ways to help
you achieve the best performance+
se local variables instead of fields. 'ccessing local variables is 5uicker than
accessing class members.
Minimi4e method calls.>emember that the 0ava virtual machine uses the stack
to load and store a stack frame for every method it e6ecutes. *or e6ample,
instead of doing something like+
*or Fint i=K! i8obj.getLengthF G! iUUG D
)) do something %ith arra+ elements
H
where the length of the array is evaluated every time through the loop, it is
much more efficient to do this+
int len = obj.getLengthF G!
*or Fint i=K! i8len! iUUG D
)) do something %ith arra+ elements
H
'void string concatenation. This may cause a lot of ob?ect creation and
subse5uent garbage collection, and therefore decreases performance and
increases the application3s memory usage. It3s often more efficient to use
StringE6**er instead.
Minimi4e ob?ect creation. =b?ect creation leads to ob?ect destruction and
reduces performance. Instead, design ob?ects that can be recycled. Instead of
creating return ob?ects inside of methods, consider passing in a reference to the
return ob?ect and modifying its values.
'void synchroni4ation.If an operation takes longer than a fraction of a second
to run, consider placing it in a separate thread.
Part II: Programming with the C,/Cand the
I/P
Part II starts by elaborating on some of the concepts introduced in
Chapter 9. .ater chapters show how to program with the C.-C,MI-P
'PIs, including <I, event handling, networking, and databases.
Chapter $ shows how to convert MI-lets into e6ecutable Palm
applications for handheld devices running Palm =! v9.; or higher.
Chapter E
Chapter ;
Chapter F
Chapter N
Chapter :
Chapter $
Cha$ter 2& (orking with I/lets
MI-lets are very simple to implement. 'll MI-lets must e6tend the
java&.microedition.midlet.=I:let abstract class and implement certain methods
in that class. The =I:let abstract class provides the basic functionality re5uired in all
MI-lets. ' MI-let runs in a controlled environment and therefore must implement
certain methods that allow the application manager (which installs and runs the
MI-let) to control the behavior of the MI-let. These methods are known as life c'cle
met-ods, since they reflect various states in which a MI-let can be.
Dou3ll recall from the previous chapter that a MI-let can be in one of three states+
paused, active, or destroyed. The state chart in *igure E"# shows the possible state
transitions of a MI-let, this time with the addition of the methods that the 0ava
Manager will call inside the MI-let code during those transitions.
.igure 2+%& I/let state transitions
Here, the java&.microedition.midlet.=I:let abstract class defines three life
cycle methods that are called during the state transitions+ 'a6seA''FG, startA''FG,
and destro+A''FG. These three methods were present in the e6ample we developed
in Chapter #. The responsibilities for these three life cycle methods are as follows.
'6blic void startA''F G
This method indicates that the MI-let is moving from a paused state to an
active state. Here, the MI-let will typically initiali4e any ob?ects that are
re5uired while the MI-let is active, and set the current display.
'6blic void 'a6seA''F G
This method is called when the MI-let is moving from an active state to a
paused state. This means that it will pause any threads that are currently active,
as well as optionally setting the ne6t display to be shown when the MI-let is
re"activated. -ata can be persisted, if necessary, and retrieved later when the
MI-let is activated again.
'6blic void destro+A''Fboolean 6nconditionalG
This method indicates that the MI-let is moving to the destroyed state. It
should free or close all resources that have been ac5uired during the life of the
MI-let. In addition, the method should persist any data that it wishes to save
for future use.
It is important to note that startA''F G can be called more than once. In addition to
being called when the MI-let is first activated to move the MI-let from the paused
state to the active state, it can also be called if the MI-let has been paused during
e6ecution and wishes to again return to the active state.
2&% The A$$lication anager
The application manager, sometimes called the 'pplication Management !ystem
('M!) or MI-let management software, is software that is preinstalled on a MI-P
device and that functions as an operating environment. *or e6ample, on a Motorola
i:;s, the 0ava 'pps menu item will start the application manager, which immediately
shows the 0ava logo and the words IMobile Information -evice Profile CompatibleI
and then displays a menu of the MI-let suites that have been installed on the phone.
However, the application manager must do more than simply show a menu of the
MI-let suites that are installed. 'ccording to the MI-P specification, the application
manager must be able to+
>etrieve a MI-let suite from somewhere, possibly through a serial connection,
infrared connection, or across a wireless connection to the Internet
Install a MI-let suite on the MI-P device
Perform version management on MI-let suites that are installed
.aunch a MI-let from a MI-let suite and provide an operating environment
for the 78M, as well as any system, MI-P, and C.-C classes
-elete a previously installed MI-let suite
's a MI-let programmer, you typically won3t need to be concerned with the internals
of the application manager running on the deviceKit3s uni5ue to each device.
However, some insight into its responsibilities is important when designing MI-P
applications. In this case, the MI-let life cycle methods can be called by the
application manager to control the MI-let state+
&hen the user launches a MI-let, the application manager creates a new
instance of the MI-let class by calling its 4ero"argument constructor. This
typically performs the one"time initiali4ation. =nce this is done, the MI-let
will be placed in a paused state. However, if any e6ception occurs during the
instantiation of the MI-let class, the application manager will move the class
to the destroyed state.
'fter the MI-let has been placed in the paused state, the application manager
calls startA''F G to transition it to the active state.
The application manager can then call 'a6seA''F G to move it from the active
state to the paused state, either via a re5uest from the program itself or from
the operating environment.
destro+A''F G can be called by the application manager to transition the
MI-let to the destroyed state. The destro+A''FG method takes a boolean
argument to indicate if the MI-let should clean up or not.
26ample E"# shows a MI-let skeleton class that implements the life cycle methods of
the java&.microedition.midlet.=I:let class.
!6am$le 2+%& I/let skeleton
im'ort java&.microedition.midlet.C!
'6blic class =+=I:let e&tends =I:let D
'6blic =+=I:letF G D
)) constr6ctor
H
'6blic void startA''F G D
)) entering active state
H
'6blic void 'a6seA''F G D
)) entering 'a6sed state
H
'6blic void destro+A''F boolean 6nconditionalG D
)) entering destro+ed state
H
H
Believe it or not, this class is all you need to create a MI-let. The only thing we
should reiterate is our earlier warning that startA''F G can be called more than
once. Hence, if you have any one"time initiali4ation that you wish to perform for your
MI-let, be sure that it is placed in the constructor of the MI-let ob?ect and not in the
startA''F G method.
2arlier, we mentioned that a MI-let could change its own state if needed. The
java&.microedition.midlet.=I:let abstract class provides three methods that can
be called by a MI-let to control its own state transitions+
'6blic void noti*+Pa6seF G
' MI-let may call this method to pause itself. It can be called while in the
active state, to inform the 0ava 'pplication Manager that the MI-let has
entered the paused state.
'6blic void res6me.eB6estF G
' MI-let may call this method to e6press interest in entering the active state.
The application manager also calls this method to determine which MI-let to
activate, then it calls its startA''F G method.
'6blic void noti*+:estro+edF G
' MI-let calls this method to destroy itself. It can be called while in the active
state or the paused state, to indicate to the application manager that it has
entered the destroyed state. @ote that the application manager will not call
destro+A''F G. Conse5uently, the MI-let manages the release of its
resources.
2&2 Creating I/lets
@ow that you3re familiar with MI-let states and the application manager, let3s create
another MI-let. 's you3ve probably guessed by now, this involves the following five
steps+
#. &rite the MI-let.
1. Compile the MI-let3s source code.
9. Preverify the MI-let3s class file.
E. Package the application in a 0'> file.
;. Create a 0'- file.
.et3s review each of these steps. *irst, we3ll look at the command"line techni5ue that
was shown in Chapter #. Then, we3ll introduce the 7Toolbar application, which comes
with the 01M2 &ireless Toolkit and which can make our lives much easier.
2&2&% (rite the I/let
The first step in the development life cycle is to write the MI-let. 26ample E"1 shows
a simple MI-let, Pa+ment=I:let. This MI-let creates a List ob?ect of type
2/C.!I82 (that is, only one option can be selected at a time), and adds three
methods of payments to it. It displays a list of options for the user to select a method
of payment.
!6am$le 2+2& 5am$le I/let
im'ort java&.microedition.midlet.C!
im'ort java&.microedition.lcd6i.C!
'6blic class Pa+ment=I:let e&tends =I:let D
)) The dis'la+ *or this =I:let
'rivate :is'la+ dis'la+!
)) List to dis'la+ 'a+ment methods
List method = n6ll!
'6blic Pa+ment=I:letF G D
method = ne% ListFI=ethod o* Pa+mentIJ
Choice.E2CL-SI/EG!
H
'6blic void startA''F G D
dis'la+ = :is'la+.get:is'la+FthisG!
method.a''endFI/isaIJ n6llG!
method.a''endFI=asterCardIJ n6llG!
method.a''endFIAme&IJ n6llG!
dis'la+.setC6rrentFmethodG!
H
)CC
C Pa6se is a no7o' since there are no backgro6nd
C activities or record stores that need to be closed.
C)
'6blic void 'a6seA''F G D
H
)CC
C :estro+ m6st clean6' ever+thing not handled b+ the
C garbage collector. In this case there is nothing to
C clean6'.
C)
'6blic void destro+A''Fboolean 6nconditionalG D
H
H
2&2&2 Com$ile the 5ource Code
To compile the source code with the command"line tools of the 0ava &ireless Toolkit,
use the javac command. >emember that you should use the 7bootclass'ath option
to make sure the source code is compiled against the correct C.-C and MI-P
classes.
C"#midlets, javac 7bootclass'ath C"#j$me%tk#lib#mid'a'i.Ai'
Pa+ment=I:let.java
This command produces the Pa+ment=idlet.class file in the current directory. This
is a slightly simplified version of the command we used in Chapter #, which puts the
resulting class file in a temporary directory.
2&2&0 Preverif< the Class .ile
The ne6t step is to preverify the class file using the 'reveri*+ command+
C"j$me%tk#bin, 'reveri*+ 7class'ath
C"#midlets!C"#j$me%tk#lib#mid'a'i.Ai'
Pa+ment=I:let
'gain, a slightly different approach. This command creates an output subdirectory in
the current directory and writes a new file Pa+ment=I:let.class. This is the
preverified class that the 78M can run with its modified class verifier.
2&2&2 Package the A$$lication in a JA4 .ile
In order to enable dynamic downloading of MI-P applications, the application must
be packaged in a 0'> file. To create a 0'> file, use the jar command+
C"#midlets, jar cv* 'a+ment.jar Pa+ment=idlet.class
2&2&3 Create a JA/ .ile
' 0'- file is necessary if you want to run a C.-C"compliant application. 26ample E"
9 shows a sample 0'- file for the payment MI-let.
!6am$le 2+0& A sam$le JA/ file
=I:let7L" 'a+mentJJPa+ment=I:let
=I:let7Mame" Pa+ment
=I:let7/ersion" L.K
=I:let7/endor" @.A
=I:let7<ar7-.L" 'a+ment.jar
=I:let7<ar7SiAe" SOL
=nce you have the 0'- file, you can test your application using the MI-P emulator
using the em6lator command of the 0ava &ireless Toolkit, as shown here+
C"#j$me%tk#bin, em6lator 72descri'tor"C!#midlets#'a+ment.jad
If all goes well, activate the MI-let and you will see output similar to *igure E"1.
.igure 2+2& 4unning the $a<ment I/let
If your MI-P application consists of multiple MI-lets, they can all be in one 0'> file
as a MI-let suite. However, you would need to specify them in the 0'- file using the
MI-let"n entry, where n is the number of the MI-let. Consider the 0'- file in
26ample E"E, with three hypothetical MI-lets.
!6am$le 2+2& Three h<$othetical I/lets
=I:let7L" E6+J J E6+=idlet
=I:let7$" SellJ J Sell=idlet
=I:let7P" TradeJ J Trade=idlet
=I:let7Mame" Trading
=I:let7/ersion" L.K
=I:let7/endor" @.A
=I:let7<ar7-.L" trade.jar
=I:let7<ar7SiAe" $SOL
If you run this 0'- file, you would see something similar to *igure E"9.
.igure 2+0& I/let suite
' MI-P application may consist of multiple MI-lets, as shown in *igure E"9.
!imilarly, a desktop application consists of menus and options, as shown in *igure E"
E.
.igure 2+2& /eskto$ a$$lication
2&2&@ 5im$lif<ing the /evelo$ment
Dou have now seen how to compile, preverify, create 0'> and 0'- files, and run
MI-lets from the command line. This is fine if you want to understand what3s
happening behind the scenes. However, there is an alternative. 'n integrated
development environment, such as the 01M2 &ireless Toolkit, can be used to simplify
the development and deployment of MI-lets. The 01M2 &ireless Toolkit comes with
an application called 7Toolbar. The following steps show how to use the 7Toolbar to
set up a simple MI-let, develop the application, package it, and run it.
#. In Microsoft &indows, choose !tart Programs 01M2 &ireless Toolkit
7Toolbar to start the development environment. *igure E"; shows the
resulting 7Toolbar screen.
.igure 2+3& 1Tool;ar screen
1. Click on the @ew Pro?ect button to create a new pro?ect called 'a+ment, and
call the MI-let class Pa+ment=I:let, as shown in *igure E"F.
.igure 2+@& >ew $ro8ect
9. =nce you click on Create Pro?ect in *igure E"F, you will get a setting pro?ect
window, as shown in *igure E"N. This window allows you to modify the
MI-let attributes. 'll the re5uired attributes are shown in *igure E"N.
.igure 2+A& 4eBuired attri;utes
E. If you click on the =ptional tab, you will get a window with all the optional
attributes, which are shown in *igure E":.
.igure 2+9& '$tional attri;utes
;. =nce you click =7, you will get the original 7Toolbar screen with
information to indicate where to save your source and resource files.
'ssuming the &ireless Toolkit is installed in the directory C:\J2ME."/, then
you will be told to save your 0ava source files in
C:\J2ME."/\apps\pa'ment\src and your resource files (e.g., icons) in
C:\J2ME."/\apps\pa'ment\res.
@ow, use your favorite te6t editor and write Pa+ment=I:let, or simply copy the
source from 26ample E"1. Then, save it in the re5uired location and click on the Build
button to compile it. @ote that the 7Toolbar application performs all the steps of
compiling the application, preverifying the classes, compressing them into a 0'> file,
and creating a corresponding 0'- file for you. 'll you have to do is to click the >un
button to run it. Then you can test your MI-let using a default phone, Motorola3s i:;s,
or a Palm =!, as shown in *igure E"$.
.igure 2+C& 5elect a testing device "u$$er right corner of 1Tool;ar#
Choose your favorite testing device to test the MI-let. *or e6ample, *igure E"#%
shows the Pa+ment=I:let running in a default gray phone device.
.igure 2+%D& Pa<mentI/let on the default $hone
*igure E"## shows the Pa+ment=I:let running on Motorola3s i:;s device.
.igure 2+%%& Pa<mentI/let on the otorola i93s
*igure E"#1 shows the same application running on a Palm Pilot and *igure E"#9
shows the Pa+ment=I:let application running on >IM3s BlackBerry. Chapter $
discusses how to install the 0ava 'pplication Manager on a real Palm =! device and
how to convert e6isting MI-lets into P>C e6ecutable files for handheld devices
running Palm =! 9.; or higher.
.igure 2+%2& Pa<mentI/let on Palm '5
.igure 2+%0& Pa<mentI/let running on 4I:s BlackBerr<
2&2&A /e$lo<ing I/lets
's of this writing, deploying MI-lets is still an e6perimental process. However, the
0ava application manager that comes with the MI-P reference implementation now
provides some clues about how we can deploy MI-lets to various devices.
!pecifically, MI-lets can be installed in two ways+
sing a data cable or other dedicated physical connection from a local host
computer
sing a network to which the device is intermittently connected
The first method works well with P-'s, which are often used with a host computer,
with which the P-'s fre5uently synchroni4e their data. *or e6ample, the MI-P for
Palm implementation, which is discussed in Chapter $, is a good e6ample of thisA its
application manager allows MI-let suites to be installed from a host PC during the
synchroni4ation process.
The second method is more popular when installing MI-lets on cell phones and other
wireless devices. &ith these devices, the most likely delivery transport is the wireless
network itself. The process of deploying MI-let suites over a network is referred to as
over0t-e0air 1#"2 provisioning. =T' provisioning is not yet part of the MI-P
specification, but it is likely to become the dominant mechanism for distributing
MI-lets and will probably be included in the formal specification soon.
2&2&A&% /e$lo<ing 'TA
's of this writing, =T' provisioning is ?ust starting to be used with 01M2 devices
such as the Motorola i:;s,i;%6 series of cell phones. =T' provisioning allows MI-let
providers to install their MI-let suites via web servers that provide hyperte6t links.
This allows you to download MI-let suites to a cell phone via a &'P or Internet
microbrowser. Here is a brief description of how this process works.
*irst, to deploy a MI-let from a web server, you need to reconfigure your web server
by adding a new MIM2 type+
te&t)vnd.s6n.j$me.a''7descri'tor jad
How to add the MIM2 type depends on what server you are running. *or e6ample, if
you3re running 'pache Tomcat, you would add a new MIM2 type by adding a new
entry in the we&.3ml server configuration file, as follows+
8mime7ma''ing,
8e&tension,jad8)e&tension,
8mime7t+'e,te&t)vnd.s6n.j$me.a''7descri'tor8)mime7t+'e,
8)mime7ma''ing,
Dou would then use the following type of procedure to install a MI-let suite from a
web page+
#. Click on a link, which will probably re5uest a file with a 0'- e6tension, such
as the following+
8A H.E0=9=+A''.jad9,Click here to install the =I:let s6ite8)A,
1. The server will then send the M'pp.jad file to the phone with the MIM2 type
set to te&t)vnd.s6n.j$me.a''7descri'tor, as described earlier. >ecall that
the 0'- file must contain the =I:let7<ar7-.L and =I:let7<ar7SiAe
properties, which tell the device where to download the MI-let suite, as well
as the suite3s si4e in bytes.
9. The 0ava application manager on the phone will then ask if you want to install
the MI-let into the phone, assuming that the phone has the resources to run
the MI-let (i.e., that there3s enough space on the device to hold the MI-let
suite).
E. If you answer yes, the entire 0'> file will be downloaded from the server,
using the properties specified in the 0'- file.
=nce the MI-let is downloaded, it will be installed the first time you try to use it. '
downloaded MI-let stays on the device until you remove it (unlike 0ava applets).
2&2&A&2 /e$lo<ing to the otorola i3D6=i93s
Dou can also download 01M2 applications to a Motorola,@e6tel i;%6 or i:;s device
from your desktop through a data cable. This cable does not come with the phone
itself, but can be ordered online from @e6tel. The i-2@ update software can then be
downloaded from the i-2@ development site (http+,,www.motorola.com,idendev).
In addition, you can also purchase a data cable that comes with a C-">=M containing
the i-2@ update software from @e6tel from this site. =btaining the software may
involve authori4ation from your carrier, which can take between one and five days.
=nce you are granted authori4ation, however, you can install applications on up to
five individual phones. The following paragraphs describe how to use the Motorola
i-2@ update software to download a 01M2 MI-let to your phone.
'fter you have obtained the update software, start it up and choose the 01M2
-evelopers tab on the far left. This will result in a screen similar to that in *igure E"
#E. *rom here, you can choose a 0'- file to download the application into your
phone through the data cable. @ote that the 0'- file and the 0'> file must reside in
the same directory and must have the same filename (e6cluding the e6tension).
.igure 2+%2& otorola i/!> u$date software
*or the most part, downloading an application to the phone is easy. However, the
Motorola i:;s and i;%6 phones will perform a number of checks to ensure the
integrity of the application while installing it. Dou should observe the following rules
to ensure that the phone will install the application.
The 0'- file downloaded to the i:;s or i;%6 must contain at least the following
entries, which are case"sensitive+
=I:let7Mame"
=I:let7/ersion"
=I:let7/endor"
=I:let7<ar7SiAe"
=I:let7<ar7-.L"
It can also contain the following optional entries+
=I:let7:escri'tion"
=I:let7In*o7-.L"
=I:let7:ata7SiAe"
In addition, the 0'- file can contain any other MI-let"specific information that does
not begin with the letters IMI-let"I.
>emember from Chapter 9 that the 0'> file must contain a manifest with at least the
following information, which must be identical to the data in the 0'- file+
=I:let7Mame"
=I:let7/ersion"
=I:let7/endor"
If you do not include this information in the manifest, the phone will respond with a
I-escriptor 2rrorI when it is attempting to install the application. If this happens,
simply press the Menu button while the MI-let is selected and remove it from the
system.
Here are some other things to note when downloading to the Motorola i:;s or i;%6+
The 0'- file is case"sensitive.
The ma6imum file length for both the 0'- and the 0'> file is #F characters,
which includes the four characters for the e6tension (e.g., .JD or .J4).
The byte si4e of the 0'> file must be accurately stated in the 0'- file.
2ach of the attributes in the 0'- and 0'> file manifests must have a value
associated with it. Dou cannot leave an attribute value blank.
Classes which are instantiated using the Class.*orMameF G method must be
identified in the 0'- file using the attribute+ i:EM7Install7Class7n", where
n is a positive integer. The class name is listed afterward without the .class
e6tension.
26ample E"; shows the manifest information that we would be using if we wanted to
download the HelloMidlet application from Chapter # to the Motorola i:;s.
>emember that the manifest must contain the three specified attributes (=I:let7Mame,
=I:let7/ersion, and =I:let7/endor) and that they must be identical to the values
in the 0'- file. If they differ, the phone will not install the MI-let. &e have also
included the MI-let class identification information and the profile and configuration
version numbers, which we recommend that you include in your MI-let manifests as
well.
!6am$le 2+3& anifest&mf
=I:let7Mame" Hello=idlet
=I:let7/endor" @.A
=I:let7/ersion" L.K.K
=I:let7L" Hello=idletJJHello=idlet
=icroEdition7Pro*ile" =I:P7L.K
=icroEdition7Con*ig6ration" CL:C7L.K
't this point, let3s create a compressed 0'> file of the classes that make up the
MI-let. &ith the manifest and the preverified class in the same directory, enter the
following command+
,jar cv*m Hello=idlet.jar mani*est.m* Hello=idlet.class
=nce that is completed, you3ll need to create the 0'- file. 26ample E"F shows the
0'- file for our HelloMidlet application. @ote that we had to change the value of the
=I:let7<ar7SiAe attribute to match the si4e, in bytes, of the 0'> file that we ?ust
created. In this case, it turned out to be $;E bytes with the additional manifest
information.
!6am$le 2+@& *elloidlet&8ad
=I:let7L" Hello=idletJJHello=idlet
=I:let7<ar7SiAe" SXV
=I:let7<ar7-.L" htt'"))%%%.oreill+.com)
=I:let7Mame" Hello=idlet
=I:let7/endor" @.A
=I:let7/ersion" L.K.K
=I:let7:escri'tion" A sam'le a''lication
@ow we3re ready to go. 'gain, be sure that the 0'- file and the 0'> file have the
same name and reside in the same directory. Then use the i-2@ software tools to
download the application to your phone. It should only take a few seconds once
you3ve chosen the target 0'- file. 'fter the download has completed, start the 0ava
'pplication Manager on the phone (0ava 'pps under the Main Menu) and select the
HelloMidlet application. Press the soft button to install it. Dou are now installing your
first 0ava MI-let on a real device. If everything goes okay, you can run your program
after it completes the installation and verification steps.
Cha$ter 3& I/P ?UI Programming
ser interface re5uirements for handheld devices are different from those for desktop
computers. *or e6ample, the display si4e of handheld devices is smaller, and input
devices do not always include pointing tools such as a mouse or pen input. *or these
reasons, you cannot follow the same user"interface programming guidelines for
applications running on handheld devices that you can on desktop computers.
The C.-C itself does not define any <I functionality. Instead, the official <I
classes for the 01M2 are included in profiles such as the MI-P and are defined by the
0ava Community Process (0CP). Dou3ll note that the <I classes included in the MI-P
are not based on the 'bstract &indow Toolkit ('&T). That seems like a ma?or issue,
which brings us to the following 5uestion.
3&% (h< >ot 4euse the A(T)
'fter a great deal of consideration, the MI-P 26pert <roup decided not to subset the
e6isting '&T and Pro?ect !wing classes for the following reasons+
'&T is designed for desktop computers and optimi4ed for these machines.
'&T assumes certain user interaction models. The component set of the '&T
is designed to work with a pointing device such as a mouseA however, many
handheld devices, such as cell phones, have only a keypad for user input.
'&T has a rich feature set, and includes support for functionality that is not
found or is impractical to implement on handheld devices. *or e6ample, the
'&T has e6tensive support for window management, such as resi4ing
overlapping windows. However, the limited display si4e of handheld devices
makes resi4ing a window impractical. Therefore, the window and layout
managers within the '&T are not re5uired for handheld devices.
&hen a user interacts with an '&T"based application, event ob?ects are
created dynamically. These ob?ects e6ist only until each associated event is
processed by the application or system, at which time the ob?ect becomes
eligible for garbage collection. The limited CP and memory of handheld
devices, however, cannot handle the burden.
3&2 The I/P ?UI APIs
Because of the issues outlined earlier, the MI-P contains its own abbreviated <I,
which is much different from '&T. The MI-P <I consists of both high"level and
low"level 'PIs, each with their own set of events. This chapter discusses and shows
e6amples of using ob?ects from both the high"level and low"level 'PIs. Handling
events from 'PIs, however, is deferred to the ne6t chapter.
The high"level 'PI is designed for applications where portability between mobile
information devices is important. To achieve portability, the 'PI employs a high"level
abstraction and gives you little control over its look and feel. *or e6ample, you cannot
define the visual appearance (shape, color, or font) of the high"level components.
Most interactions with the components are encapsulated by the implementationA the
application will not be aware of them. Conse5uently, the underlying implementation
does the necessary adaptation to the device3s hardware and native user interface style.
Classes that implement the high"level 'PI all inherit the
java&.microedition.lcd6i.Screen class.
The low"level 'PI provides little abstraction. It is designed for applications that need
precise placement and control of graphic elements, as well as access to low"level
input events. This 'PI gives the application full control over what is being drawn on
the display. The java&.microedition.lcd6i.Canvas and
java&.microedition.lcd6i.Wra'hics classes implement the low"level 'PI.
However, we should point out that MI-lets that access the low"level 'PI are not
guaranteed to be portable, because this 'PI provides mechanisms to access details that
are specific to a particular device.
3&2&% The I/P ?UI odel
Here3s how the MI-P <I model works, in a nutshell. In order to show something on
a MI-P device, you3ll need to obtain the device3s displa'+ which is represented by the
java&.microedition.lcd6i.:is'la+ class. The :is'la+ class is the one and only
display manager that is instantiated for each active MI-let and provides methods to
retrieve information about the device3s display capabilities.
=btaining the device3s display is easy. However, this ob?ect by itself isn3t very
interesting. Instead, the more interesting abstraction is the screen, which encapsulates
and organi4es graphics ob?ects and coordinates user input through the device. !creens
are represented by the java&.microedition.lcd6i.Screen ob?ect and are shown by
the :is'la+ ob?ect by calling its setC6rrentF G method. There can be several
screens in an application, but only one screen at a time can be visible (or current) in a
display, and the user can traverse only through the items on that screen. *igure ;"#
shows the one"to"many relationship between the display and its screens.
.igure 3+%& 4elationshi$ ;etween dis$la< and screens
There are three types of screens in the MI-P <I+
!creens that entirely encapsulate a comple6 user interface component, such as
a List or Te&tEo& component (the List component is shown in *igure ;":
and the Te&tEo& component is shown in *igure ;";). The structure of these
screens is predefined, and the application cannot add other components to
these screens.
<eneric screens that use a 0orm component. The application can add te6t,
images, and a simple set of related I components to the form, which acts as a
container.
!creens used within the conte6t of the low"level 'PI, such as a subclass of the
Canvas or Wra'hics class.
3&2&2 The lcdui Package
'll MI-P <I classes are contained in the java&.microedition.lcd6i package.
This package contains three interfaces and twenty"one classes, as shown in Table ;"#
and Table ;"1.
Ta;le 3+%& lcdui interfaces
Interface Description
Choice
-efines an 'PI for a user interface component that implements a selection
from a predefined number of choices
CommandListener
sed by applications that need to receive high"level events from
implementations
ItemStateListener
sed by applications that need to receive events that indicate changes in the
internal state of the interactive items
Ta;le 3+2& lcdui classes
Class Description
Alert
' screen that shows data to the user and waits for a certain period of time before
proceeding to the ne6t screen.
AlertT+'e ' utility class that indicates the nature of the alert.
Canvas
The base class for writing applications that need to handle low"level events and to issue
graphics calls for drawing to the display.
ChoiceWro6' ' group of selectable elements intended to be placed within a 0orm.
Command ' construct that encapsulates the semantic information of an action.
:ate0ield
'n editable component for presenting calendar data and time information that may be
placed into a 0orm.
:is'la+ ' utility that represents the manager of the display and input devices of the system.
:is'la+able 'n ob?ect that has the capability of being placed on the display.
0ont ' utility that represents font and font metrics.
0orm
' screen that contains an arbitrary mi6ture of items (images, te6t, te6t fields, or choice
groups, for instance).
Wa6ge ' utility that implements a bar graph display of a value intended for use in a form.
Wra'hics ' utility that provides a simple two"dimensional geometric rendering capability.
Image ' utility that holds graphical image data.
ImageItem ' utility that provides layout control when Image ob?ects are added to a form or alert.
Item ' superclass for all components that can be added to a 0orm or Alert.
List ' screen containing a list of choices.
Screen The superclass of all high"level user interface classes.
StringItem 'n item that can contain a String.
Te&tEo& ' screen that allows the user to enter and edit te6t.
Te&t0ield 'n editable te6t component that can be placed into a 0orm.
Ticker
' ticker"type piece of te6t that runs continuously across the display. It can be attached
to all screen types e6cept Canvas.
The class diagram in *igure ;"1 shows the ma?or classes and the relationships
between them.
.igure 3+2& Class diagram of the ma8or classes in the lcdui $ackage
3&2 Creating ,ow+,evel ?UI Com$onents
In the high"level 'PI, you have no control of what is displayed on the screen and very
little freedom to IplayI with the components programmatically. The implementation is
responsible for selecting the best approach for the device. !ome applications,
however, such as games, may need more control over what is drawn on the screen.
The MI-P java&.microedition.lcd6i package also provides a low"level 'PI for
handling such cases.
In order to directly draw lines, te6t, and shapes on the screen, you must use the
Canvas class. The Canvas class provides a blank screen on which a MI-let can draw.
*or e6ample, let3s draw the string IHello&orldI on the screen. There3s a simple way to
do this+ subclass the Canvas class, which is an abstract class that e6tends
:is'la+able, and override the 'aintF G method. The resulting class, =+Canvas, is
shown in 26ample ;"#.
The implementation of the 'aintF G method uses the drawing capabilities of the
java&.microedition.lcd6i.Wra'hics class. In the 'aintF G method, the drawing
color is set to red, then a rectangle is drawn in the current color. The methods
getWidthF G and getHeightF G return the width and height of the Canvas,
respectively. The ne6t call to setColorF G sets the drawing color to whiteA then the
string IHello &orldCI is drawn in the top left corner of the screen.
!6am$le 3+%& 5u;classing Canvas
im'ort java&.microedition.lcd6i.C!
'6blic class =+Canvas e&tends Canvas D
'6blic void 'aintFWra'hics gG D
g.setColorF$XXJ KJ KG!
g.*ill.ectFKJ KJ getWidthFGJ getHeightF GG!
g.setColorF$XXJ $XXJ $XXG!
g.dra%StringFIHello WorldTIJ KJ KJ g.T@P 5 g.LE0TG!
H
H
@ow, in order to view the =+Canvas, it must be instantiated and displayed. !ince
Canvas is a subclass of :is'la+able, it can be displayed the same way any other
screen using the setC6rrentF G method. 26ample ;"1 shows the resulting MI-let.
!6am$le 3+2& Instantiating and dis$la<ing <Canvas
im'ort java&.microedition.midlet.C!
im'ort java&.microedition.lcd6i.C!
'6blic class =+=idlet e&tends =I:let D
'6blic =+=idletF G D )) constr6ctor
H
'6blic void startA''F G D
Canvas canvas = ne% =+CanvasF G!
:is'la+ dis'la+ = :is'la+.get:is'la+FthisG!
dis'la+.setC6rrentFcanvasG!
H
'6blic void 'a6seA''F G D
H
'6blic void destro+A''Fboolean 6nconditionalG D
H
H
If you run this in the &ireless Toolkit emulator, you will see something similar to
*igure ;"11. @ote from 26ample ;"# that the colors are set to red and white, but since
a grayscale display is being used, the colors are mapped to appropriate shades of black
and white. Try switching displays to see which devices give a better feel for the
colors.
.igure 3+22& /rawing 7*ello (orldE7 on a Canvas
3&2&% /rawing ?ra$hics
The (%,%) coordinate represents the upper left corner of the display. The numeric value
of the 6"coordinate increases from left to right, and the numeric value of the y"
coordinate increases from top to bottom. 'pplications should always check the
dimensions of the drawing area by using the following methods of the Canvas class+
'6blic int getHeightF G!
'6blic int getWidthF G!
These two methods return the height and width of the displayable area in pi6els,
respectively.
The drawing model used is called pi3el replacement. It works by replacing the
destination pi6el value with the current pi6el value specified in the graphics ob?ects
being used for rendering. ' 1E"bit color model is provided with : bits each for >ed,
<reen, and Blue (><B). However, since not all devices support color, colors
re5uested by applications will be mapped into colors available on the devices. ' well"
written application, however, may check if a device supports color. This can be done
using the isColorFG and n6mColorsF G methods of the :is'la+ class, which we
covered earlier in the chapter.
The Wra'hics class provides the setColorFG and getColorF G methods for setting
and getting the color. nlike the '&T,!wing, however, there is no
setEackgro6ndF G and set0oregro6ndFG, so you need to e6plicitly call *ill.ectF
GJ as shown in 26ample ;"#. Most of the other methods in the Wra'hics class are
self"e6planatory and similar to methods in the '&T version of this class. However,
let3s go over a few of them here to see how they work in the 01M2 environment.
3&2&2 /ou;le Buffering
The double buffering techni5ue is often used to perform smooth effect animation. In
this techni5ue, you do not draw to the display, but instead to a copy of the display (an
off"screen buffer) that is maintained in memory. &hen you are done drawing to the
buffer, you then copy the contents of the buffer to the display. The rationale here is
that copying the contents of memory to the display is faster than drawing by using
primitives.
To implement double buffering, first create a mutable image with the si4e of the
screen+
int %idth = getWidthF G!
int height = getHeightF G!
Image b6**er = Image.createImageF%idthJ heightG!
@e6t, obtain a graphics conte6t for the buffer+
Wra'hics gc = b6**er.getWra'hicsF G!
@ow, you can draw to the buffer+
)) animate
)) ..
gc.dra%.ectF$KJ $KJ $XJ PKG!
&hen you need to copy the buffer to the screen, you can override the 'aintF G
method to draw the buffer to the device display+
'6blic void 'aintFWra'hics gG D
g.dra%ImageFb6**erJ KJ KJ KG!
H
@ote that some MI-P implementations are already double"
buffered, and therefore this work may not be necessary. To check
if the graphics are double"buffered by an implementation, use the
Canvas. is:o6bleE6**eredF G method.
3&2&0 Threading Issues
The MI-P <I 'PIs are thread"safe. In other words, the methods can be called at any
time from any thread. The only e6ception is the service.e'aintsF G method of the
Canvas class, which immediately calls the 'aintF G method to force immediate
repainting of the display. This means that if 'aintF G tries to synchroni4e on any
ob?ect that is already locked by the application when service.e'aintsF G is called,
the application will deadlock. To avoid deadlocks, do not lock an ob?ect that will be
used by the 'aintFG method if service.e'aintsF G is involved.
In addition, you can use the callSeriall+F G method of the :is'la+ class to
e6ecute code after all pending repaints are served, as shown in the following segment
of code+
class TestCanvas e&tends Canvas im'lements .6nnable D
void doSomethingF G D
)) code *ragment L
callSeriall+FthisG!
H
'6blic void r6nF G D
)) code *ragment $
H
H
Here, the ob?ect3s r6nF G method will be called after the initial call.
3&2&2 .onts
*onts cannot be created by applications. Instead, an application re5uests a font based
on attributes (i.e., si4e, face, style) and the underlying implementation will attempt to
return a font that closely resembles the re5uested font. The 0ont class represents
various fonts and metrics. There are three font attributes defined in the 0ont class, and
each may have different values, as follows+
3ace
=@M@SPACE, P.@[email protected]@MAL, S1STE=
/ize
S=ALL, =E:I-=, LA.WE
/tyle
E@L:, ITALIC, PLAIM, -M:E.LIME:
*or e6ample, to specify a medium si4e font, use 0ont.SIYE?=E:I-=, and to specify
an italic style, use 0ont.ST1LE?ITALIC, and so on. 8alues for the style attributes may
be combined using the => (P) operatorA values for the other attributes may not be
combined. *or e6ample, the value of this style attribute specifies a plain, underlined
font+
ST1LE?PLAIM 5 ST1LE?-M:E.LIME:
However, the following is illegal+
SIYE?S=ALL 5 SIYE?=E:I-=
This is also illegal+
0ACE?S1STE= 5 0ACE?=@M@SPACE
2ach font in the system is actually implemented individually, so in order to obtain an
ob?ect representing a font, use the get0ontF G method. This method takes three
arguments for the font face, si4e, and style, respectively. *or e6ample, the following
snippet of code obtains a 0ont ob?ect with the specified face, style, and si4e attributes+
0ont *ont = 0ont.get0ontF0ACE?S1STE=J ST1LE?PLAIMJ SIYE?=E:I-=G!
If a matching font does not e6ist, the implementation will attempt to provide the
closest match, which is always a valid 0ont ob?ect.
=nce a font is obtained, you can use methods from the 0ont class to retrieve
information about that font. *or e6ample, you can use the methods get0aceFG,
getSiAeF G, and getSt+leF G to retrieve information about the face, si4e, and style
of the font, respectively.
.et3s look at an e6ample. The code in 26ample ;"9 subclasses the Canvas class. In
this e6ample, the drawing color is set to white, a rectangle is drawn in the current
color, then the drawing color is set to black. The rest of the code draws the system
fonts on the device screen, as shown in *igure ;"19.
.igure 3+20& /rawing s<stem fonts on the device screen
!6am$le 3+0& Using fonts
im'ort java&.microedition.lcd6i.C!
'6blic class 0ontCanvas e&tends Canvas D
'6blic void 'aintFWra'hics gG D
g.setColorFK&******G!
g.*ill.ectFKJ KJ getWidthFGJ getHeightF GG!
g.setColorFK&KKKKKKG!
g.set0ontF0ont.get0ontF0ont.0ACE?S1STE=J 0ont.ST1LE?PLAIMJ
0ont.SIYE?LA.WEGG!
g.dra%StringFIS+stem 0ontIJ KJ KJ g.LE0T 5 g.T@PG!
g.set0ontF0ont.get0ontF0ont.0ACE?S1STE=J 0ont.ST1LE?PLAIMJ
0ont.SIYE?=E:I-=GG!
g.dra%StringFI=edi6m SiAeIJ KJ LXJ g.LE0T 5 g.T@PG!
g.set0ontF0ont.get0ontF0ont.0ACE?S1STE=J 0ont.ST1LE?E@L:J
0ont.SIYE?=E:I-=GG!
g.dra%StringFIEold St+leIJ KJ PKJ g.LE0T 5 g.T@PG!
g.set0ontF0ont.get0ontF0ont.0ACE?S1STE=J 0ont.ST1LE?ITALICJ
0ont.SIYE?=E:I-=GG!
g.dra%StringFIItalic St+leIJ KJ VXJ g.LE0T 5 g.T@PG!
g.set0ontF0ont.get0ontF0ont.0ACE?S1STE=J
0ont.ST1LE?-M:E.LIME:J 0ont.SIYE?=E:I-=GG!
g.dra%StringFI-nderlined St+leIJ KJ OKJ g.LE0T 5 g.T@PG!
H
H
@ow, we instantiate the 0ontCanvas class and display it, as shown in 26ample ;"E.
!6am$le 3+2& Instantiating and dis$la<ing the .ontCanvas class
im'ort java&.microedition.midlet.C!
im'ort java&.microedition.lcd6i.C!
'6blic class 0ont=idlet e&tends =I:let D
'6blic 0ont=idletF G D )) constr6ctor
H
'6blic void startA''F G D
Canvas canvas = ne% 0ontCanvasF G!
:is'la+ dis'la+ = :is'la+.get:is'la+FthisG!
dis'la+.setC6rrentFcanvasG!
H
'6blic void 'a6seA''F G D
H
'6blic void destro+A''Fboolean 6nconditionalG D
H
H
3&2&3 ?uidelines for ?UI Programming for I/P /evices
's we close this chapter, keep in mind some important guidelines when designing
MI-lets with graphical 'PI functionality+
Be sure to make the MI-let user interface simple and easy to use. >emember
that your applications will likely be used by novice users who probably haven3t
used a 01M2"enabled phone and may not be familiar with its interface.
se the high"level 'PI as much as possible, so that your MI-lets are portable
across different handheld devices.
If your application re5uires you to use the low"level 'PI, keep to the platform"
independent part of the low"level 'PI. This means that your MI-lets should
not assume any other keys than those defined in the Canvas class. &e3ll
discuss this in more detail in the ne6t chapter.
MI-lets should never assume any specific screen si4eA instead, they should
5uery the si4e of the display and ad?ust accordingly.
2ntering alphanumeric data through a handheld device can be tedious. If
possible, provide a list of choices from which the user can select.
Cha$ter @& I/P !vents
In '&T and !wing, events are generated when a user interacts with an application.
*or e6ample, if the user selects !ave from the *ile menu, the application is notified of
this action and responds to the generated event. The same model holds true for the
MI-P. However, as mentioned in the previous chapter, there are two MI-P user
interface 'PIs+ high"level and low"level. Therefore, there are two kinds of events+
high"level (such as selecting an item from a list) and low"level (such as pressing a key
on the device).
This chapter discusses event handling in the MI-P and shows, through e6amples, how
to handle high"level and low"level MI-P events generated by the components of the
previous chapter. &e start with an e6planation of a simple application of events+
navigating between screens.
@&% 5creen >avigation
' MI-let developer needs to provide ways for the user to navigate through the
different screens that make up the MI-let. Because we can only show one screen at a
time, however, we need to tie a mechanism to each screen that indicates to the MI-let
that the user has completed working with the current :is'la+able screen. &e can do
this by using the Command class, which is part of the java&.microedition.lcd6i
package. .et3s take a closer look at the Command class now.
@&%&% Commands
0ust like a design pattern with the same name, the Command class encapsulates the
semantic information of an action. @ote that it only contains information about a
command, not the actual functionality that is e6ecuted when a command is activated.
Here is the constructor of the Command class+
'6blic CommandFString labelJ int commandT+'eJ int 'riorit+G!
This is the only constructor for the Command class. Hence, creating a Command ob?ect is
e6tremely simple+
Command in*oCommand = ne% CommandFIIn*oIJ Command.SC.EEMJ $G!
The Command class constructor takes three parameters, and therefore contains the
following three lightweight pieces of information+ la&el, command t'pe, and priorit'.
The la&el is a string used for the visual representation of the command. *or
e6ample, the label may appear ne6t to a soft button on the device or as an
element in a menu.
The command t'pe element specifies the command3s intent. The predefined
types are actually static integers in the Command class+ EAC>, CAMCEL, E2IT,
HELP, ITE=, @>, SC.EEM, and ST@P.
The priorit' value describes the importance of this command relative to other
commands on the screen. ' priority value of L indicates the most important
commandA higher priority values indicate commands of lesser importance.
2ach component that e6tends :is'la+able (such as Screen or Canvas) has the
following methods available to it+
'6blic void addCommandFCommand cG!
'6blic void removeCommandFCommand cG!
These methods allow you to bind a command to a :is'la+able ob?ect. (That3s pretty
much all of themA recall *igure ;"1.) &hen the MI-let e6ecutes, the device assigns a
visual representation of the command (typically a soft button or menu item) and
chooses its placement based on the command type, placing similar commands based
on their priority values. Consider the following e6ample, where a Te&tEo& ob?ect is
created along with three commands. The commands are added to the Te&tEo& ob?ect,
and the current screen is then set to be the Te&tEo& ob?ect+
:is'la+ dis'la+ = :is'la+.get:is'la+FthisG!
Te&tEo& tb = ne% Te&tEo&FI=I:PIJ IWelcome to =I:PIJ VKJ
Te&t0ield.AM1G!
Command e&itCommand = ne% CommandFIE&itIJ Command.SC.EEMJ LG!
Command in*oCommand = ne% CommandFIIn*oIJ Command.SC.EEMJ $G!
Command b6+Command = ne% CommandFIE6+IJ Command.SC.EEMJ $G!
tb.addCommandFe&itCommandG!
tb.addCommentFin*oCommandG!
tb.addCommandFb6+CommandG!
dis'la+.setC6rrentFtbG!
.ook carefully at what this code displays in *igure F"#. Here, the application manager
maps the E&it command to the screen using the soft button on the lower left, but then
creates a =en6 command to hold the In*o and E6+ commands. Clicking the right soft
button under =en6 takes you to a screen with a two"button menu+ In*o and E6+. This
is because the In*o and E6+ commands are of lesser priority than the E&it command.
.igure @+%& !6it, Info, and Bu< commands
The general strategy that the application manager will follow is to assign as many
commands with a high priority to as many soft buttons as are available. If there are
not enough soft buttons, the implementation will likely group the remaining in a
secondary menu that can be selected using a Menu soft button, as shown above.
However, the e6act rules for how each device handles this type of situation are
implementation"dependent.
The Command class provides only the following three methods for retrieving the type,
label, and priority values+
'6blic int getCommandT+'eF G!
'6blic String getLabelF G!
'6blic int getPriorit+F G!
@ote that there is no way to reset these ob?ect properties once they are set in the
constructor.
The MI-P I 'PI lets you set up a screen with no commands,
but this is generally not useful because the user cannot move to
another screen. It is important to note that the Command class can
be used with both the high"level and the low"level 'PIs. Hence,
commands can be placed on Screen ob?ects as well as Canvas
ob?ects.
's we mentioned before, the command itself only contains information about a
command, not the actual action that happens when a command is activated. The action
is defined in a CommandListener, which is a call&ack ob?ect that is associated with
the screen.
@&%&2 The Command,istener Interface
&hen a user interacts with a MI-let, such as by selecting an item in a list or
interacting with a Wa6ge, events are generated. Dour application is then notified to
handle these events through the use of callbacks. Callbacks are actually invocations of
programmer"defined methods performed by the underlying application in response to
actions taken by a user at runtime.
Callbacks are used in many programming environments, especially in <I
construction kits. *or e6ample, the '&T 'PI makes heavy use of callbacks. &hen a
user interacts with a component, for e6ample, the interface code calls back the
computational code to respond to the user3s action. In some languages such as C,CQQ,
callbacks are implemented by passing a function pointer to another function. The
receiving function uses the function pointer to invoke another function when a
particular event occurs. Because the 0ava programming language does not have
pointers, however, callbacks are implemented with interfaces. 'n interface defines a
set of methods, but unlike a class, it does not implement their behavior. Instead, you
provide interface method implementations for the class that implements the interface.
There are four kinds of user interface callbacks in the MI-P+
'bstract commands that are part of the high"level 'PI
.ow"level events that represent single"key presses and releases
Calls to the 'aintF G method of a Canvas class
Calls to a .6nnable ob?ect3s r6nFG method, re5uested by a call to the
callSeriall+F G method of the :is'la+ class
@ote that all user"interface callbacks are seriali4ed by the application manager. In
other words, they all occur one after another in a single thread of e6ecution, and never
at the same time. ser interface callbacks are called as soon as the previous callback
returns. In addition, the MI-P user interface 'PI is thread"safe and includes a
mechanism for event synchroni4ation. 'n application can use the callSeriall+F G
method of the :is'la+ class to e6ecute an operation serially with events.
Both Screen and Canvas ob?ects can have listeners for commands that are sent when
user interaction occurs. *or an ob?ect to be a listener, it must implement the
CommandListener interface. Dou can register a listener by using the
setCommandListenerF G method, which is part of the :is'la+able class and is
inherited by both Screen and Canvas. @ote that there can only be one
CommandListener ob?ect for each :is'la+able that the MI-let has created.
'6blic void setCommandListenerFCommandListener cG!
The CommandListener interface is for MI-lets that need to receive high"level events
from the implementation. This interface has one method that a listener must
implement, which is the commandActionF G method.
'6blic void commandActionFCommand cJ :is'la+able dG!
The first parameter is a command ob?ect that identifies the command (if any) that has
been added to :is'la+able with the addCommandF G method and invoked. The
second parameter is the :is'la+able ob?ect where the event occurred.
@&%&2&% *andling sim$le events
.et3s look at a simple e6ample. In 26ample F"#, a List component is created and
filled with the strings IItemLI, IItem$I, IItemPI, and IItemVI. The 're'areF G
method is called whenever an item is selected. The testItemZF G methods (where R
is a number between # and E) each call the 're'areF G method and set the name of
the menu.
!6am$le @+%& *andling high+level events
im'ort java&.microedition.lcd6i.C!
im'ort java&.microedition.midlet.C!
'6blic class EventE&L e&tends =I:let im'lements CommandListener D
)) dis'la+ manager
:is'la+ dis'la+ = n6ll!
)) a men6 %ith items
List men6 = n6ll! )) main men6
)) te&tbo&
Te&tEo& in'6t = n6ll!
)) command
static *inal Command backCommand = ne% CommandFIEackIJ
Command.EAC>J KG!
static *inal Command main=en6Command = ne% CommandFI=ainIJ
Command.SC.EEMJ LG!
static *inal Command e&itCommand = ne% CommandFIE&itIJ
Command.ST@PJ $G!
String c6rrent=en6 = n6ll!
)) constr6ctor
'6blic EventE&LF G D
H
)CC
C Start the =I:let b+ creating a list o* items and associating
C the e&it command %ith it.
C)
'6blic void startA''F G thro%s =I:letStateChangeE&ce'tion D
dis'la+ = :is'la+.get:is'la+FthisG!
men6 = ne% ListFI=en6 ItemsIJ Choice.I=PLICITG!
men6.a''endFIItemLIJ n6llG!
men6.a''endFIItem$IJ n6llG!
men6.a''endFIItemPIJ n6llG!
men6.a''endFIItemVIJ n6llG!
men6.addCommandFe&itCommandG!
men6.setCommandListenerFthisG!
main=en6F G!
H
'6blic void 'a6seA''F G D
dis'la+ = n6ll!
men6 = n6ll!
in'6t = n6ll!
H
'6blic void destro+A''Fboolean 6nconditionalG D
noti*+:estro+edF G!
H
)) main men6
void main=en6F G D
dis'la+.setC6rrentFmen6G!
c6rrent=en6 = I=ainI!
H
)CC
C a generic method that %ill be called %hen an+ o*
C the items on the list are selected.
C)
'6blic void 're'areF G D
in'6t = ne% Te&tEo&FIEnter some te&t" IJ IIJ XJ
Te&t0ield.AM1G!
in'6t.addCommandFbackCommandG!
in'6t.setCommandListenerFthisG!
in'6t.setStringFIIG!
dis'la+.setC6rrentFin'6tG!
H
)CC
C Test itemL.
C)
'6blic void testItemLF G D
're'areF G!
c6rrent=en6 = IitemLI!
H
)CC
C Test item$.
C)
'6blic void testItem$F G D
're'areF G!
c6rrent=en6 = Iitem$I!
H
)CC
C Test itemP.
C)
'6blic void testItemPF G D
're'areF G!
c6rrent=en6 = IitemPI!
H
)CC
C Test itemV.
C)
'6blic void testItemVF G D
're'areF G!
c6rrent=en6 = IitemVI!
H
)CC
C Handle events.
C)
'6blic void commandActionFCommand cJ :is'la+able dG D
String label = c.getLabelF G!
i* Flabel.eB6alsFIE&itIGG D
destro+A''Ftr6eG!
H else i* Flabel.eB6alsFIEackIGG D
i*Fc6rrent=en6.eB6alsFIitemLIG 55
c6rrent=en6.eB6alsFIitem$IG 55
c6rrent=en6.eB6alsFIitemPIG 55
c6rrent=en6.eB6alsFIitemVIGG D
)) go back to men6
main=en6F G!
H
H else D
List do%n = FListGdis'la+.getC6rrentF G!
s%itchFdo%n.getSelectedInde&F GG D
case K" testItemLF G!break!
case L" testItem$F G!break!
case $" testItemPF G!break!
case P" testItemVF G!break!
H
H
H
H
The EventE&L class implements the CommandListener interface by providing an
implementation for the commandActionF G method. In this implementation, the label
of the command passed into the callback method is checked. If the label e5uals E&it,
the MI-let is destroyed. If the label e5uals Eack and the current menu is IItemLI,
IItem$I, IItemPI, or IItemVI, the program goes back to the main menu. =therwise,
the selected item is found and the appropriate method is called. @ote that when you
have an item list, you can use the :is'la+.getC6rrentF G method to return the list,
and then switch between the items to determine which item is selected. If you run the
EventE&L MI-let, you should see output similar to *igure F"1.
.igure @+2& *andling high+level events
@&%&2&2 Creating ?UI com$onents and handling events
@ow let3s look at another e6ample that demonstrates how to create various <I
components and to handle their events. The MI-let in this e6ample allows you to test
lists, forms, choices, gauges, te6t fields, and te6t bo6es. The EventE&$ MI-let shown
in 26ample F"1 makes use of the following classes, listed in alphabetical order, from
the java&.microedition.lcd6i package+ Alert, AlertT+'e, Command, :ate0ield,
:is'la+, :is'la+able, 0orm, Wa6ge, List, Te&tEo&, Te&t0ield, and Ticker, as
well as the CommandListener interface.
!6am$le @+2& Constructing and testing ?UI com$onents
im'ort java&.microedition.lcd6i.C!
im'ort java&.microedition.midlet.C!
'6blic class EventE&$ e&tends =I:let im'lements CommandListener D
)) dis'la+ manager
:is'la+ dis'la+ = n6ll!
)) a men6 %ith items
List men6 = n6ll! )) main men6
)) list o* choices
List choose = n6ll!
)) te&tbo&
Te&tEo& in'6t = n6ll!
)) ticker
Ticker ticker = ne% TickerFITest W-I Com'onentsIG!
)) alerts
*inal Alert so6ndAlert = ne% AlertFIso6nd AlertIG!
)) date
:ate0ield date = ne% :ate0ieldFIToda+9s date" IJ
:ate0ield.:ATEG!
)) *orm
0orm *orm = ne% 0ormFI0orm *or St6**IG!
)) ga6ge
Wa6ge ga6ge = ne% Wa6geFIWa6ge LabelIJ tr6eJ LKJ KG!
)) te&t *ield
Te&t0ield te&t*ield = ne% Te&t0ieldFITe&t0ield LabelIJ IabcIJ
XKJ KG!
)) command
static *inal Command backCommand = ne% CommandFIEackIJ
Command.EAC>J KG!
static *inal Command main=en6Command = ne% CommandFI=ainIJ
Command.SC.EEMJ LG!
static *inal Command e&itCommand = ne% CommandFIE&itIJ
Command.ST@PJ $G!
String c6rrent=en6 = n6ll!
)) constr6ctor.
'6blic EventE&$F G D
H
)CC
C Start the =I:let b+ creating a list o* items and associating
C the e&it command %ith it.
C)
'6blic void startA''F G thro%s =I:letStateChangeE&ce'tion D
dis'la+ = :is'la+.get:is'la+FthisG!
men6 = ne% ListFITest Com'onentsIJ Choice.I=PLICITG!
men6.a''endFITest Te&tEo&IJ n6llG!
men6.a''endFITest ListIJ n6llG!
men6.a''endFITest AlertIJ n6llG!
men6.a''endFITest :ateIJ n6llG!
men6.a''endFITest 0ormIJ n6llG!
men6.addCommandFe&itCommandG!
men6.setCommandListenerFthisG!
men6.setTickerFtickerG!
main=en6F G!
H
'6blic void 'a6seA''F G D
dis'la+ = n6ll!
choose = n6ll!
men6 = n6ll!
ticker = n6ll!
*orm = n6ll!
in'6t = n6ll!
ga6ge = n6ll!
te&t*ield = n6ll!
H
'6blic void destro+A''Fboolean 6nconditionalG D
noti*+:estro+edF G!
H
)) main men6
void main=en6F G D
dis'la+.setC6rrentFmen6G!
c6rrent=en6 = I=ainI!
H
)CC
C Test the Te&tEo& com'onent.
C)
'6blic void testTe&tEo&F G D
in'6t = ne% Te&tEo&FIEnter Some Te&t"IJ IIJ XJ
Te&t0ield.AM1G!
in'6t.setTickerFne% TickerFItestTe&tEo&IGG!
in'6t.addCommandFbackCommandG!
in'6t.setCommandListenerFthisG!
in'6t.setStringFIIG!
dis'la+.setC6rrentFin'6tG!
c6rrent=en6 = Iin'6tI!
H
)CC
C Test the List com'onent.
C)
'6blic void testListF G D
choose = ne% ListFIChoose ItemsIJ Choice.=-LTIPLEG!
choose.setTickerFne% TickerFIlistTestIGG!
choose.addCommandFbackCommandG!
choose.setCommandListenerFthisG!
choose.a''endFIItem LIJ n6llG!
choose.a''endFIItem $IJ n6llG!
choose.a''endFIItem PIJ n6llG!
dis'la+.setC6rrentFchooseG!
c6rrent=en6 = IlistI!
H
)CC
C Test the Alert com'onent.
C)
'6blic void testAlertF G D
so6ndAlert.setT+'eFAlertT+'[email protected]!
so6ndAlert.setStringFICC E..@. CCIG!
dis'la+.setC6rrentFso6ndAlertG!
H
)CC
C Test the :ate0ield com'onent.
C)
'6blic void test:ateF G D
java.6til.:ate no% = ne% java.6til.:ateF G!
date.set:ateFno%G!
0orm * = ne% 0ormFIToda+9s dateIG!
*.a''endFdateG!
*.addCommandFbackCommandG!
*.setCommandListenerFthisG!
dis'la+.setC6rrentF*G!
c6rrent=en6 = IdateI!
H
)CC
C Test the 0orm com'onent.
C)
'6blic void test0ormF G D
*orm.a''endFga6geG!
*orm.a''endFte&t*ieldG!
*orm.addCommandFbackCommandG!
*orm.setCommandListenerFthisG!
dis'la+.setC6rrentF*ormG!
c6rrent=en6 = I*ormI!
H
)CC
C Handle events.
C)
'6blic void commandActionFCommand cJ :is'la+able dG D
String label = c.getLabelF G!
i* Flabel.eB6alsFIE&itIGG D
destro+A''Ftr6eG!
H else i* Flabel.eB6alsFIEackIGG D
i*Fc6rrent=en6.eB6alsFIlistIG 55
c6rrent=en6.eB6alsFIin'6tIG 55
c6rrent=en6.eB6alsFIdateIG 55
c6rrent=en6.eB6alsFI*ormIGG D
)) go back to men6
main=en6F G!
H
H else D
List do%n = FListGdis'la+.getC6rrentF G!
s%itchFdo%n.getSelectedInde&F GG D
case K" testTe&tEo&F G!break!
case L" testListF G!break!
case $" testAlertF G!break!
case P" test:ateF G!break!
case V" test0ormF G!break!
H
H
H
H
To test the EventE&$ MI-let using the 01M2 &ireless Toolkit, do the following+
#. Create a new pro?ect (call it 26ample F"1) and a MI-let class (call it
EventE&$), copy the code to the appropriate location, and compile it.
1. >un the EventE&$ MI-let in the emulator.
9. Dou should see the name of the pro?ect (26ample F"1) in the application
manager, as shown in *igure F"9.
.igure @+0& Pro8ect !6am$le @+2 I/let
E. 'ctivate the MI-let.
;. 's the MI-let runs, you see a menu with the following options+ Test Te6tBo6,
Test .ist, Test 'lert, Test -ate, and Test *orm, as shown in *igure F"E.
.igure @+2& !vent!62 I/let
F. Choose a test to perform.
Tests from the EventE&$ MI-let are shown in *igure F";.
.igure @+3& The Te6tBo6, ,ist, and Alert tests
If you have a soundcard, you will hear a warning sound with the alert. The remaining
tests from the EventE&$ MI-let are shown in *igure F"1.
.igure @+@& /ate.ield, Calendar, and .orm, with ?auge and Te6t.ield tests
@&%&0 The Item5tate,istener Interface
'pplications use the ItemStateListener interface to receive events that indicate
changes in the internal state of items within a 0orm screen. Items within a 0orm screen
may be changed when the user performs any of the following actions+
'd?usts the value of an interactive Wa6ge.
2nters or modifies the values of a Te&t0ield.
2nters a new date or time in a :ate0ield.
Changes the set of selected values in a ChoiceWro6'.
This interface has only one method that a listener must implement+
'6blic void itemStateChangedFItem itemG!
Dou can use the setItemStateListenerF G method of the 0orm class to register a
listener for these conditions, as shown in the ne6t section.
@&%&0&% Changing the date
In 26ample F"9, a :ate0ield ob?ect is created and added to a form. &hen you click
on the date, you can change it by navigating through the calendar. &hen the date is
changed, a message appears.
!6am$le @+0& Im$lementing the Item5tate,istener interface
im'ort java&.microedition.midlet.C!
im'ort java&.microedition.lcd6i.C!
'6blic class EventE&P e&tends =I:let D
:is'la+ dis'la+!
'6blic EventE&PF G D
dis'la+ = :is'la+.get:is'la+FthisG!
H
'6blic void destro+A'' Fboolean 6nconditionalG D
noti*+:estro+edF G!
S+stem.o6t.'rintlnFIA'' destro+ed IG!
H
'6blic void 'a6seA'' F G D
dis'la+ = n6ll!
S+stem.o6t.'rintlnFIA'' 'a6sed.IG!
H
'6blic void startA'' F G D
0orm *orm = ne% 0ormFIChange :ateIG!
ItemStateListener listener = ne% ItemStateListenerF G D
java.6til.Calendar cal = java.6til.Calendar.
getInstanceFjava.6til.TimeYone.get:e*a6ltF GG!
'6blic void itemStateChangedFItem itemG D
cal.setTimeFFF:ate0ieldGitemG.get:ateF GG!
S+stem.o6t.'rintlnFI#n:ate has changedIG!
H
H!
)) register *or events
*orm.setItemStateListenerFlistenerG!
)) get toda+9s date
java.6til.:ate no% = ne% java.6til.:ateF G!
:ate0ield dateItem = ne% :ate0ieldFIToda+9s date"IJ
:ate0ield.:ATEG!
dateItem.set:ateFno%G!
)) add date to the 0orm screen
*orm.a''endFdateItemG!
dis'la+.setC6rrentF*ormG!
H
H
Here, the ItemStateListener interface is implemented as an anonymous inner class
by providing an implementation to the itemStateChangedF G method. If you run the
EventE&P MI-let, you should see output similar to *igure F"N.
.igure @+A& Im$lementing the Item5tate,istener interface
@&2 *andling ,ow+,evel !vents
If you use the Canvas class to write applications to access low"level input events or to
issue graphics calls for drawing to the display, you must handle low"level events.
<ame applications are likely to use the Canvas class because it provides methods to
handle game actions and key events. The key events are reported with respect to
keycodes that are directly bound to concrete keys on the device.
The Canvas class, which is a subclass of :is'la+able, allows the application to
register a listener for commands, but it re5uires applications to subclass the listener
first. 'lso, while screens allow the application to define a listener and register it with
an instance of the Screen class, the Canvas class does not allow this, because several
listener interfaces need to be created, one for each kind of event.
@&2&% 1e< !vents
2very key for which events are reported is assigned a keycode. The MI-P defines the
following keycodes in the Canvas class+
>E1?M-=K
The keycode for key %
>E1?M-=L
The keycode for key #
>E1?M-=$
The keycode for key 1
>E1?M-=P
The keycode for key 9
>E1?M-=V
The keycode for key E
>E1?M-=X
The keycode for key ;
>E1?M-=O
The keycode for key F
>E1?M-=R
The keycode for key N
>E1?M-=N
The keycode for key :
>E1?M-=S
The keycode for key $
>E1?STA.
The keycode for the star key IJI
>E1?P@-M:
The keycode for the pound key IRI
's you probably guessed, these are the keys %..$, J, and R. =ther keys might e6ist on
some devices, but for portability, applications should use only the standard keycodes.
The get>e+MameF G method is used to retrieve an informative string for a key.
@&2&2 ?ame Actions
If your application needs arrow keys and gaming"related events, use game actions
instead of keycodes. Canvas defines the following constants as well+
-P
' constant for the -P game action
:@WM
' constant for the :@WM game action
LE0T
' constant for the LE0T game action
.IWHT
' constant for the .IWHT game action
0I.E
' constant for the 0I.E game action
WA=E?A
' constant for the general purpose I'I game action
WA=E?E
' constant for the general purpose IBI game action
WA=E?C
' constant for the general purpose ICI game action
WA=E?:
' constant for the general purpose I-I game action
&hile each keycode is mapped to one game action, a game action can be associated
with more than one keycode. The translation between the two is done with the
get>e+CodeFG and getWameActionF G methods.
If your application uses game actions and you want the
application to be portable, you should translate key events into
game actions with the getWameActionF G method and test the
result. *or e6ample, the game actions -P, :@WM, LE0T, and .IWHT
can be mapped differently on different devices. The
getWameActionF G method returns the .IWHT game action, for
e6ample, when the user presses the key that is a natural right on
the device.
@&2&0 !vent /eliver< ethods
The following methods of the Canvas class are available for handling low"level
events+
'rotected void ke+PressedFint ke+CodeG!
'rotected void ke+.eleasedFint ke+CodeG!
'rotected void ke+.e'eatedFint ke+CodeG!
'rotected void 'ointerPressedFint &J int +G!
'rotected void 'ointer:raggedFint &J int +G!
'rotected void 'ointer.eleasedFint &J int +G!
These methods are callbacks that you should override in a class that e6tends the
Canvas class. There are a couple of important things to note here+
The ke+.e'eatedF G method might not be available on all devices. Dour
application should check the availability of repeat actions by calling the
has.e'eatEventsF G method.
The pointer events may not be present on all devices, so before using the
'ointerPressedFG, 'ointer:raggedFG, and 'ointer.eleasedF G methods,
your application should check if a pointer mechanism is available by calling
the hasPointerEventsFG and hasPointer=otionEventsF G methods first.
@&2&0&% *andling low+level events
26ample F"E shows how to handle low"level events. In this e6ample, the Canvas class
is subclassed to use an anonymous inner class, an implementation is provided for the
ke+PressedFG and ke+.eleasedF G methods, and an empty implementation is
provided for the 'aintF G method. &hen a key is pressed or released, the application
prints the value of that key.
!6am$le @+2& *andling low+level events
im'ort java&.microedition.midlet.C!
im'ort java&.microedition.lcd6i.C!
'6blic class EventE&V e&tends =I:let D
:is'la+ dis'la+!
Command e&it!
'6blic EventE&VF G D
dis'la+ = :is'la+.get:is'la+FthisG!
H
'6blic void destro+A'' Fboolean 6nconditionalG D
H
'6blic void 'a6seA'' F G D
S+stem.o6t.'rintlnFIA'' 'a6sed.IG!
H
'6blic void startA'' F G D
dis'la+ = :is'la+.get:is'la+FthisG!
Canvas canvas = ne% CanvasF G D )) anon+mo6s class
'6blic void 'aintFWra'hics gG D
H
'rotected void ke+PressedFint ke+CodeG D
i* Fke+Code , KG D
S+stem.o6t.'rintlnFIke+Pressed I UFFcharGke+CodeGG!
H else D
S+stem.o6t.'rintlnFIke+Pressed action I
UgetWameActionFke+CodeGG!
H
H
'rotected void ke+.eleasedFint ke+CodeG D
i* Fke+Code , KG D
S+stem.o6t.'rintlnFIke+.eleased I UFFcharGke+CodeGG!
H else D
S+stem.o6t.'rintlnFIke+.eleased action I
UgetWameActionFke+CodeGG!
H
H
H! )) end o* anon+mo6s class
e&it = ne% CommandFIE&itIJ Command.ST@PJ LG!
canvas.addCommandFe&itG!
canvas.setCommandListenerFne% CommandListenerF G D
'6blic void commandActionFCommand cJ :is'la+able dG D
i*Fc == e&itG D
noti*+:estro+edF G!
H else D
S+stem.o6t.'rintlnFISa% the command" IUcG!
H
H
HG!
dis'la+.setC6rrentFcanvasG!
H
H
If you run the EventE&P MI-let and activate it, you should see output similar to that
in *igure F"1.
.igure @+9& *andling low+level events
'n alternative implementation for the ke+PressedF G method is to interpret the keys
at runtime, as shown in the following segment of code+
'6blic void ke+PressedFint ke+CodeG D
int action = getWameActionFke+CodeG!
s%itchFactionG D
case LE0T" S+stem.o6t.'rintlnFI=@/E T@ THE LE0TIG!break!
case .IWHT" S+stem.o6t.'rintlnFI=@/E T@ THE .IWHTIG!break!
)) and so on....
H
H
Cha$ter A& >etworking
&ay back in Chapter #, we briefly introduced the C.-C <eneric Connection
*ramework. .et3s 5uickly review why it was necessary to create an entirely new
networking library for the C.-C.
The java.io and java.net packages of the 01!2 are not suitable for handheld
devices with a small memory footprint, for the following reasons+
-evice manufacturers who work with circuit"switched networks re5uire
stream"based connections such as the Transport Control Protocol (TCP),
which is a connection"oriented protocol.
-evice manufacturers working with packet"switched networks re5uire
datagram"based connections such as the ser -atagram Protocol (-P),
which is a connectionless protocol.
=ther handheld devices have specific mechanisms for communications.
'll this variation makes designing networking facilities for the C.-C 5uite a
challenge. This challenge has led to the design of a set of related abstractions that can
be used at the programming level instead of using different abstractions for different
forms of communications. *or e6ample, the 01!2 java.net package provides a set of
related abstractions in the form of over 1% networking classes, including Socket,
ServerSocket, and :atagramSocket. &ith the C.-C, however, we need to go a step
further to save space.
A&% ?eneric Connections
In the <eneric Connection *ramework, all connections are created using the static
o'enF G methods from a single class+ java&.microedition.io.Connector . If
successful, these methods return an ob?ect that implements one of the generic
connection interfaces. *igure N"# shows how these interfaces form an inheritance
hierarchy. The Connection interface (don3t confuse Connection with Connector) is
the base interface.
.igure A+%& Connection interface hierarch<
The Connection interface represents the most basic connection type. It can
only be opened and closed.
The In'6tConnection interface represents a device from which data can be
read. Its o'enIn'6tStreamF G method returns an input stream for the
connection.
The @6t'6tConnection interface represents a device to which data can be
written. .ikewise, its o'en@6t'6tStreamF G method returns an output stream
for the connection.
The StreamConnection interface combines the input and output connections.
The ContentConnection interface e6tends the StreamConnection interface.
It provides access to some of the basic metadata information provided by
HTTP connections.
The StreamConnectionMoti*ier interface waits for a connection to be
established. It returns an ob?ect that implements the StreamConnection
interface, on which a communication link has been established.
The :atagramConnection interface is used to represent a datagram endpoint.
The simplest o'enF G method of the Connector class has the following synta6+
'6blic Connection o'enFString nameG thro%s java.io.I@E&ce'tion!
The String parameter has the format Ischeme"targetaddress!'arametersI and
conforms to the >. synta6 in >*C 19$F. Here are a few e6amples+
2stablish an ,--. connection
Connector.o'enFIhtt'"))%%%.ora.comIG!
/tart a soc!et connection
Connector.o'enFIsocket"))%%%.ora.com"NKIG!
2stablish a data"ram connection
Connector.o'enFIdatagram"))LS$.LON.$.LKL"$PVXIG!
Comm$nicate with a port
Connector.o'enFIcomm"K!ba6drate=SOKKIG!
4pen files
Connector.o'enFI*ile")m+*ile.t&tIG!
The goal of the above synta6 is to isolate the differences between the setup of one
protocol and another protocol into a simple string that characteri4es the type of
connection. Most of the application3s code remains the same, regardless of the
protocol you use. Dou will see the benefits of this in the e6amples later in this chapter.
The connection e6amples above are for illustration only. The
C.-C itself does not provide any protocol implementations,
because no implementations should be provided at the
configuration level. In addition, a 01M2 profile such as the MI-P
does not have to provide implementations for all of the protocols
mentioned earlier. The MI-P implementation from !un
Microsystems, for e6ample, provides an implementation for the
HTTP protocol, but it does not provide implementations for
socket or datagram connections.
The Connector class provides two other static o'enF G methods that can be used to
open connections, which have the following signatures+
'6blic static Connection o'enFString 6rlJ int modeG
thro%s java.io.I@E&ce'tion!
'6blic static Connection o'enFString 6rlJ int modeJ boolean timeo6tsG
thro%s java.io.I@E&ce'tion!
The first method takes two parameters+ the >. for the connection and the access
mode. The access mode is used to indicate to the protocol handler the intentions of the
calling code. The access mode can be one of the following constants, which are
defined in the Connector class+
'6blic static *inal int .EA:!
'6blic static *inal int W.ITE!
'6blic static *inal int .EA:?W.ITE!
Dou can use these constants to specify if the connection is going to be e6clusively
read from (.EA:), e6clusively written to (W.ITE), or both (.EA:?W.ITE). If the access
mode parameter is omitted, the .EA:?W.ITE default will be used. It is important,
however, to note that these flags are protocol"dependent. *or e6ample, a connection to
a printer would not allow .EA: access.
The other o'enF G method takes an additional third parameter, which is a boolean
flag to indicate that the calling code wants to receive a timeout e6ception in the form
of a java.io.Interr6'tedI@E&ce'tion. The timeout value is not given, as it is
protocol"dependent, and there is no guarantee that the underlying protocol
implementation will throw the timeout e6ception. If this parameter is omitted, then no
timeout e6ceptions will be thrown.
A&2 I/P Connectivit<
The MI-P e6tends the C.-C <eneric Connection *ramework to provide support for
the HTTP protocol. &hy HTTPL &ell, HTTP can be implemented using both IP
protocols (such as TCP,IP) or non"IP protocols (such as &'P and I"mode). In the
latter case, the device would have to utili4e a gateway that could perform >.
naming resolution to access the Internet, as shown in *igure N"1.
.igure A+2& The ;enefit of *TTP su$$ort
'll of the MI-P #.% implementations must provide support for
the HTTP protocol. Therefore, we encourage you to only use
protocols supported by the MI-P (i.e., HTTP), as this will allow
the application to be portable across all mobile information
devices.
The idea of having the MI-P support the HTTP protocol is very clever. *or network
programming, you can revert to the HTTP programming model, and your applications
will run on any MI-P device, whether it is a <!M phone with a &'P stack, a phone
with I"mode, a Palm 8II wireless, or a handheld device with Bluetooth.
A&2&% The *tt$Connection Interface
The Htt'Connection interface is part of the java&.microedition.io package. This
interface defines the necessary methods and constants to e6change data through an
HTTP connection. It has the following methods (the constants, which have been
omitted here to save space, are documented in 'ppendi6 -)+
'6blic inter*ace Htt'Connection e&tends ContentConnection D
)) '6blic instance methods
'6blic long get:ateF G thro%s I@E&ce'tion!
'6blic long getE&'irationF G thro%s I@E&ce'tion!
'6blic String get0ileF G!
'6blic String getHeader0ieldFint nG thro%s I@E&ce'tion!
'6blic String getHeader0ieldFString nameG thro%s I@E&ce'tion!
'6blic long getHeader0ield:ateFString nameJ long de*G thro%s
I@E&ce'tion!
'6blic int getHeader0ieldIntFString nameJ int de*G thro%s
I@E&ce'tion!
'6blic String getHeader0ield>e+Fint nG thro%s I@E&ce'tion!
'6blic String getHostF G!
'6blic long getLast=odi*iedF G thro%s I@E&ce'tion!
'6blic int getPortF G!
'6blic String getProtocolF G!
'6blic String get[6er+F G!
'6blic String get.e*F G!
'6blic String get.eB6est=ethodF G!
'6blic String get.eB6estPro'ert+FString ke+G!
'6blic int get.es'onseCodeF G thro%s I@E&ce'tion!
'6blic String get.es'onse=essageF G thro%s I@E&ce'tion!
'6blic String get-.LF G!
'6blic void set.eB6est=ethodFString methodG thro%s I@E&ce'tion!
'6blic void set.eB6estPro'ert+FString ke+J String val6eG thro%s
I@E&ce'tion!
H
The HTTP protocol is a re5uest"response application protocol in which the parameters
of the re5uest must be set before the re5uest is sent. The connection could be in one of
the three following states+
/et$p
@o connection has been established yet.
Connected
' connection has been made and the re5uest has been sentA a response is
e6pected soon.
Closed
The connection has been closed. !ome methods will throw an I@E&ce'tion if
called.
=nly in the setup state can the methods set.eB6est=ethodF G and
set.eB6estPro'ert+F G be invoked. These can be used to cover the HTTP headers
that are typically seen in an HTTP re5uest. *or e6ample, suppose you have the
following connection+
Htt'Connection c = FHtt'ConnectionG
Connector.o'enFIhtt'"))%%%.ora.comIG!
Dou can set the re5uest method to be of type P@ST as follows+
c.set.eB6est=ethodFHtt'Connection.P@STG!
Dou can also use the set.eB6estPro'ert+F G method to set some of the HTTP
header information. *or e6ample, you can set the -ser7Agent property as follows+
c.set.eB6estPro'ert+FI-ser7AgentIJ
IPro*ile)=I:P7L.K Con*ig6ration)CL:C7L.KIG!
The following methods of Htt'Connection (or its sub"interfaces), which cause data
to be transmitted or received, will cause a state transition from the setup state to the
connected state+
'6blic long get:ateF G thro%s java.io.I@E&ce'tion
'6blic String getEncodingF G
'6blic long getE&'irationF G thro%s java.io.I@E&ce'tion
'6blic String getHeader0ieldFString nameG thro%s java.io.I@E&ce'tion
'6blic long getHeader0ield:ateFString nameJ long de*G thro%s
java.io.I@E&ce'tion
'6blic int getHeader0ieldIntFString nameJ int de*G thro%s
java.io.I@E&ce'tion
'6blic String getHeader0ield>e+Fint nG thro%s java.io.I@E&ce'tion
'6blic long getLast=odi*iedF G thro%s java.io.I@E&ce'tion
'6blic long getLengthF G
'6blic int get.es'onseCodeF G thro%s java.io.I@E&ce'tion
'6blic String get.es'onse=essageF G thro%s java.io.I@E&ce'tion
'6blic String getT+'eF G
'6blic :ataIn'6tStream o'en:ataIn'6tStreamFString nameG thro%s
java.io.I@E&ce'tion
'6blic :ata@6t'6tStream o'en:ata@6t'6tStreamFString nameG thro%s
java.io.I@E&ce'tion
'6blic In'6tStream o'enIn'6tStreamFString nameG thro%s
java.io.I@E&ce'tion
'6blic @6t'6tStream o'en@6t'6tStreamFString nameG thro%s
java.io.I@E&ce'tion
&hile the connection is open (i.e., in the connected state), the following methods can
be safely invoked+
'6blic void closeF G thro%s java.io.I@E&ce'tion
'6blic String get0ileF G
'6blic String getHostF G
'6blic int getPortF G
'6blic String getProtocolF G
'6blic String get[6er+F G
'6blic String get.eB6est=ethodF G
'6blic String get.eB6estPro'ert+FString ke+G
'6blic String get-.LF G
Before we look at sample applications, let3s briefly review some of the concepts that
our e6amples will be using+ the HTTP programming model, C<I, and 0ava servlets.
A&0 The *TTP Programming odel
HTTP is a re5uest"response application protocol. &hen programming with 0ava
HTTP libraries, such as the <eneric Connection *ramework, the parameters of the
re5uest must always be set before the re5uest is sent. This allows the entire re5uest,
including parameters, to be sent at the same time.
A&0&% 4eBuest ethods
There are two commands to send data from a form on a web page to a C<I script or a
servlet hosted by the HTTP server. These commands are WET and P@ST. 2ach of these
has a different way of sending data to the server.
*or the WET method, the input values are sent as part of the >. in the
[-E.1?ST.IMW environment variable.
*or the P@ST method, data is sent as an input stream and its length is saved in
the C@MTEMT?LEMWTH environment variable.
The P@ST method is more secure, and you can send more data using it. 's an e6ample,
consider the following HTM. code for the form shown in *igure N"9.
.igure A+0& .orm with one field "?!T method#
8*orm action=http://www.somesite.com/cgi-
bin/getgrade.cgimethod=IWETI,
St6dentZ"
8in'6t t+'e=Ite&tI name=Iidn6mI siAe=PK,
8in'6t name=I.etrieve=arksI val6e=I.etrieve =arksI t+'e=Is6bmitI,
8)*orm,
This form is handled by the script at -ttp:55www.somesite.com5cgi0&in5getgrade.cgi.
@ote that the form uses the WET method to transmit the information. &hen the user
enters a student number, such as ##1199, and clicks the >etrieve Marks button, the
form data is sent to the C<I script as part of the >.. Hence, the encoded >. is+
-ttp:55www.somesite.com5cgi0&in5getgrade.cgi6idnum7882299.
In the case of P@ST, however, input values are not sent as part of the >.. They are
sent as an input stream in a separate message.
If the user enters a string with spaces, all spaces are replaced by the pluses (Q). 'lso,
if the form re5uires multiple input values for different fields, the fields are separated
by an ampersand (S). *or e6ample, if the above form has two input fieldsKone for
the student name and the other for the student numberKthe names of the fields are
name and idnum, respectively. !uppose the input values are I!am .eeI for name and
I##1199I for idnum. Then the encoded >. would be+ -ttp:55www.somesite.com5cgi0
&in5getgrade.cgi6name7:am;Lee<idnum7882299.
A&0&2 5ervlets
0ava servlets also support a re5uest and response programming model. &hen a client
sends a re5uest to the server, the server relays the re5uest to the servlet. The servlet
then constructs a response that the server relays back to the client. nlike C<I scripts,
however, servlets are written in 0ava and run within the same process as the HTTP
server.
&hen a client re5uest is made, the server first calls upon the serviceF G method of
the servlet and passes it a re5uest and response ob?ect. The servlet then determines
whether this re5uest is a WET or P@ST operation, and calls either the
Htt'Servlet.doWetFG or Htt'Servlet.doPostFG methods as needed. Both the
doWetFG and doPostF G methods take a re5uest ob?ect, Htt'Servlet.eB6est, and a
response ob?ect, Htt'Servlet.es'onse, as parameters.
G#H
G#H
This is ?ust enough information to get you through this chapter. If you3d like to learn more about 0ava servlets,
we recommend Java :ervlet =rogramming by 0ason Hunter (=3>eilly).
A&2 Invoking 4emote A$$lications from I/lets
@ow let3s look at some e6amples of fetching HTTP pages and invoking C<I scripts
and servlets from MI-lets using the connection framework.
A&2&% .etching a Page
26ample N"# shows how to read the contents of a file referenced by a >., using a
StreamConnection. 'n Htt'Connection can also be used, but since no HTTP"
specific behavior is needed here, the StreamConnection is used. The application is
very simple. The Connector.o'enF G method opens a connection to the >. and
returns a StreamConnection ob?ect. Then an In'6tStream is opened through which
to read the contents of the file, one character at a time, until the end of the file
(signaled by a character value of "#) is reached. In the event that an e6ception is
thrown, both the stream and connection are closed.
!6am$le A+%& .etching a $age referenced ;< a U4,
im'ort java.io.C!
im'ort java&.microedition.io.C!
im'ort java&.microedition.lcd6i.C!
im'ort java&.microedition.midlet.C!
'6blic class 0etchPage=idlet e&tends =I:let D
'rivate :is'la+ dis'la+!
String 6rl = Ihtt'"))%%%.javaco6rses.com)hello.t&tI!
'6blic 0etchPage=idletF G D
dis'la+ = :is'la+.get:is'la+FthisG!
H
)CC
C This %ill be invoked %hen %e start the =I:let
C)
'6blic void startA''F G D
tr+ D
get/iaStreamConnectionF6rlG!
H catch FI@E&ce'tion eG D
))Handle E&ce'tions an+ other %a+ +o6 like.
S+stem.o6t.'rintlnFII@E&ce'tion I U eG!
e.'rintStackTraceF G!
H
H
)CC
C Pa6seJ discontin6e ....
C)
'6blic void 'a6seA''F G D
H
)CC
C :estro+ m6st clean6' ever+thing.
C)
'6blic void destro+A''Fboolean 6nconditionalG D
H
)CC
C read 6rl via stream connection
C)
void get/iaStreamConnectionFString 6rlG thro%s I@E&ce'tion D
StreamConnection c = n6ll!
In'6tStream s = n6ll!
StringE6**er b = ne% StringE6**erF G!
Te&tEo& t = n6ll!
tr+ D
c = FStreamConnectionGConnector.o'enF6rlG!
s = c.o'enIn'6tStreamF G!
int ch!
%hileFFch = s.readF GG T= 7LG D
b.a''endFFcharG chG!
H
S+stem.o6t.'rintlnFb.toStringF GG!
t = ne% Te&tEo&FI0etch PageIJ b.toStringF GJ LK$VJ KG!
H *inall+ D
i*Fs T= n6llG D
s.closeF G!
H
i*Fc T= n6llG D
c.closeF G!
H
H
)) dis'la+ the contents o* the *ile in a te&t bo&.
dis'la+.setC6rrentFtG!
H
H
&hen you run and activate 0etchPage=idlet, you should see a screen similar to
*igure N"E.
.igure A+2& .etching a $age reference ;< a U4,
A&2&2 Invoking a C?I 5cri$t "?!T#
The following e6ample shows how to invoke a C<I script from an HTTP server,
capturing and displaying the results on the handheld device screen. This e6ample uses
an Htt'Connection ob?ect, which is returned by the call to the Connector.o'enF G
method. The call to set.eB6est=ethodF G sets the re5uest method to WET, followed
by two calls to set.eB6estPro'ert+F G, which in turn set the HTTP re5uest header
properties -ser7Agent and Content7Lang6age. In this e6ample, a script is invoked
with a student I- number encoded as part of the >.. The script searches a database
file and returns the final grade for the student corresponding to the I- number.
The >. has the form -ttp:55www.javacourses.com5cgi0
&in5getgrade6idnum78>2?8@. 'lternatively, you can do this with
the commented"out code shown below in bold. The latter
techni5ue can also be used if the student I- number is to be
entered by the user, as you will see in the ne6t e6ample.
This e6ample3s source code is shown in 26ample N"1.
!6am$le A+2& Invoking a C?I scri$t "?!T method#
im'ort java.io.C!
im'ort java&.microedition.io.C!
im'ort java&.microedition.lcd6i.C!
im'ort java&.microedition.midlet.C!
)CC
C An e&am'le =I:let to invoke a CWI scri't FWET methodG.
C)
'6blic class InvokeCgi=idletL e&tends =I:let D
'rivate :is'la+ dis'la+!
String 6rl =
Ihtt'"))%%%.javaco6rses.com)cgibin)getgrade.cgi\idn6m=LN$KLOI!
'6blic InvokeCgi=idletLF G D
dis'la+ = :is'la+.get:is'la+FthisG!
H
)CC
C InitialiAation. Invoked %hen %e activate the =I:let.
C)
'6blic void startA''F G D
tr+ D
getWradeF6rlG!
H catch FI@E&ce'tion eG D
S+stem.o6t.'rintlnFII@E&ce'tion I U eG!
e.'rintStackTraceF G!
H
H
)CC
C Pa6seJ discontin6e ....
C)
'6blic void 'a6seA''F G D
H
)CC
C :estro+ m6st clean6' ever+thing.
C)
'6blic void destro+A''Fboolean 6nconditionalG D
H
)CC
C .etrieve a grade....
C)
void getWradeFString 6rlG thro%s I@E&ce'tion D
Htt'Connection c = n6ll!
In'6tStream is = n6ll!
@6t'6tStream os = n6ll!
StringE6**er b = ne% StringE6**erF G!
Te&tEo& t = n6ll!
tr+ D
c = FHtt'ConnectionGConnector.o'enF6rlG!
)) set the reB6est method to WET
c.set.eB6est=ethodFHtt'Connection.WETG!
)) set some HTTP reB6est headers
c.set.eB6estPro'ert+FI-ser7AgentIJIPro*ile)=I:P7L.K
Con*ig6ration)CL:C7L.KIG!
c.set.eB6estPro'ert+FIContent7Lang6ageIJ Ien7CAIG!
os = c.o'en@6t'6tStreamF G!
)C
)).etrieve in*o *or I: n6mber LN$KLO
String str = I\idn6m=LN$KLOI!
b+te 'ostmsg34 = str.getE+tesF G!
*orFint i=K!i8'ostmsg.length!iUUG D
os.%riteE+teF'ostmsg3i4G!
H
os.*l6shF G!
C)
is = c.o'en:ataIn'6tStreamF G!
int ch!
%hile FFch = is.readF GG T= 7LG D
b.a''endFFcharG chG!
S+stem.o6t.'rintlnFFcharGchG!
H
t = ne% Te&tEo&FI0inal WradesIJ b.toStringF GJ LK$VJ KG!
H *inall+ D
i*FisT= n6llG D
is.closeF G!
H
i*Fos T= n6llG D
os.closeF G!
H
i*Fc T= n6llG D
c.closeF G!
H
H
dis'la+.setC6rrentFtG!
H
H
&hen you run and activate InvokeCgi=idletL, you should see a screen similar to
*igure N";.
.igure A+3& Invoking a C?I scri$t "?!T method#
A&2&0 Invoking a C?I 5cri$t "P'5T#
@ow let3s talk about making HTTP re5uests using P@ST. In this e6ample, the input is
sent to the C<I script, called pgrade.cgi, in a message.
The >. variable, defined in 26ample N"9, specifies the location of the pgrade.cgi
C<I script. In this e6ample, an HTTP connection is opened to the C<I script,
followed by opening input and output streams on the connection. -ata for the script is
sent through the output stream, and the response is received through the input stream.
The C<I script in this e6ample, which is written in Perl, takes a student number input
value. If the student number is found in the database file, the script retrieves the
corresponding final grade and returns the grade to the calling client. In the case of
MI-lets, however, there are no HTM. forms, so here the message name=LN$KLO is
sent to the C<I script. The source code for this e6ample is shown in 26ample N"9.
@ote that when using the P@ST method, the C@MTEMT?T1PE header must be set to
a''lication)&7%%%7*orm76rlencoded, because this content type+
!pecifies normal data encoding.
Converts blanks to plus (Q) signs.
Converts non"alphanumeric characters to he6adecimal numbers preceded by a
percent sign (T).
Places an ampersand (S) between each name=val6e pair.
In short, this content type prevents data corruption during the transmission of form
data from the browser to the server.
!6am$le A+0& Invoking a C?I scri$t "P'5T method#
im'ort java.io.C!
im'ort java&.microedition.io.C!
im'ort java&.microedition.lcd6i.C!
im'ort java&.microedition.midlet.C!
)CC
C An e&am'le =I:let to invoke a CWI scri't FP@ST method is 6sedG.
C)
'6blic class InvokeCgi=idlet$ e&tends =I:let D
'rivate :is'la+ dis'la+!
String 6rl = Ihtt'"))%%%.javaco6rses.com)cgi7bin)'grade.cgiI!
'6blic InvokeCgi=idlet$F G D
dis'la+ = :is'la+.get:is'la+FthisG!
H
)CC
C InitialiAation. Invoked %hen %e activate the =I:let.
C)
'6blic void startA''F G D
tr+ D
getWradeF6rlG!
H catch FI@E&ce'tion eG D
S+stem.o6t.'rintlnFII@E&ce'tion I U eG!
e.'rintStackTraceF G!
H
H
)CC
C Pa6seJ discontin6e ....
C)
'6blic void 'a6seA''F G D
H
)CC
C :estro+ m6st clean6' ever+thing.
C)
'6blic void destro+A''Fboolean 6nconditionalG D
H
)CC
C .etrieve a grade....
C)
void getWradeFString 6rlG thro%s I@E&ce'tion D
Htt'Connection c = n6ll!
In'6tStream is = n6ll!
@6t'6tStream os = n6ll!
StringE6**er b = ne% StringE6**erF G!
Te&tEo& t = n6ll!
tr+ D
c = FHtt'ConnectionGConnector.o'enF6rlG!
c.set.eB6est=ethodFHtt'Connection.P@STG!
c.set.eB6estPro'ert+FIC@MTEMT7T1PEIJ
Ia''lication)&7%%%7*orm76rlencodedIG!
c.set.eB6estPro'ert+FI-ser7AgentIJ
IPro*ile)=I:P7L.K Con*ig6ration)CL:C7L.KIG!
c.set.eB6estPro'ert+FIContent7Lang6ageIJ Ien7CAIG!
os = c.o'en@6t'6tStreamF G!
)) send in'6t
String str = Iname=LN$KLOI!
b+te 'ostmsg34 = str.getE+tesF G!
*orFint i=K!i8'ostmsg.length!iUUG D
os.%riteF'ostmsg3i4G!
H
os.*l6shF G!
is = c.o'en:ataIn'6tStreamF G!
int ch!
)) receive o6t'6t
%hile FFch = is.readF GG T= 7LG D
b.a''endFFcharG chG!
S+stem.o6t.'rintlnFFcharGchG!
H
t = ne% Te&tEo&FI0inal WradesIJ b.toStringF GJ LK$VJ KG!
H *inall+ D
i*FisT= n6llG D
is.closeF G!
H
i*Fos T= n6llG D
os.closeF G!
H
i*Fc T= n6llG D
c.closeF G!
H
H
dis'la+.setC6rrentFtG!
H
H
&hen you run and activate the InvokeCgi=idlet$, you should see output similar to
*igure N"F.
.igure A+@& Invoking a C?I scri$t "P'5T method#
A&2&2 Invoking a 5ervlet
Dou can invoke a servlet from a MI-let the same way you would invoke a C<I script+
by opening an HTTP connection and obtaining input,output streams on that
connection. This section presents two e6amples.
The first e6ample invokes a servlet using the WET operation and collects and
displays the results.
In the second e6ample, the servlet accepts input obtained from the user of the
handset and invoked with the P@ST method.
A&2&2&% .irstidlet5ervlet
In this e6ample, InvokeServlet=idletL is invoked with the WET method and the
response is received and displayed on the handset. @o input is sent to the servlet.
&hen invoked, the servlet sends the IServlet InvokedTI string and the date back to
the client. The source code for the InvokeServlet=idletL is in 26ample N"E.
!6am$le A+2& Invoking a servlet with no in$ut values
im'ort java.io.C!
im'ort java&.microedition.io.C!
im'ort java&.microedition.lcd6i.C!
im'ort java&.microedition.midlet.C!
)CC
C An e&am'le =I:let to invoke a servlet.
C)
'6blic class InvokeServlet=idletL e&tends =I:let D
'rivate :is'la+ dis'la+!
String 6rl =
Ihtt'"))L$R.K.K.L"NKNK)e&am'les)servlet)HelloServletI!
'6blic InvokeServlet=idletLF G D
dis'la+ = :is'la+.get:is'la+FthisG!
H
)CC
C InitialiAation. Invoked %hen %e activate the =I:let.
C)
'6blic void startA''F G D
tr+ D
invokeServletF6rlG!
H catch FI@E&ce'tion eG D
S+stem.o6t.'rintlnFII@E&ce'tion I U eG!
e.'rintStackTraceF G!
H
H
)CC
C Pa6seJ discontin6e ....
C)
'6blic void 'a6seA''F G D
H
)CC
C :estro+ m6st clean6' ever+thing.
C)
'6blic void destro+A''Fboolean 6nconditionalG D
H
)CC
C .etrieve a grade....
C)
void invokeServletFString 6rlG thro%s I@E&ce'tion D
Htt'Connection c = n6ll!
In'6tStream is = n6ll!
StringE6**er b = ne% StringE6**erF G!
Te&tEo& t = n6ll!
tr+ D
c = FHtt'ConnectionGConnector.o'enF6rlG!
c.set.eB6est=ethodFHtt'Connection.WETG!
c.set.eB6estPro'ert+FI-ser7AgentIJIPro*ile)=I:P7L.K
Con*ig6ration)CL:C7L.KIG!
c.set.eB6estPro'ert+FIContent7Lang6ageIJ Ien7CAIG!
is = c.o'en:ataIn'6tStreamF G!
int ch!
%hile FFch = is.readF GG T= 7LG D
b.a''endFFcharG chG!
H
t = ne% Te&tEo&FI0irst ServletIJ b.toStringF GJ LK$VJ KG!
H *inall+ D
i*FisT= n6llG D
is.closeF G!
H
i*Fc T= n6llG D
c.closeF G!
H
H
dis'la+.setC6rrentFtG!
H
H
The source code for the HelloServlet, which sends the message IServlet
InvokedTI and the date back to the client, is shown in 26ample N";. Dou will need a
web server that is capable of running servlets to make this work, such as the freely
distributed 'pache Tomcat.
!6am$le A+3& *ello5ervlet
im'ort java.io.C!
im'ort java.6til.C!
im'ort java&.servlet.C!
im'ort java&.servlet.htt'.C!
)CC
C The sim'lest 'ossible servlet.
C)
'6blic class HelloServlet e&tends Htt'Servlet D
'6blic void doWetFHtt'Servlet.eB6est reB6estJ Htt'Servlet.es'onse
res'onseG
thro%s I@E&ce'tionJ ServletE&ce'tion D
res'onse.setContentT+'eFIte&t)'lainIG!
PrintWriter o6t = res'onse.getWriterF G!
o6t.'rintlnFIServlet InvokedTIG!
o6t.'rintlnFne% :ateF GG!
H
H
&hen you run and activate the InvokeServlet=idletLJ you should see something
similar to *igure N"N.
.igure A+A& .irst5ervletidlet out$ut
A&2&2&2 5econdidlet5ervlet
@ow let3s see how to invoke a servlet that e6pects input with the P@ST method. This is
a more sophisticated e6ample than the previous one. In this e6ample, the
InvokeServlet=idlet$ prompts the user to enter a value (the first name). &hen the
user presses the key that corresponds to the S6bmit command, the .eB6estServlet
is invoked. .eB6estServlet then retrieves the input values of the re5uest from the
buffer and returns them back to the client, showing that the servlet received the P@ST
re5uest. @ote that the servlet and the MI-let in this e6ample run on the same
machine. The source code for the InvokeServlet=idlet$ is shown in 26ample N"F.
!6am$le A+@& Invoking a servlet with an in$ut value
im'ort java&.microedition.rms.C!
im'ort java&.microedition.lcd6i.C!
im'ort java&.microedition.midlet.C!
im'ort java&.microedition.io.C!
im'ort java.io.C!
im'ort java.6til./ector!
'6blic class InvokeServlet=idlet$ e&tends =I:let im'lements
CommandListener D
:is'la+ dis'la+ = n6ll!
List men6 = n6ll!
Te&tEo& in'6t = n6ll!
String 6ser = n6ll!
)) note that the servlet and =I:let r6n on the same machine
String 6rl =
Ihtt'"))L$R.K.K.L"NKNK)e&am'les)servlet).eB6estServlet$I!
static *inal Command backCommand = ne% CommandFIEackIJ
Command.EAC>J KG!
static *inal Command s6bmitCommand = ne% CommandFIS6bmitIJ
Command.@>J $G!
static *inal Command e&itCommand = ne% CommandFIE&itIJ
Command.ST@PJ PG!
String c6rrent=en6 = n6ll!
'6blic InvokeServlet=idlet$F G D
H
'6blic void startA''F G thro%s =I:letStateChangeE&ce'tion D
dis'la+ = :is'la+.get:is'la+FthisG!
men6 = ne% ListFIInvoke ServletIJ Choice.I=PLICITG!
men6.a''endFIAdd a 6serIJ n6llG!
men6.addCommandFe&itCommandG!
men6.setCommandListenerFthisG!
main=en6F G!
H
'6blic void 'a6seA''F G D
H
'6blic void destro+A''Fboolean 6nconditionalG D
noti*+:estro+edF G!
H
void main=en6F G D
dis'la+.setC6rrentFmen6G!
H
'6blic void addMameF G D
in'6t = ne% Te&tEo&FIEnter *irst name"IJ IIJ XJ
Te&t0ield.AM1G!
in'6t.addCommandFs6bmitCommandG!
in'6t.addCommandFbackCommandG!
in'6t.setCommandListenerFthisG!
in'6t.setStringFIIG!
dis'la+.setC6rrentFin'6tG!
H
void invokeServletFString 6rlG thro%s I@E&ce'tion D
Htt'Connection c = n6ll!
In'6tStream is = n6ll!
@6t'6tStream os = n6ll!
StringE6**er b = ne% StringE6**erF G!
Te&tEo& t = n6ll!
tr+ D
c = FHtt'ConnectionGConnector.o'enF6rlG!
c.set.eB6est=ethodFHtt'Connection.P@STG!
c.set.eB6estPro'ert+FIC@MTEMT7T1PEIJ
Ia''lication)&7%%%7*orm76rlencodedIG!
c.set.eB6estPro'ert+FI-ser7AgentIJ
IPro*ile)=I:P7L.K Con*ig6ration)CL:C7L.KIG!
c.set.eB6estPro'ert+FIContent7Lang6ageIJ Ien7CAIG!
os = c.o'en@6t'6tStreamF G!
String str = Iname=IU6ser!
b+te 'ostmsg34 = str.getE+tesF G!
S+stem.o6t.'rintlnFILength" IUstr.getE+tesF GG!
*orFint i=K!i8'ostmsg.length!iUUG D
os.%riteF'ostmsg3i4G!
H
)) or +o6 can easil+ do"
))os.%riteFFIname=IU6serG.getE+tesF GG!
os.*l6shF G!
is = c.o'en:ataIn'6tStreamF G!
int ch!
%hile FFch = is.readF GG T= 7LG D
b.a''endFFcharG chG!
S+stem.o6t.'rintFFcharGchG!
H
t = ne% Te&tEo&FISecond ServletIJ b.toStringF GJ LK$VJ KG!
t.addCommandFbackCommandG!
t.setCommandListenerFthisG!
H *inall+ D
i*FisT= n6llG D
is.closeF G!
H
i*Fos T= n6llG D
os.closeF G!
H
i*Fc T= n6llG D
c.closeF G!
H
H
dis'la+.setC6rrentFtG!
H
'6blic void commandActionFCommand cJ :is'la+able dG D
String label = c.getLabelF G!
i* Flabel.eB6alsFIE&itIGG D
destro+A''Ftr6eG!
H else i* Flabel.eB6alsFIEackIGG D
main=en6F G!
H else i* Flabel.eB6alsFIS6bmitIGG D
6ser = in'6t.getStringF G!
tr+ D
invokeServletF6rlG!
HcatchFI@E&ce'tion eG DH
H else D
addMameF G!
H
H
H
The source code for the .eB6estServlet, which retrieves the P@ST re5uest from the
buffer and sends the input values back to the client, is shown in 26ample N"N.
!6am$le A+A& 4eBuest5ervlet
im'ort java.io.C!
im'ort java.te&t.C!
im'ort java.6til.C!
im'ort java&.servlet.C!
im'ort java&.servlet.htt'.C!
)CC
C E&am'le servlet sho%ing reB6est headers
C)
'6blic class .eB6estServlet e&tends Htt'Servlet D
'6blic void doPostFHtt'Servlet.eB6est reB6estJ Htt'Servlet.es'onse
res'onseG
thro%s I@E&ce'tionJ ServletE&ce'tion D
res'onse.setContentT+'eFIte&t)'lainIG!
PrintWriter o6t = res'onse.getWriterF G!
E6**ered.eader br = reB6est.get.eaderF G!
String b6* = br.readLineF G!
o6t.'rintFI.ec" IUb6*G!
H
H
In order to use Servlet.eB6est.getParameterFStringG to
retrieve the input values from the MI-let in 26ample N"F, the
C@MTEMT?T1PE header must be set to a''lication)&7%%%7
*orm76rlencoded, as discussed earlier in this chapter.
&hen you run InvokeServlet=idlet$ and invoke it by entering your name, you
should see something similar to *igure N":.
.igure A+9& 5econdidlet5ervlet out$ut
A&3 (ireless 5ession Tracking
The term session tracking means maintaining state information about a series of
re5uests from the same client. Maintaining such information for clients that use HTTP
is a problem. &hyL Because HTTP is a re5uest"response protocol, which means the
connection between the client and the server is not maintained for the duration of the
conversation. In other words, HTTP is a stateless protocol. This means you cannot
depend on the underlying connection protocol to maintain state informationA you must
find other ways to perform session tracking.
The two most widely used techni5ues for session tracking are cookies and !4L
rewriting. ' cookie is a piece of data that a &eb server sends to the client. This piece
of data is stored by the client and used the ne6t time the client makes a re5uest from
that server. However, if cookies are disabled by the browser or, more importantly, if
the browser itself does not support them (as is the case with most current wireless
devices), then cookies are not of much use. However, you can send and receive
cookies through the use of the Htt'Connection.set.eB6estPro'ert+F G and
Htt'Connection.getHeader0ieldF G methods. To send a cookie to a server, simply
set the value of the cookie re5uest property before sending the message.
String m+LocalCookie/ariable!
Htt'Connection connection = FHtt'ConnectionGConnection.o'enFsome-.LG!
Connection.set.eB6estPro'ert+FIcookieIJ m+LocalCookie/ariableG!
&hen you receive a response back from the server, you can parse the resulting Set7
cookie header field as follows+
is = c.o'enIn'6tStreamF G!
String cookie = connection.getHeader0ieldFISet7cookieIG!
I* Fcookie T= n6llG
m+LocalCookie/ariable = cookie.s6bstringFKJ cookie.inde&@*FI!IGG!
The other techni5ue for session tracking is >. rewriting. This techni5ue is ideal for
clients that do not support cookies or have cookies disabled. &ith this techni5ue, the
session information is encoded into >.s that the server generates. This means that
instead of returning this >. (-ttp:55www.somesite.com5servlet5s-op5catalog.-tml),
the server generates the following >., or something similar, instead
(-ttp:55www.somesite.com5servlet5s-op5catalog.-tmlAjsessionid7clB>9C9@C9t).
The information that would otherwise be stored in a cookie is appended to the >..
Dou can parse this information out into a String after it arrives, using a techni5ue
similar the one we used with cookies in the previous section. The server will look for
this information when a re5uest is made from the client. The e6act synta6 of the
encoded >. depends on the underlying server environment. However, the 0ava
!ervlet 'PI provides facilities such as the res'onse.encode-.LFStringG and
res'onse.encode.edirect-.LFStringG methods, which you can use for session
tracking.
A&@ I/let >etworking 5ecurit<
=ver the past few years, concerns about security on the Internet have heated up
immensely. It3s common in this day and age to hear of companies whose data has been
hacked and from whom valuable credit card information has been stolen. It probably
won3t be long before people can IsniffI the data going through cell phones ?ust as
easily as data traveling across the Internet. &hat can you doL *ortunately, computers
these days are capable of using encr'ption techni5ues to scramble data as it travels
through the unsafe corridors of the Internet. In fact, one of the most popular forms of
encryption uses a wide variety of cryptographic techni5ues to protect your data. It3s
called !ecure !ockets .ayer (!!.) and is built into practically every web browser.
&ill you need encryption for your MI-let programsL That3s a hard 5uestion to answer.
Many wireless protocols already use a sophisticated level of scramblingKfar more
than an average IsnifferI can decode. 'nd while cryptographic software can be
relatively small and easy to use on a desktop, using it on a cell phone can 5uickly
e6pend both your processing power and program space. nderstanding cryptography
can take a bit of time as well.
G1H
However, if you absolutely must have security on your
cell phone to protect data traveling on the Internet, we recommend checking out the
open source lightweight 'PI software from IThe .egion of the Bouncy CastleI
(http+,,www.bouncycastle.org).
G1H
' great place to start, however, is Bruce !chneier3s pplied Cr'ptograp-', !econd 2dition (&iley).
Cha$ter 9& /ata;ase Programming
' database is a non"volatile place for storing the state of ob?ects. *or some
applications, you might need ob?ects to e6ist even after the application that created
them closes. &ithout a storage mechanism, ob?ects and their states are destroyed
when an application closes. However, if you save ob?ects to a persistent storage
facilit', such as a database, they can be read in later by the same application or even
other applications.
The persistent storage facilities provided in the 01!2 platform, such as the 0-BC and
=b?ect !eriali4ation 'PIs, are too large for handheld devices with a small memory
footprint. !torage re5uirements vary significantly from one resource"constrained
device to another. 01M2 and the MI-P solve this problem by using the >ecord
Management !ystem (>M!).
This chapter introduces the details of the MI-P >M!, a persistent storage facility for
MI-lets, and shows you how to develop MI-P database applications, using an
e6ample involving stocks. Throughout this chapter, the terms record store and
data&ase are used interchangeably.
9&% The 4ecord anagement 5<stem
'n >M! database (or record store) consists of a collection of records that remain
persistent after the MI-let closes. &hen you invoke the MI-let again, it can retrieve
data from the persistent record store. However, to use the >M!, we need to get
familiar with some of the classes and concepts provided by the
java&.microedition.rms package.
9&%&% 4ecord 5tores
>ecord stores, which are binary files, are actually platform"dependent because they
are created in platform"uni5ue locations. MI-lets within a single application (a
MI-let suite) can create multiple record stores with different names. The >M! 'PIs
provide the following types of functionality.
They allow MI-lets to manipulate (add and remove) records within a record
store.
They allow MI-lets in the same application or suite to share records (access
each other3s record store directly).
@ote that no mechanism, however, is provided for sharing records between MI-lets in
different MI-let suites.
>ecord stores have names that are case"sensitive and cannot be more than 91
characters in length. ' MI-let cannot create two record stores with the same name in
the same application. However, it can create a record store with the same name in
another application. &hen you create a new record store in an emulator, it is typically
stored under a directory called D#JM. *or e6ample, let3s assume you are using the
&ireless Toolkit and it is installed under C:\J2ME."/. If your pro?ect name is
:tockEuotes and your record store is m'stocks, the record store is created under
C:\J2ME."/\D#JM and has the name m'stocks.d&.
The MI-P >M! implementation ensures that all individual record store operations are
atomic, synchronous, and seriali4ed, so no corruption occurs with multiple access.
However, if your MI-lets use multiple threads to access a record store, it is your
responsibility to synchroni4e this access. =therwise, some of your records might
accidentally be overwritten if your application is not thread"safe.
9&%&2 The 8ava6µedition&rms Package
The java&.microedition.rms package consists of four interfaces, one class, and
five e6ception classes.
9&%&2&% Interfaces
Table :"# lists the four interfaces in the java&.microedition.rms package.
Ta;le 9+%& The interfaces in 8ava6µedition&rms
Interface Description
.ecordCom'arator This interface defines a comparator to compare two records.
.ecordEn6meration This interface represents a bidirectional record enumerator.
.ecord0ilter
This interface defines a filter to e6amine a record and check if it matches,
based on a criteria defined by the application.
.ecordListener
This interface receives records that were added, changed, or deleted from a
record store.
9&%&2&2 Classes
There is one class in this package, as shown in Table :"1.
Ta;le 9+2& The class in 8ava6µedition&rms
Class Description
.ecordStore This class represents a record store.
9&%&2&0 !6ce$tions
There are five e6ceptions in the package, as shown in Table :"9.
Ta;le 9+0& The e6ce$tions in 8ava6µedition&rms
!ception Description
Invalid>ecordI-26ception This e6ception is thrown to indicate that the >ecordI- is invalid.
>ecord!tore26ception
This e6ception is thrown when a general e6ception is thrown by the
.ecordStore class.
>ecord!tore*ull26ception This e6ception is thrown when the record store filesystem is full.
>ecord!tore@ot*ound26ception This e6ception is thrown when the record store could not be found.
>ecord!tore@ot=pen26ception
This e6ception is thrown to indicate an operation on a closed record
store.
9&2 Programming with the 45
-atabase programming with the >M! is relatively straightforward. ' record store
consists of a collection of records that is uni5uely identified by its record I-, which is
an integer value. The record I- is the primary key for the records. The first record has
an I- of #, and each additional record is assigned an I- that is the previous value plus
#. The record I- is stored as an integer value, which gives the theoretical limit of
1,#EN,E:9,FEN records.
G#H
G#H
But if your devices had at least 1.# gig of memory, you probably wouldn3t need to use the 01M2C
9&2&% '$ening, Closing, and /eleting a 4ecord 5tore
To open a record store, you need to be familiar with the static o'en.ecordStoreF G
method of the .ecordStore class+
'6blic static .ecordStore o'en.ecordStoreFString recordStoreMameJ
Eoolean createI*Mecessar+G thro%s .ecordStoreE&ce'tionJ
.ecordStore06llE&ce'tionJ .ecordStoreMot0o6ndE&ce'tion
Here is an e6ample of using this method+
.ecordStore db = n6ll!
tr+ D
db = .ecordStore.o'en.ecordStoreFIm+:E*ileIJ tr6eG!
H catch F.ecordStoreMot0o6ndE&ce'tion rsn*eG D
)) Handle e&ce'tion
H catch F.ecordStore06llE&ce'tion *s*eG D
)) Handle e&ce'tion
H catch F.ecordStoreE&ce'tion rseG D
)) Handle e&ce'tion
H
'ssuming that everything works right, this line of code creates a new database file
named m'D%file. The second parameter, a boolean which is set to tr6e, says that if
the record store does not e6ist, then you should create it.
If the o'en.ecordStoreF G method is called by a MI-let when
the record store is already open by another MI-let in the same
MI-let suite, the method returns a reference to the same
.ecordStore ob?ect.
=nce we3ve opened a record store, we will eventually need to close it. &e can do this
with the following .ecordStore method+
'6blic void close.ecordStoreF G thro%s .ecordStoreMot@'enE&ce'tionJ
.ecordStoreE&ce'tion
It is important to note that the record store will not actually be closed until
close.ecordStoreFG is called as many times as o'en.ecordStoreF G was called.
Therefore, the programmer must balance the number of close calls and open calls
before the record store is actually closed. 7eeping a record store open can take up a
great deal of memory. Consider closing a record store even when a MI-let is placed
in the paused state.
!ometimes it3s necessary to locate a particular record store among several that are
currently on the device. If you want to find out the names of all the record stores
currently on the device, use the following static method+
'6blic static String34 list.ecordStoresF G
Dou can delete an entire record store from the database, using the following static
.ecordStore method+
'6blic static void delete.ecordStoreFString recordStoreMameG thro%s
.ecordStoreE&ce'tionJ .ecordStoreMot0o6ndE&ce'tion
Dou can find out the si4e of the currently opened record store in bytes, using the
getSiAeF G method+
'6blic int getSiAeF G thro%s .ecordStoreMot@'enE&ce'tion
In addition, if you want to find out how many bytes the current record store can still
grow, use the following+
'6blic int getSiAeAvailableF G thro%s .ecordStoreMot@'enE&ce'tion
*inally, you can use the get/ersionF G method of the .ecordStore to find out the
IversionI of the current record store. Here, the version does not have anything to do
with the version of software that the database is using. Instead, the version is actually
an integer stored with the record store that increments each time a record is added,
modified, or deleted.
'6blic int get/ersionF G thro%s .ecordStoreMot@'enE&ce'tion
9&2&2 Creating and odif<ing 4ecords
' record is simply an array of bytes. Dou can use the :ataIn'6tStream,
:ata@6t'6tStream, E+teArra+In'6tStream, and E+teArra+@6t'6tStream classes
to pack and unpack data in and out of byte arrays. *or e6ample, suppose you have the
following record, represented by a single string+ I0irstnameJ LastMameJ AgeI. To
add this record to the record store, you can use the add.ecordF G method+
'6blic int add.ecordFb+te34 dataJ int o**setJ int n6mE+tesG thro%s
.ecordStoreMot@'enE&ce'tionJ .ecordStoreE&ce'tionJ
.ecordStore06llE&ce'tion
This method adds all or part of the contents of a byte array of data, starting at the
o**set specified and continuing the n6mE+tes, and places it in the record store. The
method then returns the inde6 assigned to that record in the database. Continuing from
the previous e6ample+
tr+ D
E+teArra+@6t'6tStream baos = ne% E+teArra+@6t'6tstreamF G!
:ata@6t'6tStream dos = ne% :ata@6t'6tStreamFbaosG!
dos.%rite-T0FrecordG!
E+te b34 = baos.toE+teArra+F G!
recordM6mber = db.add.ecordFbJ KJ b.lengthG!
H catch FE&ce'tion eG D
)) Handle e&ce'tions
H
Here, we construct a :ata@6t'6tStream for writing the record to the record store,
then convert the E+teArra+@6t'6tStream to a byte array. *inally, we invoke
add.ecordF G to add the record to the record store. This is not the only way to
construct and add a new record to a record store, however. Instead of creating a series
of linked streams, it is easier to convert a string into a series of bytes using the
getE+tesF G method of String+
tr+ D
String record = I0irstnameJ LastnameJ AgeI!
E+te b34 = record.getE+tesF G!
recordM6mber = db.ad.ecordFbJ KJ b.lengthG!
H catch FE&ce'tion eG D
)) Handle E&ce'tions
H
Dou can also use the set.ecordF G method if you want to e6plicitly reset an inde6ed
record in the record store. This works the same as add.ecordF G, e6cept that the first
parameter is the specific record I- that you wish to set+
'6blic void set.ecordFint recordIdJ b+te34 ne%:ataJ int o**setJ
int n6mE+tesG thro%s .ecordStoreMot@'enE&ce'tionJ
Invalid.ecordI:E&ce'tionJ .ecordStoreE&ce'tionJ
.ecordStore06llE&ce'tion
To read a record from the record store, you can use one of two get.ecordF G
methods+
'6blic b+te34 get.ecordFint recordI:G thro%s
.ecordStoreMot@'enE&ce'tionJ Invalid.ecordI:E&ce'tionJ
.ecordStoreE&ce'tion
'6blic int get.ecordFint recordI:J b+te34 b6**erJ int o**setG
thro%s .ecordStoreMot@'enE&ce'tionJ Invalid.ecordI:E&ce'tionJ
.ecordStoreE&ce'tion
The first method returns a byte array containing the entire record that was stored at the
specified record I-. The second method will attempt to fill the byte array passed in
starting at the specified offset with the contents of the specified record I-. The second
method will return the amount of bytes actually copied as an integer. Be sure that
there is enough room in the byte array to handle the data from the record, or an
e6ception will be thrown.
To e6tract the data from a byte array, we can do the opposite of what we did before+
construct input streams instead of output streams. Here is an e6ample+
String in = n6ll!
tr+ D
b+te34 record = ne% b+te3db.get.ecordSiAeFrecordM6mberG4!
db.get.ecordFrecordM6mberJ recordJ KG!
E+teArra+In'6tStream bais = ne% E+teArra+In'6tStreamFrecordG!
:ataIn'6tStream dis = ne% :ataIn'6tStreamFbaisG!
in = dis.read-T0F G!
H catch FE&ce'tion eG D
)) Handle e&ce'tions
H
=r, if we don3t want to filter the data through any sort of stream, we can take the easy
route and simply pass the byte array directly into the String constructor+
String in = n6ll!
tr+ D
b+te34 record = ne% b+te3db.get.ecordSiAeFrecordM6mberG4!
db.get.ecordFrecordM6mberJ recordJ KG!
in = ne% StringFrecordG!
H catch FE&ce'tion eG D
)) Handle e&ce'tions
H
To delete a record from the record store, you have to know the record I- of the record
to be deleted. To delete the record, use the delete.ecordF G method.
'6blic void delete.ecordFint recordI:G thro%s
.ecordStoreMot@'enE&ce'tionJ Invalid.ecordI:E&ce'tionJ
.ecordStoreE&ce'tion
@ote that the other records will not change their I-. In fact, the record store will not
reuse the I- of a record once it is deleted.
There are a number of other methods that you can use in the .ecordStore class. If
you want to find out when the record store was last modified, you can use the
following method+
'6blic long getLast=odi*iedF G thro%s .ecordStoreMot@'enE&ce'tion
This method returns a date in the form of a long, which is e5uivalent to the format
used by S+stem.c6rrentTime=illisF G. This can be passed into the constructor of
the java.6til.:ate ob?ect, which can in turn be used by the java.6til.Calendar
ob?ect, as well as the java&.microedition.lcd6i.:ate0ield component.
If you want to know the name of the current record store, use the getMameF G
method+
'6blic String getMameF G thro%s .ecordStoreMot@'enE&ce'tion
If you want to find out the ne6t I- that the database will use when storing a record,
you can use the getMe&t.ecordI:F G method+
'6blic int getMe&t.ecordI:F G thro%s .ecordStoreMot@'enE&ce'tionJ
.ecordStoreE&ce'tion
To get a tally of the number of records currently in the record store, use the following
method+
'6blic int getM6m.ecordsF G thro%s .ecordStoreMot@'enE&ce'tion
If you wish to find out the number of bytes in a currently stored record, use the
get.ecordSiAeF G method (as we did in one of the previous e6amples to initiali4e
the receiving byte array)+
'6blic int get.ecordSiAeFint recordIdG thro%s
.ecordStoreMot@'enE&ce'tionJ Invalid.ecordI:E&ce'tionJ
.ecordStoreE&ce'tion
*inally, there is one other method that .ecordStore includes that allows us to
enumerate all the records located in the current record store. It looks like the
following+
'6blic .ecordEn6meration en6merate.ecordsF.ecord0ilter *ilterJ
.ecordCom'arator com'aratorJ boolean kee'-'datedG thro%s
.ecordStoreMot@'enE&ce'tion
This method will list all the records in the record store, first using the appropriate
filter to select those records, then sorting them using the record comparator, and
finally returning the results inside a specially designed enumeration ob?ect. However,
there are several interfaces that we need to go over first before we can grasp the broad
picture of what this method does.
9&2&0 .iltering 4ecords
*irst, the en6merate.ecordsF G method must determine which records will be
included in the enumeration that you are re5uesting. The method determines this by
passing in an ob?ect that implements the java&.microedition.rms..ecord0ilter
interface. .uckily, only one method in this interface needs to be implemented+
'6blic boolean matchesFb+te34 candidateG!
This method takes in a byte array that represents a candidate record from a record
store. The implementation must return a boolean that indicates whether the record
should be included in the enumeration. If the method returns tr6e, the record will be
includedA if it3s *alse, it will not be. If you want all records to be included in the
enumeration, simply pass in n6ll to that parameter of the en6merate.ecordsF G
method.
Here is a sample implementation for the .ecord0ilter interface that only accepts
String"based records that start with the letters I<-L1I+
im'ort java&.microedition.rms.C!
'6blic class =+0ilter im'lements .ecord0ilter D
'6blic boolean matchesFb+te34 candidateG D
String c = ne% StringFcandidateG!
i* Fc.startsWithFI<-L1IGG
ret6rn tr6e!
else
ret6rn *alse!
H
H
9&2&2 Com$aring 4ecords
The en6merate.ecordsF G method has the ability to sort the records that it is
returning. If you would like it to do so, you must give it the ability to compare records
in the record store. *or this, your application must provide an ob?ect that implements
the java&.microedition.rms..ecordCom'arator interface. 'gain, this is relatively
simple, as you must implement only one method in this interface+
'6blic int com'areFb+te34 recordLJ b+te34 record$G
The return value of this method indicates how the two records compare, and it can be
one of three constants. *or e6ample, suppose you want to le6igraphically compare
two strings that you retrieved from two records. Here is a sample implementation+
im'ort java&.microedition.rms.C!
'6blic class =+Com'arator im'lements .ecordCom'arator D
'6blic int com'areFb+te recordL34J b+te record$34G D
String nameL = ne% StringFrecordLG!
String name$ = ne% StringFrecord$G!
int n6m = nameL.com'areToFname$G!
i*Fn6m , KG D
ret6rn .ecordCom'arator.0@LL@WS!
H else i* Fn6m 8 KG D
ret6rn .ecordCom'arator.P.ECE:ES!
H else D
ret6rn .ecordCom'arator.E[-I/ALEMT!
H
H
H
The constants that the ob?ect should return, .ecordCom'arator.0@LL@WS,
.ecordCom'arator.P.ECE:ES, and .ecordCom'arator.E[-I/ALEMT, are declared in
the .ecordCom'arator interface and have the following meanings+
.ecordCom'arator.0@LL@WS
The first record follows the second record in terms of search or sort order.
.ecordCom'arator.P.ECE:ES
The first record precedes the second record in terms of search or sort order.
.ecordCom'arator.E[-I/ALEMT
The two records are the same.
If the I- of each of the records is acceptable as an order, then you can pass in n6ll to
that parameter of the en6merate.ecordsF G method.
9&2&3 !numerating 4ecords
*inally, the en6merate.ecordsF G method will return to you an ob?ect that
implements the java&.microedition.rms..ecordEn6meration interface. This
interface is used to provide a standard set of methods to access the enumeration, and
acts like a more sophisticated version of the java.6til.En6meration class. It looks
like the following+
'6blic inter*ace .ecordEn6meration D
'6blic void destro+F G!
'6blic boolean hasMe&tElementF G!
'6blic boolean hasPrevio6sElementF G!
'6blic boolean is>e't-'datedF G!
'6blic void kee'-'datedFboolean kee'-'datedG!
'6blic b+te34 ne&t.ecordF G thro%s Invalid.ecordI:E&ce'tionJ
.ecordStoreMot@'enE&ce'tionJ .ecordStoreE&ce'tion!
'6blic int ne&t.ecordIdF G thro%s Invalid.ecordI:E&ce'tion!
'6blic int n6m.ecordsF G!
'6blic b+te34 'revio6s.ecordF G thro%s Invalid.ecordI:E&ce'tionJ
.ecordStoreMot@'enE&ce'tionJ .ecordStoreE&ce'tion!
'6blic int 'revio6s.ecordI:F G thro%s Invalid.ecordI:E&ce'tion!
'6blic void reb6ildF G!
'6blic void resetF G!
H
If you recall the signature of the en6merate.ecordsF G method, you3ll remember that
it had a third parameter, which was a boolean, called kee'-'dated. The function of
this boolean is to have the enumeration monitor the current record store. If there are
several threads updating the record store at any given time, the enumeration may not
have the correct values inside it.
However, if the boolean parameter to en6merate.ecordsF G is set to tr6e, the
.ecordEn6meration becomes a listener to the record store. If there are any changes
to the records, the .ecordEn6meration will update itself automatically. However, if
the boolean value is set to *alse, the .ecordEn6meration will not update itself until
the reb6ildF G method is called. &hich method to use is entirely your choice.
However, keep in mind that each call to en6merate.ecordsF G can take 5uite a bit of
time to complete. If you have a large data store, it may be better to implement another
strategy.
The following methods of .ecordEn6meration will also set and retrieve the boolean
property to keep the enumeration updated with any changes to the record store+
'6blic void kee'-'datedFboolean kee'-'datedG!
'6blic boolean is>e't-'datedF G!
To find out how many records have been filtered into the enumeration itself, use the
following method. (@ote the number of filtered records may not be the same as the
total amount of records in the record store.)
'6blic int n6m.ecordsF G!
If you wish to find out if the enumeration has an element before or after the current
position, you can use the following methods. @ote that the enumeration will loop
around in the event that it travels before the first element or after the final element.
'6blic boolean hasPrevio6sElementF G!
'6blic boolean hasMe&tElementF G!
If you wish to find the record I- that the previous methods refer to, use these
methods+
'6blic int ne&t.ecordIdF G thro%s Invalid.ecordI:E&ce'tion!
'6blic int 'revio6s.ecordI:F G thro%s Invalid.ecordI:E&ce'tion!
Dou can obtain the ne6t and previous records themselves using the following
methods+
'6blic b+te34 ne&t.ecordF G thro%s Invalid.ecordI:E&ce'tionJ
.ecordStoreMot@'enE&ce'tionJ .ecordStoreE&ce'tion!
'6blic b+te34 'revio6s.ecordF G thro%s Invalid.ecordI:E&ce'tionJ
.ecordStoreMot@'enE&ce'tionJ .ecordStoreE&ce'tion!
This method returns the current position of the enumeration to the state it was at when
the enumeration was first created+
'6blic void resetF G!
'nd finally, if you want to release all the data that has been stored in the enumeration
in order to gain back the memory used, utili4e the following method+
'6blic void destro+F G!
9&2&@ ,istening to 4ecord 5tores
If you wish to monitor any changes that take place in a record store, you can create an
ob?ect that implements the java&.microedition.rms..ecordListener interface.
This interface contains only three methods+
'6blic inter*ace .ecordListener D
'6blic void recordAddedF.ecordStore recordStoreJ int recordI:G!
'6blic void record.emovedF.ecordStore recordStoreJ int recordI:G!
'6blic void record=odi*iedF.ecordStore recordStoreJ int recordI:G!
H
's you probably guessed, the first method will be called if a record is added, the
second will be called if a record is removed, and the third method will be called if a
record is modified. 'll three methods have the same two parameters. The first is a
reference to the .ecordStore ob?ect, and the second parameter is an integer that
refers to the actual record store I- that was changed.
=nce you3ve created an ob?ect that implements the .ecordListener interface, you
can add or remove it from the list of listeners of a record store by using the following
two methods of the .ecordStore class+
'6blic void add.ecordListenerF.ecordListener listenerG!
'6blic void remove.ecordListenerF.ecordListener listenerG!
9&2&A A 5tock /ata;ase
@ow let3s see how we would use the >M! package to build a stock database. This
e6ample demonstrates how to work with the >M! to build a real MI-let application.
The application builds on the network programming e6perience we gained in Chapter
N and is similar to the Stock=I:let demo that comes with the MI-P. The MI-let for
this e6ample does the following+
Creates a record store (database).
'dds new records (stocks) to the record store.
8iews the stocks in the database.
To add a stock to the database, the user enters the stock symbol (such as !@&, IBM,
IT, M!, <M, or *ord). The MI-let retrieves the corresponding stock 5uote from
DahooC *inance (-ttp:55Fuote.'a-oo.com), constructs a record, and adds it to the
database. To view the stocks in the database, the MI-let iterates through the records
in the record store and prints them on the display in a nice format. The
implementation of this MI-let consists of the following three classes+ Stock.java,
Stock:E.java, and [6otes=I:let.java.
9&2&A&% The 5tock&8ava Class
This class parses a string obtained from DahooC *inance or from the record store into
fields that represent, for e6ample, the name of the stock or its price. The string
returned from DahooC *inance has the following format+
MA=E TI=E P.ICE CHAMWEL@[email protected]/
IS-MWIJI$"LP= 7 8b,RS.RX8)b,IJUP.ONRXJIOV.LNRX 7
L$S.PL$XIJRNJRO.KO$X
In the MI-let shown in 26ample :"#, the fields retrieved are the name of the stock,
the time, and the price.
!6am$le 9+%& Parses a string o;tained from FahooE .inance or from a data;ase
'6blic class Stock D
'rivate static String nameJ timeJ 'rice!
)) Wiven a B6ote *rom the serverJ
)) retrieve the nameJ
)) 'riceJ and date o* the stock
'6blic static void 'arseFString dataG D
int inde& = data.inde&@*F9I9G!
name = data.s6bstringFUUinde&JFinde& = data.
inde&@*F9I9J inde&GGG!
inde& U=P!
time = data.s6bstringFinde&J Finde& = data.
inde&@*F979J inde&GG7LG!
inde& U=X!
'rice = data.s6bstringFinde&J Finde& = data.
inde&@*F989J inde&GGG!
H
)) Wet the name o* the stock *rom
)) the record store
'6blic static String getMameFString recordG D
'arseFrecordG!
ret6rnFnameG!
H
)) Wet the 'rice o* the stock *rom
)) the record store
'6blic static String getPriceFString recordG D
'arseFrecordG!
ret6rnF'riceG!
H
H
9&2&A&2 The 5tock/B&8ava Class
This class provides methods that perform the following operations+
=pens a new record store.
'dds a new record to the record store.
Closes the record store.
2numerates through the records.
=nce you understand how to open a record store, add a new record, and close the
record store, the code in 26ample :"1 is easy to follow.
!6am$le 9+2& Provide methods for record store o$erations
im'ort java&.microedition.rms.C!
im'ort java.6til.En6meration!
im'ort java.6til./ector!
im'ort java.io.C!
'6blic class Stock:E D
.ecordStore recordStore = n6ll!
'6blic Stock:EF G DH
)) @'en a record store %ith the given name
'6blic Stock:EFString *ileMameG D
tr+ D
recordStore = .ecordStore.o'en.ecordStoreF*ileMameJ tr6eG!
H catchF.ecordStoreE&ce'tion rseG D
rse.'rintStackTraceF G!
H
H
)) Close the record store
'6blic void closeF G thro%s .ecordStoreMot@'enE&ce'tionJ
.ecordStoreE&ce'tion D
i* FrecordStore.getM6m.ecordsF G == KG D
String *ileMame = recordStore.getMameF G!
recordStore.close.ecordStoreF G!
recordStore.delete.ecordStoreF*ileMameG!
H else D
recordStore.close.ecordStoreF G!
H
H
)) Add a ne% record FstockG
)) to the record store
'6blic s+nchroniAed void addMe%StockFString recordG D
E+teArra+@6t'6tStream baos = ne% E+teArra+@6t'6tStreamF G!
:ata@6t'6tStream o6t'6tStream = ne% :ata@6t'6tStreamFbaosG!
tr+ D
o6t'6tStream.%rite-T0FrecordG!
H catch FI@E&ce'tion ioeG D
S+stem.o6t.'rintlnFioeG!
ioe.'rintStackTraceF G!
H
b+te34 b = baos.toE+teArra+F G!
tr+ D
recordStore.add.ecordFbJ KJ b.lengthG!
H catch F.ecordStoreE&ce'tion rseG D
S+stem.o6t.'rintlnFrseG!
rse.'rintStackTraceF G!
H
H
)) En6merate thro6gh the records.
'6blic s+nchroniAed .ecordEn6meration en6merateF G thro%s
.ecordStoreMot@'enE&ce'tion D
ret6rn recordStore.en6merate.ecordsFn6llJ n6llJ *alseG!
H
H
9&2&A&0 The GuotesI/let&8ava Class
*inally, the [6otes=I:let class is the actual MI-let that performs the following
tasks+
Create commands (.ist !tocks, 'dd a @ew !tock, Back, !ave, 26it)
Handle command events
Connect to DahooC *inance and retrieve 5uotes
Invoke methods from Stock and Stock:E to parse 5uotes and add new stocks
to the record store
The source for this file is listed in 26ample :"9.
!6am$le 9+0& A I/let for the stock data;ase
im'ort java&.microedition.rms.C!
im'ort java&.microedition.lcd6i.C!
im'ort java&.microedition.midlet.C!
im'ort java&.microedition.io.C!
im'ort java.io.C!
im'ort java.6til./ector!
'6blic class [6otes=I:let e&tends =I:let im'lements CommandListener D
:is'la+ dis'la+ = n6ll!
List men6 = n6ll! )) main men6
List choose = n6ll!
Te&tEo& in'6t = n6ll!
Ticker ticker = ne% TickerFI:atabase A''licationIG!
String B6oteServer =
Ihtt'"))B6ote.+ahoo.com)d)B6otes.csv\s=I!
String B6ote0ormat = IQ*=slcL%o'I! )) The onl+ *ormat s6''orted
static *inal Command backCommand = ne% CommandFIEackIJ
Command.EAC>J KG!
static *inal Command main=en6Command = ne% CommandFI=ainIJ
Command.SC.EEMJ LG!
static *inal Command saveCommand = ne% CommandFISaveIJ
Command.@>J $G!
static *inal Command e&itCommand = ne% CommandFIE&itIJ
Command.ST@PJ PG!
String c6rrent=en6 = n6ll!
)) Stock data
String nameJ dateJ 'rice!
)) record store
Stock:E db = n6ll!
'6blic [6otes=I:letF G D )) constr6ctor
H
)) start the =I:let
'6blic void startA''F G thro%s =I:letStateChangeE&ce'tion D
dis'la+ = :is'la+.get:is'la+FthisG!
)) o'en a db stock *ile
tr+ D
db = ne% Stock:EFIm+stocksIG!
H catchFE&ce'tion eG DH
men6 = ne% ListFIStocks :atabaseIJ Choice.I=PLICITG!
men6.a''endFIList StocksIJ n6llG!
men6.a''endFIAdd A Me% StockIJ n6llG!
men6.addCommandFe&itCommandG!
men6.setCommandListenerFthisG!
men6.setTickerFtickerG!
main=en6F G!
H
'6blic void 'a6seA''F G D
dis'la+ = n6ll!
choose = n6ll!
men6 = n6ll!
ticker = n6ll!
tr+ D
db.closeF G!
db = n6ll!
H catchFE&ce'tion eG DH
H
'6blic void destro+A''Fboolean 6nconditionalG D
tr+ D
db.closeF G!
H catchFE&ce'tion eG DH
noti*+:estro+edF G!
H
void main=en6F G D
dis'la+.setC6rrentFmen6G!
c6rrent=en6 = I=ainI!
H
)) Constr6ct a r6nning ticker
)) %ith stock names and 'rices
'6blic String tickerStringF G D
StringE6**er ticks = n6ll!
tr+ D
.ecordEn6meration en6m = db.en6merateF G!
ticks = ne% StringE6**erF G!
%hileFen6m.hasMe&tElementF GG D
String stockL = ne% StringFen6m.ne&t.ecordF GG!
ticks.a''endFStock.getMameFstockLGG!
ticks.a''endFI ; IG!
ticks.a''endFStock.getPriceFstockLGG!
ticks.a''endFI IG!
H
H catchFE&ce'tion e&G DH
ret6rn Fticks.toStringF GG!
H
)) Add a ne% stock to the record store
)) b+ calling Stock:E.addMe%StockF G
'6blic void addStockF G D
in'6t = ne% Te&tEo&FIEnter a Stock Mame"IJ IIJ XJ
Te&t0ield.AM1G!
in'6t.setTickerFtickerG!
in'6t.addCommandFsaveCommandG!
in'6t.addCommandFbackCommandG!
in'6t.setCommandListenerFthisG!
in'6t.setStringFIIG!
dis'la+.setC6rrentFin'6tG!
c6rrent=en6 = IAddI!
H
)) Connect to B6ote.+ahoo.com and
)) retrieve the data *or a given
)) stock s+mbol.
'6blic String get[6oteFString in'6tG thro%s I@E&ce'tionJ
M6mber0ormatE&ce'tion D
String 6rl = B6oteServer U in'6t U B6ote0ormat!
StreamConnection c = FStreamConnectionGConnector.o'enF
6rlJ Connector..EA:?W.ITEG!
In'6tStream is = c.o'enIn'6tStreamF G!
StringE6**er sb = ne% StringE6**erF G!
int ch!
%hileFFch = is.readF GG T= 7LG D
sb.a''endFFcharGchG!
H
ret6rnFsb.toStringF GG!
H
)) List the stocks in the record store
'6blic void listStocksF G D
choose = ne% ListFIChoose StocksIJ Choice.=-LTIPLEG!
choose.setTickerFne% TickerFtickerStringF GGG!
choose.addCommandFbackCommandG!
choose.setCommandListenerFthisG!
tr+ D
.ecordEn6meration re = db.en6merateF G!
%hileFre.hasMe&tElementF GG D
String theStock = ne% StringFre.ne&t.ecordF GG!
choose.a''endFStock.getMameFtheStockGUI ; I U
Stock.getPriceFtheStockGJn6llG!
H
H catchFE&ce'tion e&G DH
dis'la+.setC6rrentFchooseG!
c6rrent=en6 = IListI!
H
)) Handle command events
'6blic void commandActionFCommand cJ :is'la+able dG D
String label = c.getLabelF G!
i* Flabel.eB6alsFIE&itIGG D
destro+A''Ftr6eG!
H else i* Flabel.eB6alsFISaveIGG D
i*Fc6rrent=en6.eB6alsFIAddIGG D
)) add it to database
tr+ D
String 6serIn'6t = in'6t.getStringF G!
String 'r = get[6oteF6serIn'6tG!
db.addMe%StockF'rG!
ticker.setStringFtickerStringF GG!
H catchFI@E&ce'tion eG D
H catchFM6mber0ormatE&ce'tion seG D
H
main=en6F G!
H
H else i* Flabel.eB6alsFIEackIGG D
i*Fc6rrent=en6.eB6alsFIListIGG D
)) go back to men6
main=en6F G!
H else i*Fc6rrent=en6.eB6alsFIAddIGG D
)) go back to men6
main=en6F G!
H
H else D
List do%n = FListGdis'la+.getC6rrentF G!
s%itchFdo%n.getSelectedInde&F GG D
case K" listStocksF G!break!
case L" addStockF G!break!
H
H
H
H
9&2&9 Testing GuotesI/let
To test [6otes=I:let, use the 01M2 &ireless Toolkit as we have throughout the
book+
#. Create a new pro?ect and compile the code.
1. >un the MI-let in the emulator. Dou should see [6otes=I:let running in the
emulator, as shown in *igure :"#.
.igure 9+%& GuotesI/let
9. 'ctivate [6otes=I:let. Dou should see a menu with the following two
options+ .ist !tocks, and 'dd a @ew !tock, as shown in *igure :"1.
.igure 9+2& GuotesI/let stock data;ase
E. Choose the 'dd a @ew !tock option and add a few stocks. *igure :"9 shows
that the stocks IBM, <M, and @=> were added in this e6ample.
.igure 9+0& Adding new stocks
;. <o back and choose the 8iew !tocks option. *igure :"E shows that this option
reads the record store and retrieves all the records (stocks) that have been
added.
.igure 9+2& -iewing the record store
Have fun keeping track of your stocksC In the ne6t chapter, we will discuss how to
install MI-lets such as this on Palm computing platforms.
Cha$ter C& The I/P for Palm '5
'n early access release of the MI-P for Palm =! was released ?ust before 0ava=ne
1%%#, in early 0une, and the *irst Customer !hipping (*C!) of the MI-P for Palm =!
#.% was released in mid"=ctober, 1%%#. The MI-P for Palm =! is a 01M2 application
runtime environment based on the C.-C #.% and MI-P #.% specifications. It is
targeted at handheld devices (such as Palm Pilot, Handspring 8isor, and so on)
running Palm =! version 9.; or higher.
This chapter e6plains how to install the MI-P for Palm =! on your handheld device,
and then how to convert e6isting MI-lets, developed in earlier chapters, into Palm
>esource Code (P>C) files (e6ecutable Palm =! applications). The 01M2 &ireless
Toolkit #.%.9 supports the MI-P for Palm =!. Hence, it is possible to test MI-lets
using a Palm =! device, as shown in Chapter E.
C&% Installing the I/P for Palm '5on the (indows Platform
To install the MI-P for Palm =!, you need to perform the following steps+
#. -ownload the MI-P for Palm =!. This package (midpGpalm08H?.Iip), which
is less than one megabyte, is the early access release of the MI-P for Palm =!
implementation. Dou can download it from the 0ava web site at
http+,,?ava.sun.com,products,midpEpalm.
1. n4ip the package. -o this in the root directory C:\. This gives you a new
folder called midpGpalm8.? that contains tools and sample applications. Check
to make sure you have a file called M,D=.prc in the =4Cfiles directory, which
is the application runtime environment that supports the MI-P for Palm =!.
't this point, you are ready to install the MI-P for Palm =! on your Palm device.
C&%&% Installing the I/P for Palm '5 on the /evice
se the Hot!ync application that came with the PalmPilot to install the M,D=.prc on
your Palm =! device.
#. Place your Palm device in the cradle.
1. sing your Palm -esktop software on the PC (or a similar program), click the
Install icon and browse to C:\midpGpalm8.?\=4Cfiles to select M,D=.prc, as
shown in *igure $"#. Press the Hot!ync button on the cradle to install the file.
.igure C+%& Using Palm /eskto$ to install I/P&$rc
9. <o to the application directory on your Palm and check to see if the 0ava HU
is there. The 0ava HU is the application runtime environment that supports the
MI-P for Palm =!. @ote that the 0ava Manager environment takes up roughly
F%%7 of your Palm =! device3s storage.
Dou should see the 0ava HU icon, as shown in *igure $"1. If you do not see it, click on
another application (e.g., Calculator) and then go back to the application directory to
reset the display.
.igure C+2& Java *G s$ecial icon on Palm
If you tap the 0ava HU icon, you3ll see the 'bout screen, as shown in *igure $"9. This
contains the copyright notice and gives you the option to change the 0ava HU
preferences that apply to every 0ava application running on the device. More
information on the 0ava HU preference settings is presented later in this chapter.
.igure C+0& Java *G A;out screen
@ow you are ready to install other 0ava applications on your Palm.
C&%&2 4unning 5am$le A$$lications
There are several applications for the Palm that are written in 0ava and that come with
the software you ?ust installed. 'll the files with the .prc e6tension in the directory
C:\midpGpalm8.?\=4Cfiles are MI-P"based 0ava applications for the Palm. Dou can
use the Hot!ync to install them.
's an e6ample, use the Hot!ync and install the files )ames.prc and Demos.prc. =nce
you have installed these two files, you will see two new icons, as shown in *igure $"E.
.igure C+2& Installing sam$le I/P+;ased Java a$$lications
' MI-P"based 0ava application for the Palm runs ?ust like any other Palm application.
!imply tap the corresponding icon. @ote that the 0ava HU must already be installed.
&hen you launch a 0ava application on the Palm, the 0ava HU (which is e5uivalent to
the application manager) runs automatically. 'lso, it is important to note that the first
time you launch an application, you are asked to read and accept the MI-P licenseA
the application starts automatically once you tap 'ccept, as shown in *igure $";.
.igure C+3& 4unning Java a$$lications on the Palm for the first time
If you open an application suite (such as -emos), you are prompted to choose which
application you want to run, as shown in *igure $"F. !elect an application to run by
tapping on its arrow.
.igure C+@& 5electing an a$$lication to run from a suite
C&2 /evelo$ing >ew A$$lications
Dou can easily develop new 0ava applications for the Palm if you are familiar with the
MI-let programming model. If you have run the MI-lets in earlier chapters, or have
developed new ones, you can easily turn them into Palm applications by using a
converter tool, which we will describe later in this chapter. The development life cycle
of a Palm application can be summari4ed in the following three steps+
#. -evelop a MI-let or a MI-let suite.
1. Convert the 0'>,0'- file pair into a P>C file (e6ecutable Palm application).
9. Install the P>C file on the Palm and test the application.
C&2&% /evelo$ a I/let
's always, you can use either the !un Microsystems &ireless Toolkit or your favorite
development environment to develop a MI-let. 26ample $"# lists the MI-let that was
developed in Chapter F, which shows how to create various <I components. The
MI-let for this e6ample allows you to test lists, forms, choices, gauges, te6t fields,
and te6t bo6es.
!6am$le C+%& ?uiTests&8ava
im'ort java&.microedition.lcd6i.C!
im'ort java&.microedition.midlet.C!
'6blic class W6iTests e&tends =I:let im'lements CommandListener D
)) dis'la+ manager
:is'la+ dis'la+ = n6ll!
)) a men6 %ith items
List men6 = n6ll! )) main men6
)) list o* choices
List choose = n6ll!
)) te&tbo&
Te&tEo& in'6t = n6ll!
)) ticker
Ticker ticker = ne% TickerFITest W-I Com'onentsIG!
)) alerts
*inal Alert so6ndAlert = ne% AlertFIso6nd AlertIG!
)) date
:ate0ield date = ne% :ate0ieldFIToda+9s date" IJ
:ate0ield.:ATEG!
)) *orm
0orm *orm = ne% 0ormFI0orm *or St6**IG!
)) ga6ge
Wa6ge ga6ge = ne% Wa6geFIProgress EarIJ *alseJ $KJ SG!
)) te&t *ield
Te&t0ield te&t*ield = ne% Te&t0ieldFITe&t0ield LabelIJ IabcIJ
XKJ KG!
)) command
static *inal Command backCommand = ne% CommandFIEackIJ
Command.EAC>J KG!
static *inal Command main=en6Command = ne% CommandFI=ainIJ
Command.SC.EEMJ LG!
static *inal Command e&itCommand = ne% CommandFIE&itIJ
Command.ST@PJ $G!
String c6rrent=en6 = n6ll!
)) constr6ctor.
'6blic W6iTestsF G D
H
)CC
C Start the =I:let b+ creating a list o* items and associating
C the e&it command %ith it.
C)
'6blic void startA''F G thro%s =I:letStateChangeE&ce'tion D
dis'la+ = :is'la+.get:is'la+FthisG!
)) o'en a db stock *ile
men6 = ne% ListFITest Com'onentsIJ Choice.I=PLICITG!
men6.a''endFITest Te&tEo&IJ n6llG!
men6.a''endFITest ListIJ n6llG!
men6.a''endFITest AlertIJ n6llG!
men6.a''endFITest :ateIJ n6llG!
men6.a''endFITest 0ormIJ n6llG!
men6.addCommandFe&itCommandG!
men6.setCommandListenerFthisG!
men6.setTickerFtickerG!
main=en6F G!
H
'6blic void 'a6seA''F G D
dis'la+ = n6ll!
choose = n6ll!
men6 = n6ll!
ticker = n6ll!
*orm = n6ll!
in'6t = n6ll!
ga6ge = n6ll!
te&t*ield = n6ll!
H
'6blic void destro+A''Fboolean 6nconditionalG D
noti*+:estro+edF G!
H
)) main men6
void main=en6F G D
dis'la+.setC6rrentFmen6G!
c6rrent=en6 = I=ainI!
H
)CC
C Test the Te&tEo& com'onent.
C)
'6blic void testTe&tEo&F G D
in'6t = ne% Te&tEo&FIEnter Some Te&t"IJ IIJ LKJ
Te&t0ield.AM1G!
in'6t.setTickerFne% TickerFITesting Te&tEo&IGG!
in'6t.addCommandFbackCommandG!
in'6t.setCommandListenerFthisG!
in'6t.setStringFIIG!
dis'la+.setC6rrentFin'6tG!
c6rrent=en6 = Iin'6tI!
H
)CC
C Test the List com'onent.
C)
'6blic void testListF G D
choose = ne% ListFIChoose ItemsIJ Choice.=-LTIPLEG!
choose.setTickerFne% TickerFITesting ListIGG!
choose.addCommandFbackCommandG!
choose.setCommandListenerFthisG!
choose.a''endFIItem LIJ n6llG!
choose.a''endFIItem $IJ n6llG!
choose.a''endFIItem PIJ n6llG!
dis'la+.setC6rrentFchooseG!
c6rrent=en6 = IlistI!
H
)CC
C Test the Alert com'onent.
C)
'6blic void testAlertF G D
so6ndAlert.setT+'eFAlertT+'[email protected]!
))so6ndAlert.setTimeo6tF$KG!
so6ndAlert.setStringFICC E..@. CCIG!
dis'la+.setC6rrentFso6ndAlertG!
H
)CC
C Test the :ate0ield com'onent.
C)
'6blic void test:ateF G D
java.6til.:ate no% = ne% java.6til.:ateF G!
date.set:ateFno%G!
0orm * = ne% 0ormFIToda+9s dateIG!
*.a''endFdateG!
*.addCommandFbackCommandG!
*.setCommandListenerFthisG!
dis'la+.setC6rrentF*G!
c6rrent=en6 = IdateI!
H
)CC
C Test the 0orm com'onent.
C)
'6blic void test0ormF G D
*orm.a''endFga6geG!
*orm.a''endFte&t*ieldG!
*orm.addCommandFbackCommandG!
*orm.setCommandListenerFthisG!
dis'la+.setC6rrentF*ormG!
c6rrent=en6 = I*ormI!
H
)CC
C Handle events.
C)
'6blic void commandActionFCommand cJ :is'la+able dG D
String label = c.getLabelF G!
i* Flabel.eB6alsFIE&itIGG D
destro+A''Ftr6eG!
H else i* Flabel.eB6alsFIEackIGG D
i*Fc6rrent=en6.eB6alsFIlistIG 55
c6rrent=en6.eB6alsFIin'6tIG 55
c6rrent=en6.eB6alsFIdateIG 55
c6rrent=en6.eB6alsFI*ormIGG D
)) go back to men6
main=en6F G!
H
H else D
List do%n = FListGdis'la+.getC6rrentF G!
s%itchFdo%n.getSelectedInde&F GG D
case K" testTe&tEo&F G!break!
case L" testListF G!break!
case $" testAlertF G!break!
case P" test:ateF G!break!
case V" test0ormF G!break!
H
H
H
H
C&2&2 Convert a I/let into a P4C file
This section will e6plain how to convert a MI-let file into a P>C file. *irst, build the
MI-let in 26ample $"# and make sure there are no compilation errors. Most
development tools will create the 0'> and 0'- files for you automatically. These are
the two files needed to convert a MI-let or a MI-let suite into a P>C file. If you are
using the &ireless Toolkit, the 0'> and 0'- files can be found in the &in directory of
your pro?ect.
The MI-P for Palm =! comes with a converter tool to convert a MI-let 0'>,0'-
into an e6ecutable Palm application. To run the P>C converter tool, you can use the
batch file distributed with the release. However, if you have set the JJH(#ME
environment variable on your desktop, edit the C#DJE4"E4.%" file and change all
the JJH="( references to JJH(#ME. Then run the converted batch file.
'lternatively, you can run the tool using the command+
C"#mid'V'almL.K#converter, java 7jar Converter.jar
The converter.jar archive contains the implementations for the P>C converter tool. If
the above command runs successfully, you should see a window similar to *igure $"N.
.igure C+A& P4C converter tool
@ow, select Convert from the *ile menu, and navigate to the directory where the 0'-
and 0'> files are located (as with deployment on the Motorola i:;s and the i;%6, they
must be in the same directory). !elect the 0'- file to be converted, then click on the
Convert button to convert the file into a P>C file. If everything is okay, you will see a
success message, as shown in *igure $":.
.igure C+9& Converting JA/=JA4 to P4C
By default, the converted P>C file will be saved in the same directory as the
0'-,0'> file pair. If you like, you can save all converted P>C files under another
directory by choosing Preferences from the Converter3s *ile menu. Then you can
select a folder of your choice for output.
C&2&0 Install and Test
=nce the 0'-,0'> file pair have been converted to a P>C file, you can install the
P>C file on your Palm =! device using Hot!ync. =nce installed, you can run it and
select components to test, as shown in *igure $"$. Here, we have tested a form with a
progress bar, a te6t field, an alert, and a date.
.igure C+C& Testing a I/P a$$lication for the Palm '5
C&0 P4C Command+,ine Conversion
The P>C <I"based converter tool is easy to use. However, this comes at the e6pense
of functionality. *or e6ample, what if you wish to associate a new icon with your
application rather than have the default iconL Dou can use the command"line converter
to complete this and other tasks.
The MI-P for Palm =! distribution comes with a command"line tool for converting
0'> files to P>C files. The tool is the MakeM,D=pp, which is part of the
converter.jar archive. To run this converter, use the command+
C"#midV'almL.K#converter, java 7c' converter.jar
com.s6n.mid'.'alm.database.=ake=I:PA''
3o'tions4 <A.*ile
The options for this command are shown in Table $"#+
Ta;le C+%& Command+line P4C converter tool o$tions
"ption Description
7v 8erbose output
"v "v More information
7verbose !ame as 7v
7icon 8*ile,
*ile containing icon (in bmp, pbm, or bin Palm resource format) for the list
viewof the application
7smallicon
8*ile,
*ile containing a small icon for the Palm =! device3s icon view
7name 8name, !hort name for the application, for the Palm =! device3s icon view
7longname
8name,
.ong name for the application, for Palm =! device list view
7creator 8crid, Creator I- for the application
7t+'e 8t+'e, Type file for the application (default is appl)
7o6t*ile 8*ile, @ame of the P>C file to create
7o 8*ile, !ame as 7o6t*ile
7version
8string,
Change version
7hel' Print help information
7jad 8<A:*ile, ' 0'- file is specified (MI-let suite packaging)
&ith the command"line tool, you can produce P>C files from a single MI-let or from
a MI-let suite. *or e6ample, the following command can be used to convert a 0'>
file (containing one MI-let or a MI-let suite) to a P>C file+
C"#mid'V'almL.K#converter, java 7c' Converter.jar
com.s6n.mid'.database.=ake=I:PA'' 7t+'e
:ata g6i.jar
This command will produce a P>C file called gui.prc from the 0'> file gui.jar. @ote
that the type of application being converted can be either a''l ot :ata (case"
sensitive). If you don3t provide the 7t+'e option, then =ake=I:PA'' uses the default
type, which is a''l. It is important to note, however, that if you don3t provide a
creator I- with the 7creator option, you must set the type to :ata. The creator I-
specifies the uni5ue, four"character identifier for a Palm application. 2very Palm
application must have a creator I-, and if you do not provide one, then =ake=I:PA''
will automatically generate a creator I- for your application. To find out the creator
I-, use the 7v 7v option.
'ny application converted using the <I"based converter tool or the command"line
tool is, by default, not beamable from the Palm launcher screen, as shown in *igure $"
#%. If you use the command"line tool, however, and provide a creator I-, then the
application will be beamable.
.igure C+%D& An a$$lication cannot ;e ;eamed ";< default#
C&2 Advanced Java A$$lications
Dou have seen how to develop a simple 0ava application for the Palm that creates
various <I components. &hat about advanced applications that use networking and
databasesL &ell, the MI-P for Palm =! supports all the MI-P features, including the
<eneric Connection *ramework and the >M!. !o, now let3s look at a couple of
sample applications developed in Chapter N and Chapter :.
*irst, however, there are two things that need to be set if you want to test network"
based applications from the Palm =! 2mulator (P=!2).
#. >edirect @etlib calls to host TCP,IP. To do this, right"click on the P=!2
window, select !etting Properties, and check the >edirect @et.ib calls to
host TCP,IP, as shown in *igure $"##.
.igure C+%%& P'5! $ro$ert< settings
1. 2nable @etworking. To do this, tap the 0ava HU icon, then tap Preferences and
select @etworking 2nabled, as shown in *igure $"#1.
.igure C+%2& Java *G networking $references
The 0ava HU allows you to set special preferences. *or e6ample, it allows you to set
how much memory is used to run 0ava applications, how many colors are used, the
drawing speed, how your device will connect to the Internet, and how the controls
should be displayed on the screen. Dou can easily set all of these options using the
0ava HU. However, if you are running an application and would like to set some
preferences, select the Preferences item from the =ptions menu. Dou can choose
whether you want to set 'pplication preferences, <lobal preferences, or 0ava HU
preferences, as shown in *igure $"#9. 'pplication preferences affect only the 0ava
application you are runningA <lobal preferences affect every 0ava application running
in your device.
.igure C+%0& Preference settings for the Java *G and its a$$lications
C&2&% .etching a Page Using *tt$Connection
In Chapter N, a MI-let was developed to retrieve the contents of a file from a remote
server using the HttpConnection interface. The MI-let that implements this
functionality is :econdE3ample.java. Create a new pro?ect in the &ireless Toolkit and
use :econdE3ample.java as its source file. Build it, locate the 0'> and 0'- files, and
use the P>C converter tool to convert them into a P>C file. Install the P>C file on
P=!2 and then run the application. If all goes well, you should see something similar
to *igure $"#E.
.igure C+%2& 4etrieving a file from a remote server
C&2&2 4etrieving 5tock Guotes and (orking with /ata;ases
In Chapter :, a MI-let was developed that allows you to create a database, add stocks
(which are retrieved from DahooC *inance) to the database, and view the database.
-ownload the files :tock.java, :tockD%.java, and EuotesM,Dlet.java. Build the
application and create the 0'> and 0'- file pair. Then use the P>C converter tool to
produce a P>C file. Install the P>C file on P=!2 and then run it. 'dd a few stocks
and then view the stocks from the database. If everything goes well, you should see
something similar to *igure $"#;.
.igure C+%3& 5tock Buotes
C&3 A .inal Thought
The Palm =! implementation of MI-P provides a runtime environment and tools that
allow you to convert your MI-lets into Palm applications without writing a single
line of code. I do not know of any easier way to develop fully functional 0ava
applications for the Palm. These applications can be used ?ust like any other Palm
applicationA they run like any Palm program and can be removed from your Palm =!
device the same way that you would remove any other application. However, it
remains to be seen whether the MI-P for Palm =! is here to stay, or if it will be
superseded by the P-' Profile for 01M2, which is based on the C.-C and will
provide user interface and data storage 'PIs for handheld devices. 's of this writing,
the P-' profile is still in the works and no reference implementation is available.