📄 jun01_ericg.txt
字号:
J 2 M E T E C H T I P S
TIPS, TECHNIQUES, AND SAMPLE CODE
WELCOME to the Java Developer Connection(sm) (JDC)
Java(tm) 2 Platform, Micro Edition (J2ME(tm))
Tech Tips, for June 22, 2001. This issue covers:
* Using the MIDP List Component
* Enumerating, Filtering, and Sorting MIDP Record Stores
The J2ME Tech Tips are written by Eric Giguere
(http://www.ericgiguere.com), an engineer at iAnywhere
Solutions, inc. Eric is the author of the book "Java 2 Micro
Edition: Professional Developer's Guide" and co-author of the
upcoming "Mobile Information Device Profile for Java 2 Micro
Edition," both books in John Wiley & Sons' Professional
Developer's Guide series."
You can view this issue of the J2ME Tech Tips on the Web at
http://java.sun.com/jdc/J2METechTips/2001/tt0622.html
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
USING THE MIDP LIST COMPONENT
The Mobile Information Device Profile (MIDP) groups its user
interface components into two sets of classes: the high-level
API and the low-level API. With the high-level API you define
your user interface using a set of platform-independent
abstractions and let the MIDP implementation decide the look
and behavior of the user interface. The low-level API gives you
complete control (and responsibility) of the drawing area and the
processing of the raw input events. The low-level API was covered
in the J2ME Tech Tip for March 19, 2001 "Using the MIDP Low-Level
User Interface API"
(http://java.sun.com/jdc/J2METechTips/2001/tt0319.html#tip2).
This Tech Tip examines the List component, part of the
high-level API. All MIDP user interface components are defined
in the javax.microedition.lcdui package.
The List component displays a set of selectable strings. An
optional image can also be displayed along with each string.
The implementation displays the strings in some kind of list --
the exact format of the display is undefined -- and provides
a way for the user to navigate from one item in the list to
another, selecting or deselecting items as appropriate. The
navigation and selection procedures are separate. In other words,
the user can navigate to a specific item without selecting or
deselecting it. This is referred to as moving the input focus.
The List class extends Screen, which is the base class for all
top-level windows in the high-level API. Only one screen is
ever visible at a time. A screen has an optional title.
Because the Screen class extends Displayable, Command objects
can also be associated with List components. The List class also
implements the Choice interface, which defines a number of
methods that the List component has in common with another
component of the high-level API: the ChoiceGroup component.
A List component supports three modes of item selection. The
first mode, List.EXCLUSIVE, lets the user select exactly one item
from the list. If the user selects an item and another item is
already selected, the previous item is automatically deselected.
Conceptually, it's as if the list was composed of a set of radio
buttons, and implementations may in fact display it that way. The
second mode, List.MULTIPLE, lets the user select zero or more of
the items simultaneously. It's as if the list was composed of a
set of checkboxes. The final mode, List.IMPLICIT, is like the
exclusive mode, but the act of selecting an item also triggers an
event, as if the user had triggered a command (more on this
below).
The List class defines two constructors. Both constructors take
the screen title and the list mode (one of List.EXCLUSIVE,
List.MULTIPLE, or List.IMPLICIT). The second constructor also
takes an array of strings and an array of images in order to
initialize the List. However, the initialization can be done
separately. For example, here's one way to construct a list
of items:
List l = new List( "Choose fruit:", List.EXCLUSIVE );
l.append( "orange", null );
l.append( "apple", null );
l.append( "pear", null );
The alternative is to use the array form of the constructor:
String[] fruitNames = { "orange", "apple", "pear" };
List l = new List( "Choose fruit:", List.EXCLUSIVE,
fruitNames, null );
Note that images are entirely optional. Even if you specify them,
the implementation might ignore them. So it's safe to pass in
null whenever an image or array of images is requested.
Before displaying a List component, you'll want to register
a command listener for it:
List l = ....;
CommandListener listener = ....; // often "this"
l.setCommandListener( listener );
A command listener is an instance of any class that implements
the CommandListener interface. Often the MIDlet's main class is
the listener. Only one listener can be registered at a time.
A List in EXCLUSIVE or MULTIPLE mode must also register at least
one Command object, otherwise no events will be sent to the
command listener. This is because the EXCLUSIVE and MULTIPLE
modes do not trigger any events as the user interacts with the
list.
It's usually a good idea to add commands to lists in IMPLICIT
mode as well as in EXCLUSIVE or MULTIPLE mode. When the user
selects an item from an IMPLICIT mode list, the list notifies
its command listener using the special Command object defined as
List.SELECT_COMMAND. This object gets passed to the listener's
commandAction method as the first argument whenever a new item is
selected. In other words, you check for implicit selection using
code like this:
public void commandAction( Command c, Displayable d ){
if( c == List.SELECT_COMMAND ){
// implicit selection...
} else if( ..... ){
..... // etc. etc.
}
}
Make sure that any operation performed in response to
SELECT_COMMAND is intuitively obvious to the user. For example,
a List component that displays a list of emails might respond to
SELECT_COMMAND by displaying the text of the selected email
message. Other mail management operations are accessed by
registering appropriate Command objects.
The List contents, that is, the text and images displayed by the
List, can be changed at any time. List defines append, delete,
insert, and set methods for this purpose. A common requirement,
for example, is to delete the contents of a list. You can do this
easily, like this:
public static void deleteListContents( List l ){
int n = l.size();
while( n-- > 0 ){
l.delete( n );
}
}
The size method returns the number of items currently stored in
the List.
If you find yourself doing these kinds of operations repeatedly,
you might want to extend List to augment it with your own
features, as in the following:
public class ExtendedList extends List {
public ExtendedList( String title, int mode ){
super( title, mode );
}
public ExtendedList( String title, int mode,
String[] itemText, Image[] itemImages ){
super( title, mode, itemText, itemImages );
}
public void deleteAll(){
int n = size();
while( n-- > 0 ){
delete( n );
}
}
}
After a List has been constructed, you can obtain the index of the
selected item at any time. In EXCLUSIVE or IMPLICIT mode, use
getSelectedIndex, which returns the index (starting at 0) of the
selected item:
List l = ....; // some list
int which = l.getSelectedIndex();
Lists in MULTIPLE mode return -1 for getSelectedIndex, because
more than one item can be selected at any given time. Use
getSelectedFlags to return the selected state of each item into an
array you supply:
List l = ....; // some list
boolean[] selected = new boolean[ l.size() ];
l.getSelectedFlags( selected );
for( int i = 0; i < selected.length; ++i ){
if( selected[i] ){
System.out.println( "Item " + i + " is selected!" );
}
}
You can also check the selected state of an individual item at
any time by calling isSelected. You can set its state by calling
setSelectedFlags or setSelectedIndex. For example, here's how to
toggle the selected items in a MULTIPLE mode List:
public void toggleItems( List l ){
boolean[] selected = new boolean[ l.size() ];
l.getSelectedFlags( selected );
for( int i = 0; i < selected.length; ++i ){
selected[i] = !selected[i];
}
l.setSelectedFlags( selected );
}
Another way to toggle the selected items is to set each item's
selected state individually:
public void toggleItems( List l ){
int n = l.size();
for( int i = 0; i < n; ++i ){
l.setSelectedIndex( i, !l.isSelected( i ) );
}
}
The latter method might cause excessive repainting of the list,
however, and should be avoided in favor of calling
setSelectedFlags.
Each item in a List can have an associated image. An image is an
instance of the Image class, usually obtained by calling
Image.createImage, and passing it the path of an image in the
MIDlet suite's JAR file. For example:
Image checked = null;
Image unchecked = null;
try {
checked = Image.createImage( "/images/check.png" );
unchecked = Image.createImage( "/images/unchecked.png" );
}
catch( java.io.IOException e ){
}
You can also create images dynamically by using the Image class's
offscreen buffer capability. However, any image used in a List or
other high-level UI component must be an immutable, that is, it
must be an unchangeable image. (See the Image class documentation
for information on how to do this with dynamically-generated
images.)
Once you have an image or set of images, you can assign them to
the items either in the constructor or as arguments to the append,
insert or set methods. You assign the items in the constructor
by passing in an array of images equal in length to the array of
strings that define the items. Here's an example that illustrates
assigning images to the append method:
List l = ....; // some list
try {
l.append( "orange", Image.createImage( "/orange.png" ) );
l.append( "apple", Image.createImage( "/apple.png" ) );
l.append( "pear", Image.createImage( "/pear.png" ) );
}
catch( IOException e ){
}
Keep the images as small as possible, no more than 10-to-16
pixels high. Make them all the same size to ensure that the text
is painted correctly. Don't depend on the images being there,
however, and make sure the item text is descriptive enough without
the image.
Let's end the tip with a simple MIDlet that demonstrates the use
of the List component.
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class ListDemo extends MIDlet {
private Display display;
private int mode = List.IMPLICIT;
private Command exitCommand = new Command( "Exit",
Command.SCREEN, 2 );
private Command selectCommand = new Command( "Select",
Command.OK, 1 );
private Command nextCommand = new Command( "Next",
Command.SCREEN, 2 );
public ListDemo(){
}
protected void destroyApp( boolean unconditional )
throws MIDletStateChangeException {
exitMIDlet();
}
protected void pauseApp(){
}
protected void startApp() throws MIDletStateChangeException {
if( display == null ){ // first time called...
initMIDlet();
}
}
private void initMIDlet(){
display = Display.getDisplay( this );
display.setCurrent( new SampleList( mode ) );
}
public void exitMIDlet(){
notifyDestroyed();
}
public static final String[] items = {
"First", "Second", "Third", "Fourth"
};
class SampleList extends List implements CommandListener {
private int mode;
SampleList( int mode ){
super( "", mode, items, null );
addCommand( exitCommand );
addCommand( selectCommand );
addCommand( nextCommand );
setCommandListener( this );
switch( mode ){
case IMPLICIT:
setTitle( "Implicit" );
break;
case EXCLUSIVE:
setTitle( "Exclusive" );
break;
case MULTIPLE:
setTitle( "Multiple" );
break;
}
this.mode = mode;
}
public void commandAction( Command c, Displayable d ){
if( c == exitCommand ){
exitMIDlet();
} else if( c == selectCommand ){
showSelection( false );
} else if( c == SELECT_COMMAND ){
showSelection( true );
} else if( c == nextCommand ){
if( mode == List.IMPLICIT ){
mode = List.EXCLUSIVE;
} else if( mode == List.EXCLUSIVE ){
mode = List.MULTIPLE;
} else {
mode = List.IMPLICIT;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -