|
|||||||||
PREV NEXT | FRAMES NO FRAMES |
See:
Description
Packages | |
javax.microedition.global | Contains classes that implement the JSR-238, "Mobile Internationalization API". |
This document defines JSR-238, the Mobile Internationalization API, version 1.0.
Author: JSR-238 Expert Group (e-mail: [email protected])
Status: Final Specification
Released: 2005-02-15
Copyright © 2004-2005 Nokia Corporation. All rights reserved.
Version | Published | Description |
---|---|---|
0.1 | 2004-04-20 | API proposal, revision 1 |
0.2 | 2004-05-04 | First EG internal Community Review Draft |
0.3 | 2004-05-24 | Second EG internal Early Draft |
0.4 | 2004-06-02 | Submitted to JCP Early Draft Review with updated license |
0.5 | 2004-08-25 | First EG internal Public Draft |
0.6 | 2004-10-04 | Second EG internal Public Draft |
0.7 | 2004-10-15 | Public Review Draft |
0.8 | 2004-11-29 | Proposed Final Draft Candidate 1 |
0.9 | 2004-12-08 | Proposed Final Draft Candidate 2 |
0.9.1 | 2004-12-14 | Proposed Final Draft |
0.9.4 | 2005-02-02 | Final Specification, Release Candidate 1 |
0.9.5 | 2005-02-11 | Final Specification, Release Candidate 2 |
1.0 | 2005-02-15 | Final Specification |
NOKIA CORPORATION IS WILLING TO LICENSE THIS SPECIFICATION TO YOU ONLY UPON THE TERMS CONTAINED IN THIS LICENSE ("LICENSE"). PLEASE READ THE TERMS AND CONDITIONS OF THIS LICENSE CAREFULLY. BY ACCESSING OR USING THE SPECIFICATION YOU WILL BE BOUND BY THE TERMS OF THIS LICENSE.
JSR-238 Mobile Internationalization API Specification ("Specification")
Specification Lead: Nokia Corporation ("Specification Lead")
1. NOTICE; LIMITED LICENSE GRANTS
1.1 The Specification Lead hereby grants You a non-exclusive, non-transferable, worldwide, royalty-free, fully paid-up, limited license (without the right to sublicense) solely under intellectual property rights licensable by the Specification Lead to analyze and to use the Specification for research, evaluation, optimization and development purposes. In addition You may make a reasonable number of verbatim copies of this Specification in its entirety for Your private or internal use, as applicable, in accordance with the terms and conditions of this License.
1.2 No rights are granted under this License for internal deployment, the creation and/or distribution of implementations of the Specification for direct or indirect (including strategic) gain or advantage, the modification of the Specification (other than to the extent of Your fair use rights) or the distribution of the Specification or making the Specification available for 3rd parties.
1.3 Except as expressly set forth in this license, You acquire no right, title or interest in or to Specification or any other intellectual property licensable by the Specification Lead and no other rights are granted by implication, estoppel or otherwise. The Specification may only be used in accordance with the license terms set forth herein. This License will terminate immediately without notice from Specification Lead if You fail to comply with any provision of this License.
2. TRADEMARKS
2.1 Nokia is a registered trademark of Nokia Corporation. Nokia Corporation's product names are either trademarks or registered trademarks of Nokia Corporation. Your access to this Specification should not be construed as granting, by implication, estoppel or otherwise, any license or right to use any marks appearing in the Specification without the prior written consent of Nokia Corporation or Nokia's licensors. No right, title, or interest in or to any trademarks, service marks, or trade names of any third parties, is granted hereunder.
2.2 You shall not be allowed to remove any of the copyright statements or disclaimers or other proprietary notices contained in the Specification and You are obliged to include the copyright statement and the disclaimers, if any, in any copies of the Specification You make.
3. DISCLAIMER OF WARRANTIES
3.1 SUBJECT TO ANY STATUTORY WARRANTIES OR CONDITIONS WHICH CAN NOT BE EXCLUDED, THE SPECIFICATION IS PROVIDED "AS IS" WITHOUT WARRANTY OR CONDITION OF ANY KIND EITHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OR CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, AND STATUTORY ARE HEREBY DISCLAIMED. THE ENTIRE RISK ARISING OUT OF OR RELATING TO THE USE OR PERFORMANCE OF THE SPECIFICATION REMAINS WITH YOU.
3.2 THE SPECIFICATION MAY INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION THEREIN; THESE CHANGES WILL BE INCORPORATED INTO NEW VERSIONS OF THE SPECIFICATION, IF ANY. SPECIFICATION LEAD MAY MAKE IMPROVEMENTS AND/OR CHANGES TO THE PRODUCT(S) AND/OR THE PROGRAM(S) DESCRIBED IN THE SPECIFICATION AT ANY TIME. Any use of such changes in the Specification will be governed by the then-current license for the applicable version of the Specification.
4. LIMITATION OF LIABILITY
4.1 TO THE FULLEST EXTENT PERMITTED BY LAW, IN NO EVENT WILL THE SPECIFICATION LEAD OR ITS SUPPLIERS BE LIABLE FOR ANY LOST PROFITS, LOST SAVINGS, LOST REVENUE, LOST DATA, PROCUREMENT OF SUBSTITUE GOODS, OR FOR ANY DIRECT, INDIRECT, INCIDENTIAL, SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES, EVEN IF THE SPECIFICATION LEAD OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES OR DAMAGES. IN ADDITION THE SPECIFICATION LEAD AND ITS SUPPLIERS WILL NOT BE LIABLE FOR ANY DAMAGES CLAIMED BY YOU BASED ON ANY THIRD PARTY CLAIM.
4.2 Some jurisdictions do not allow the exclusion of implied warranties, or the limitation for consequential damages, so Section 4.1 may not apply to You in whole, but in such case Section 4.1 will apply to You to the maximum extent permitted by applicable law.
5. EXPORT CONTROL
5.1 You shall follow all export control laws and regulations relating to Specification.
6. RESTRICTED RIGHTS LEGEND
6.1 Note to U.S. Government Users. The Specification is a "Commercial Items", as that term is defined at 48 C.F.R. 2. 101, consisting of "Commercial Computer Software" and "Commercial Computer Software Documentation", as such terms are used in 48 C.F.R. 12.212 or 48 C.F.R. 227.7202, as applicable. Consistent with 48 C.F.R. 12.212 or 48 C.F.R. 227.7202-1 through 227.7202-4, as applicable, the Commercial Computer Software Documentation are being licensed to U.S. Government end users a) only as Commercial Items and b) with only those rights as are granted to all other end users pursuant to the terms and conditions herein. Unpublished-rights reserved under the copyright laws of the United States.
This specification was produced by the JSR-238 Expert Group in the Java Community Process (JCP). For more information, visit the JSR-238 web page.
The Expert Group consisted of representatives from the following companies (in alphabetical order):
Cap Gemini
Esmertec AG
IBM Corporation
Nokia Corporation
Research In Motion, LTD (RIM)
Siemens AG
Sun Microsystems, Inc.
Symbian Ltd.
Your comments about this specification are welcome. Please send them by electronic mail to the following address:
<[email protected]>
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" and "OPTIONAL" in this specification are to be interpreted as described in RFC 2119 (see "Related documentation").
Monospaced type is used to denote literal text such as /global
and constants such as DEVICE
and 0x7FFFFFFF
.
Unicode characters are expressed in the U+NNNN notation, where NNNN denotes a 16-bit hexadecimal code point.
This specification defines Mobile Internationalization API, a J2ME Optional Package containing an application program interface that allows MIDP application developers to internationalize their MIDP applications. Internationalization is a prerequisite to localization, both very important in multilingual software development.
The API provides the locale-specific formatting of dates, times, numbers (including percentages) and currency amounts. It is also possible to construct messages that have a variable number of ordered parameters. Furthermore, the API defines a mechanism to retrieve application-specific and device-specific resources, and provides services for the locale-specific collation (sorting) of strings.
Mobile Internationalization API is designed as an Optional Package, intended to be used with the Mobile Information Device Profile (MIDP) running over the Connected, Limited Device Configuration (CLDC). The implementation should also work in the Connected Device Configuration (CDC) and MAY be implemented using it. For more information, see the System requirements section.
All classes in this API are in a single package,
javax.microedition.global
.
The goal of the Mobile Internationalization API is to provide internationalization services to Java MIDlets running in MIDP over CLDC. While Java 2, Standard Edition provides extensive support for internationalization, this support has not been included in the more limited configurations and profiles of Java 2, Micro Edition.
This API is designed to provide its services in a compact and generic form. It augments the MIDP application platform by bringing MIDP applications to a similar level with desktop applications in terms of internationalization.
The underlying configuration MUST be CLDC 1.1 or later, due to the inclusion of
floating point numeric formatting. The CLDC 1.1 implementation SHOULD support the "mark and reset" functionality
for input streams. (See the documentation of CLDC's java.io.InputStream
class for details.) This ensures that the binary resource files used by this API
can be read more efficiently. CLDC 1.1 also implies support for the characters in Unicode 3.0 or later.
The version of MIDP used MUST be 2.0 later.
That version of MIDP defines the format of the microedition.locale
system property more accurately than version 1.0, and contains user interface components
to facilitate the entry of common data items in a locale-specific manner. It also
requires character encoding support for UTF-8.
If the underlying operating system provides services for Unicode collation and other related internationalization functionality, implementations of this API SHOULD take advantage of those services.
This API is implementable in CDC. Most features can be implemented in CDC by mapping the functionality to the CDC subset of the J2SE libraries.
Applications MUST be able to determine the version of Mobile Internationalization
API present in the device, if any, by querying the value of the system
property microedition.global.version
. For version 1.0 of
the API the value returned MUST be the string "1.0"
. If Mobile
Internationalization API is not present, the value
returned MUST be null
.
Some internationalization features, particularly Unicode collation, can be challenging to implement in a constrained device. However, many operating systems that have implementations of J2ME configurations already have some required basic functionality. It is therefore advisable that implementations of this API rely on this existing functionality as much as possible, and attempt to map this API into native functionality.
Implementers are also encouraged to evaluate the suitability of the data available from the Common Locale Data Repository (CLDR) Project (see "Related documentation") for their purposes when implementing locale-specific formatting and Unicode collation.
A locale is a combination of a language and a country or region. It is used in internationalization as a label for conventions that are typical for speakers of the language in the country or region.
In the Mobile Internationalization API locales are used to distinguish between different resources, data formatting conventions and string comparisons. Many classes in the API have methods taking a locale parameter that affects the behaviour of the class.
In the Mobile Internationalization API locale identifiers are simple strings.
They MUST follow the format of locale identifiers found in Chapter 5 of the MIDP 2.0 specification,
unless the identifier is the empty string. MIDP 2.0 locale identifiers
consist of an ISO 639-1 two-letter language code, an ISO 3166-1 two-letter country code, and
a variant code. If the value is non-null
, only the language code is mandatory.
For application resource files handled by this API, the empty string as a locale identifier has a special meaning, as discussed in the "Resource files" section. When formatting data items or sorting strings using an empty locale triggers locale-neutral behaviour (see the respective class descriptions).
For robustness and compatibility with J2SE, methods taking locale identifiers as parameters MUST accept both underscore (U+005F) and dash (U+002D). However, application programmers SHOULD use only the dash.
Note that many classes in this API use the value of the microedition.locale
system property as the default locale unless something else is specified.
As the MIDP specification allows this value to have the null
value,
some classes revert to a locale-neutral behaviour in such situations.
Resources are application data that is typically localized. When the application is run, a different resource may be loaded for the same identifier, depending on the current locale setting of the runtime system and the organization of the application resources. Each resource has an identifier that is used when loading the resource at runtime.
Mobile Internationalization API has two different resource categories:
application resources and device resources.
The ResourceManager
class is used to access both application resources
and device resources. Application resources are supplied
by the developer and shipped with the application, whereas device resources
have already been made available by the device manufacturer.
The set of device resources varies by manufacturer and is not in the scope of this API. Instead device manufacturers should define the appropriate public resources and their identifiers for application developers to use. The storage format of device resources is implementation-specific.
The application programmer can group related application resources together by using a base name. In this context it is a non-empty string that is used in the names of application resource files to indicate that they belong together. The base name can reflect anything the application developer wants, such as menu commands or messages.
If the base name is empty, it refers to device resources. For these resources there is no application resource file, but instead the manufacturer-defined resources are consulted.
Application developers SHOULD restrict the characters used in the base names to the ASCII character set. The JAR file specification does not explicitly state the character encoding used in the file names, and many utilities have problems with non-ASCII characters.
Application resources MUST be stored inside the application's JAR file. They MUST be in the binary resource file format defined by this specification (see the section "The binary resource file format").
The organization of the application resource files inside the JAR file MUST
be as follows. The JAR file MUST contain a special directory named '/global
'
to store the resource files. This directory MUST contain a subdirectory for
each supported locale. The directory names MUST be valid MIDP 2.0 locale identifiers.
Resource files specific to some locale MUST be placed inside the corresponding
locale subdirectory under /global
, whereas common resources
MUST be placed in the /global
directory. The names of the
resource files MUST be of the form 'baseName.res
',
where baseName
is the base name used in the ResourceManager
constructors.
For example, the absolute pathname of a resource file inside the JAR might be
'/global/en/Menus.res
' or '/global/fi-FI/Menus.res
'
for resources specific to locales en
and fi-FI
.
In the case of common resources the filename might be '/global/Common.res
'.
The following diagram illustrates this arrangement:
JAR file root | | +----global----Common.res | | +----fi-FI----Menus.res | Labels.res | en-------Menus.res | Labels.res | de-DE----Menus.res Labels.res
This example contains seven resource files inside the JAR file, with absolute
filenames such as /global/Common.res
,
/global/fi-FI/Menus.res
, and so on.
Often it is advantageous to collect together elements that do not change from one locale to another. For example, you can save storage by placing into a common resource file those resources that could change but will never be translated.
According to the MIDP 2.0 specification, if the microedition.locale
system property is present at all (i.e. it is non-null
),
it always contains the language part. To implement the common locale this API extends the
MIDP 2.0 definition so that an empty locale identifier points
to common resource files placed in the '/global
' directory.
These files MUST conform to the same naming rules as the locale-specific resources.
The resource retrieval mechanism MUST also support resource inheritance;
if a resource is not found using the specified locale identifier, it is searched again with the
last component of the locale identifier removed, until a match is found or it is
determined that the resource is not found even in the common locale.
For an in-depth description of the inheritance mechanism see the ResourceManager
class description.
Note that the directory and file names inside the JAR are case-sensitive.
The ResourceManager
class has a static method
getSupportedLocales
to determine which locales are supported
for a given base name. For device resources this information MUST be provided by the
implementation. For application resources the application JAR file MUST contain a meta-information file
for each base name, called 'global/_baseName
'.
The meta-information
mechanism avoids repeated lookups of resource files from inside the JAR file.
Each meta-information file lists the supported locales for the corresponding base name. The file MUST contain the locale identifiers of the locales supported for that base name, separated by one blank space (U+0020). These files SHOULD be generated along with the binary resource files.
If the contents of the meta-information file for some base name do not
agree with the actual resource files inside the JAR file, the effect MUST
be as follows when attempting to instantiate a ResourceManager
for that
base name and the requested locale:
If the meta-information file lists the locale, but no
resource file for the combination of base name and locale exists, the
attempt MUST throw a ResourceException
with the error code
NO_RESOURCES_FOR_BASE_NAME
.
If the meta-information file does not list the locale,
the attempt MUST throw an UnsupportedLocaleException
,
even if a resource file for the combination of base name and locale exists.
For example, if the JAR file contains application resource files for the base name Menus
for the Finnish, Hungarian and Brazilian Portuguese locales, the file global/_Menus
would
contain the following:
fi-FI hu-HU pt-BR
Values in the meta-information file MAY be quoted using U+0022 QUOTATION MARK,
for example "fi-FI"
. If there are common resources for the base name, the
file MUST include the empty string. The empty string MUST
be quoted and it SHOULD be the first value in the file.
In the previous example, if the base name Menus
had also common
resources, the meta-information file _Menus
would contain
"" fi-FI hu-HU pt-BR
This is equivalent to
"" "fi-FI" "hu-HU" "pt-BR"
If the meta-information file for the specified base name is not found,
the getSupportedLocales
method MUST throw a
ResourceException
with
the error code METAFILE_NOT_FOUND
.
This section describes the structure of the binary resource file format of Mobile Internationalization API. To be accessible using this API, resource files shipped with applications MUST be in this format.
Each resource in the resource file MUST have an associated ID,
with a value of between 0x00000000
and
0x7FFFFFFF
(inclusive). The resource IDs
MUST be unique inside one resource file. However, the same resource ID
can occur in other resource files with the same base name but different
locales. This allows resource inheritance as discussed in the
ResourceManager
class description.
All resources are stored
as byte arrays. Being the most common resources, strings
are a special case in the API. The string data MUST be encoded in UTF-8.
Other resources are stored as raw data, and the meaning of the data is
application-specific. For example, it could be PNG image data passed to
the createImage
method of
the LCDUI Image
class.
The resource file format consists of the following:
4-byte signature;
header length;
file header;
the resource data
The first byte of the signature MUST be 0xEE
(the number
238 expressed in hexadecimal),
the second and third bytes MUST be 0x4D
and
0x49
(the characters 'M' and 'I' in UTF-8 encoding),
and the fourth byte MUST contain the file format and API version. The top four bits
of the version represent the major version, while the bottom four bits are the minor version.
The minor and major versions MUST follow the version of the API specification. For example,
in resource files intended for this version of the API (1.0) the version byte is
0x10
.
The header length is expressed in bytes. The length MUST NOT include the 4-byte signature.
The file header MUST contain a table of 64-bit entries, one for each resource. The entries combine the following components into one value: the resource ID, the resource type, and the byte offset of the resource from the start of the file. The top 32 bits of the entry MUST contain the resource ID. The bottom 32 bits of the entry MUST contain the combined type and offset, with top eight bits representing the type, and the remaining 24 bits representing the byte offset from the start of the file. The lengths of the resource blocks are calculated from the byte offsets. The last entry in the table is special, with an offset that points past the end of the file. It is only used to calculate the length of the last actual resource. The entries MUST be in ascending order by byte offset.
The following figure illustrates the structure of the entry.
bits 63...32 bits 31...0 |----------------|---------------| resource ID type offset |----|----------|
Zero-length resources are allowed in the resource file as placeholders
for future content. The implementation
MUST NOT return null
for resources that have an entry in the offset table.
Instead, for string resources
the implementation MUST return the empty string, and for binary data it MUST return
an empty byte array.
If the ResourceManager
implementation supports the caching of resources, it SHOULD read the
table of offsets and types into memory when it is
first constructed. Later it MAY also cache the resources it reads. To determine
if ResourceManager supports caching, applications can call the
isCaching()
method of the class. This information
could be used to determine if the application itself needs to cache resources or not.
The application specific resources MUST appear in the resource file in ascending order by resource ID. However, the resource ID sequence MAY contain gaps, so that the index table is essentially a sparse array. This allows the implementation to skip straight to the desired resource using only the index, without reading the file over again from the start.
The type of each resource MUST be encoded in the top eight bits of the lower 32-bit half of the index entry. Currently the following values are defined for the resource type:
0x01 = string in UTF-8 encoding
0x10 = binary data
0x00 = end of resources
The resource type is used by the getResource
and
getString
methods of the
ResourceManager
class.
Different types of resources MAY occur in arbitrary order inside the resource file,
except for the type 0x00, which is not an actual resource. There MUST be only one
entry with type 0x00 in the file, and it MUST be the last entry in the offset table.
The resource ID associated with that entry MUST be 0x80000000.
The maximum size of the resource file is determined by the
number of resources in the file, their individual sizes and the offset.
A resource file always contains the signature, the header and at least one
offset, which MAY be the only one. Hence the minimum
size of the resource file is 4 + 4 + 8 = 16 bytes. The use of
invalid resource files MUST result in a
ResourceException
being thrown with error code
DATA_ERROR
.
All data in the resource file with units larger than an octet MUST appear in the "Big Endian" format (network byte order).
This informative section describes a sample binary resource file. The file contains five resources (three strings and two images). The hexadecimal dump of the bytes in the file has been augmented with offset labels from the start of the file, and comments have been inserted (starting with the hash mark #). These offset labels and comments do not appear in the actual file. Also, all the image data is not shown.
000000 EE 4D 49 10 # signature and version 000004 00 00 00 30 # length of header # start of offset table # ID=0x00000040, type=0x01, offset 0x000038 000008 00 00 00 40 01 00 00 38 # ID=0x00000041, type=0x01, offset 0x00003A 000010 00 00 00 41 01 00 00 3A # ID=0x00008000, type=0x10, offset 0x000040 000018 00 00 80 00 10 00 00 40 # ID=0x00008001, type=0x01, offset 0x00011F 000020 00 00 80 01 01 00 01 1F # ID=0x00008002, type=0x10, offset 0x000123 000028 00 00 80 02 10 00 01 23 # ID=0x80000000, type=0x00 (end of resources), end offset 000030 80 00 00 00 00 00 02 20 # start of resources # the string 'OK' (ID=0x0040) 000038 4F 4B # the string 'Cancel' (ID=0x0041) 00003A 43 61 6E 63 65 6C # data for image 'stop.png' (ID=0x8000) 000040 89 50 4E 47 0D 0A 1A 0A... # the string 'Back' (ID=0x8001) 00011F 42 61 63 6B # data for image 'ok.png' (ID=0x8002) 000123 89 50 4E 47 0D 0A 1A 0A... 000220 # end of file
The sample resource file contains resources with IDs 0x00000040, 0x00000041,
0x00008000, 0x00008001, and 0x00008002.
At runtime, when an instance of ResourceManager
has been created to access the contents of this file, the
call getString(0x00000040)
will return the string "OK"
,
and the call getData(0x00008000)
will return the data of the image file stop.png
as a byte array.
(The first call is equivalent to getResource(0x00000040)
,
and the second is equivalent to getResource(0x00008000)
.)
See the ResourceManager
class documentation
for details about the API calls.
Note that application developers SHOULD define symbolic constants for the application resources.
This informative section details the advantages of the binary resource
format used in this API over text-based formats,
such as the one used by the PropertyResourceBundle
class in
Java 2, Standard Edition.
The use of UTF-8 enables the
application programmer to use a single character encoding for all text,
regardless of the language of the text. In J2SE PropertyResourceBundles
all strings have to be in the ISO Latin-1
encoding, and all characters outside that encoding need to be specified in the
\Uxxxx notation. For Chinese and Japanese characters the use of UTF-8 often uses more memory than
a native encoding, but does not require the use of \Uxxxx escapes.
Integers are used instead of strings to identify resources, taking up less memory. They correspond directly to the resource IDs used by the ResourceManager API.
A binary format uses less storage than a text-based format and it can be read in an efficient manner. Both of these considerations are important in a mobile device.
In the binary format strings can contain embedded newlines, unlike in the line-delimited text file format.
JSR-118 Expert Group, Mobile Information Device Profile, version 2.0. Java Community Process. Available at http://www.jcp.org/en/jsr/detail?id=118.
Connected, Limited Device Configuration Specification, Version 1.1. Java Community Process. Available at http://www.jcp.org/en/jsr/detail?id=139.
Francois Yergeau, UTF-8, a transformation format of ISO 10646, RFC 2279. Available at http://www.ietf.org/rfc/rfc2279.txt.
S. Bradner, Key Words for use in RFCs to Indicate Requirement Levels, RFC 2119. Available at http://www.ietf.org/rfc/rfc2119.txt.
The Unicode Consortium, The Unicode Standard, Version 3.0. Addison-Wesley, 2000. See http://www.unicode.org.
Common Locale Data Repository (CLDR). See http://www.unicode.org/cldr/.
JAR File Specification. See http://java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html.
This informative section contains programming examples for Mobile Internationalization API.
These are code fragments from a demonstration MIDlet
that uses a ResourceManager
to load images and strings from binary resource
files in the application's JAR file.
import javax.microedition.global.*; public final class MoonDemo extends MIDlet implements CommandListener { private ResourceManager res; public static final int PHASE_NEW_MOON = 0; . . . public static final int PHASE_WANING_CRESCENT = 7; // Images for the different moon phases. // These are loaded when first needed. private Image[] phaseImages = new Image[8]; private int currentPhase; // indicates the current phase shown private ImageItem moonPhaseImageItem; // shows the image in the form . . . public MoonDemo() { try { // Use system default locale. We have English texts in the // common locale for backup. res = ResourceManager.getManager("MoonPhases"); } catch (ResourceException re) { System.out.println(re.getMessage() + " (" + re.getErrorCode() + ")"); } nextCommand = new Command( res.getString(MoonPhases.COMMAND_NEXT), Command.SCREEN, 1); exitCommand = new Command( res.getString(MoonPhases.COMMAND_EXIT), Command.EXIT, 1); mainForm = new Form(res.getString(MoonPhases.TEXT_MOON_PHASES)); mainForm.addCommand(nextCommand); mainForm.addCommand(exitCommand); mainForm.setCommandListener(this); moonPhaseImageItem = new ImageItem("", null, ImageItem.LAYOUT_CENTER, ""); mainForm.append(moonPhaseImageItem); updateMainForm(); display.setCurrent(mainForm); } . . . private void updateMainForm() { if (phaseImages[currentPhase] == null) { // Get the phase image. Use new moon as the base and add the // current phase (0 to 7) to get the correct resource ID. byte[] imageData = res.getData( MoonPhases.IMAGE_NEW_MOON + currentPhase); phaseImages[currentPhase] = Image.createImage( imageData, 0, imageData.length); } moonPhaseImageItem.setImage(phaseImages[currentPhase]); // Just load the text. If the resource manager is caching, // the string will come from the heap and not from the JAR. // Use new moon as the ID base. String phaseText = res.getString( MoonPhases.TEXT_NEW_MOON + currentPhase); moonPhaseImageItem.setLabel(phaseText); } } /** Utility class that contains the resource ID constants. */ public final class MoonPhases { // class name is the basename // private constructor to prevent instantiation private MoonPhases() { } public static final int TEXT_MOON_PHASES = 1; public static final int COMMAND_NEXT = 2; public static final int COMMAND_EXIT = 3; public static final int TEXT_NEW_MOON = 11; public static final int TEXT_WAXING_CRESCENT = 12; public static final int TEXT_FIRST_QUARTER = 13; public static final int TEXT_WAXING_GIBBOUS = 14; public static final int TEXT_FULL_MOON = 15; public static final int TEXT_WANING_GIBBOUS = 16; public static final int TEXT_LAST_QUARTER = 17; public static final int TEXT_WANING_CRESCENT = 18; public static final int IMAGE_NEW_MOON = 111; public static final int IMAGE_WAXING_CRESCENT = 112; public static final int IMAGE_FIRST_QUARTER = 113; public static final int IMAGE_WAXING_GIBBOUS = 114; public static final int IMAGE_FULL_MOON = 115; public static final int IMAGE_WANING_GIBBOUS = 116; public static final int IMAGE_LAST_QUARTER = 117; public static final int IMAGE_WANING_CRESCENT = 118; }
The MIDlet uses the following directory structure in the JAR file:
JAR file root | | +----global----MoonPhases.res | | +----da-DK----MoonPhases.res | | fi-FI----MoonPhases.res | | en-------MoonPhases.res | | hu-HU----MoonPhases.res
These are code fragments from a demonstration MIDlet that
formats data items correctly for the locale using a Formatter
.
The labels and the formatting templates are loaded from a resource
file.
Calendar now = Calendar.getInstance(); StringItem todaysDate = new StringItem(res.getString(RES_LABEL_DATE), fmt.formatDateTime(now, Formatter.DATE_LONG)); todaysDate.setLayout(Item.LAYOUT_NEWLINE_AFTER); formattingForm.append(todaysDate); StringItem currentTime = new StringItem(res.getString(RES_LABEL_TIME), fmt.formatDateTime(now, Formatter.TIME_LONG)); currentTime.setLayout(Item.LAYOUT_NEWLINE_AFTER); formattingForm.append(currentTime); Runtime rt = Runtime.getRuntime(); long totalMemory = rt.totalMemory(); long freeMemory = rt.freeMemory(); // reuse template variable String template = res.getString(RES_MESSAGE_TOTAL_MEMORY); String totalString = fmt.formatNumber(totalMemory); String totalMegString = fmt.formatNumber(totalMemory / 1048576.0, 1); String totalMemoryMessage = Formatter.formatMessage(template, new String[] { totalString, totalMegString }); // in template: {0} {1} float freePercentage = freeMemory / (float) totalMemory; String freePercentageString = fmt.formatPercentage(freePercentage, 1); template = res.getString(RES_MESSAGE_FREE_MEMORY); String freeString = fmt.formatNumber(freeMemory); String freeMegString = fmt.formatNumber(freeMemory / 1048576.0, 1); String freeMemoryMessage = Formatter.formatMessage(template, new String[] { freeString, freeMegString, freePercentageString }); // in template: {0} {1} {2} StringItem totalMemoryString = new StringItem( res.getString(RES_LABEL_TOTAL_MEMORY), totalMemoryMessage); totalMemoryString.setLayout(Item.LAYOUT_NEWLINE_AFTER); formattingForm.append(totalMemoryString); StringItem freeMemoryString = new StringItem( res.getString(RES_LABEL_FREE_MEMORY), freeMemoryMessage); freeMemoryString.setLayout(Item.LAYOUT_NEWLINE_AFTER); formattingForm.append(freeMemoryString); StringItem piString = new StringItem(res.getString(RES_LABEL_PI), fmt.formatNumber(Math.PI, 5)); formattingForm.append(piString);
The English language string resources used in this code are:
RES_LABEL_DATE "Today's date:"
RES_LABEL_TIME "Current time:"
RES_MESSAGE_TOTAL_MEMORY "{0} bytes ({1} MB)"
RES_LABEL_TOTAL_MEMORY "Total memory:"
RES_LABEL_FREE_MEMORY "Free memory:"
RES_LABEL_PI "Value of π (to 5 decimal places):"
RES_MESSAGE_FREE_MEMORY "{0} bytes ({1} MB), {2} free"
The following sample code shows how to sort an array of strings
in a locale-specific way using an instance of
StringComparator
.
private StringComparator comp;
private void sortList() {
// Fetch the data from the List widget
String[] data = new String[collationList.size()];
for (int i = 0; i < data.length; i++) {
data[i] = collationList.getString(i);
}
// Prepare a StringComparator for sorting.
if (comp == null) {
comp = new StringComparator(); // use default locale
}
// Bubble sort; slow but illustrative
String hold = null; // temporary holding area for swap
for (int pass = 1; pass < data.length; pass++) { // all passes
for (int itemIndex = 0;
itemIndex < data.length - pass; itemIndex++) {
int result = comp.compare(
data[itemIndex], data[itemIndex + 1]);
if (result > 0) {
// first item belongs after second, c.f. "a[i] > a[i+1]"
hold = data[itemIndex];
data[itemIndex] = data[itemIndex + 1];
data[itemIndex + 1] = hold;
}
}
}
// Populate the list again with the sorted data
populateCollationList(data);
|
|||||||||
PREV NEXT | FRAMES NO FRAMES |