📄 mar01_ericg.txt
字号:
You could easily extend the Record class to include methods such
as getFirstName and getLastName to make it easy to extract the
data you've stored in a record.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
USING THE MIDP LOW-LEVEL USER INTERFACE API
With J2ME, profiles are responsible for defining the user
interface (UI) application programming interface (API). The
Mobile Information Device Profile (MIDP) defines two such APIs,
referred to as the high-level and low-level APIs. The high-level
API requires you to use task-oriented abstractions to define what
the user interface does. You have no real control over what gets
drawn on the screen -- the implementation selects the best
approach for the device. The high-level API is portable across
all MIDP-enabled devices and is really geared towards business
applications. Look for more information about the high-level API
in a future J2ME Tech Tip.
The low-level API is aimed squarely at game developers. Unlike
the high-level API, the low-level API gives you complete access
to the screen and to input events. However, this access comes
with a price, because you're then responsible for drawing
everything that is shown on the screen. You can use both the
high-level and low-level APIs in the same application, but not at
the same time. Think of the application as a deck of cards, with
only one card visible at a time (much like the behavior provided
by the java.awt.CardLayout class in the J2SE(tm) Platform).
Each card, known as a screen in MIDP terminology, in the deck can
use either the high-level API or the low-level API, but not both.
The only exception applies to the use of command objects,
discussed later in this tip.
To use the low-level API in a MIDlet, you must write a class
that extends the Canvas class:
// Simple canvas
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class MyCanvas extends Canvas {
private MIDlet midlet;
public MyCanvas( MIDlet midlet ){
this.midlet = midlet;
}
protected void paint( Graphics g ){
g.setColor( 255, 255, 255 );
g.fillRect( 0, 0, getWidth(), getHeight() );
g.setColor( 0, 0, 0 );
g.drawString( "Hello there!", getWidth()/2, 0,
g.TOP | g.HCENTER );
}
}
All user interface classes are in the javax.microedition.lcdui
package. Notice that you also need to import the
javax.microedition.midlet package because you will pass to each
canvas a reference to the MIDlet. Your canvas subclass must
implement a paint method, which is called by the system to
repaint the screen. The paint method is passed a Graphics object
which defines methods for all the standard drawing primitives
you would expect, such as drawArc, drawLine, drawRect, and
drawString. Color is supported in the API using a 24-bit RGB
model, although the device might support less color than the API.
The MyCanvas example simply erases the screen by painting it
white and then draws a string (in black) at the center top of the
screen.
You activate a canvas by calling the setCurrent method on the
MIDlet's Display object, usually in the startApp method of the
application's MIDlet class:
// Simple MIDlet
import javax.microedition.midlet.*;
public class MyMIDlet extends MIDlet {
private Display display;
private MyCanvas canvas;
public MyMIDlet(){
display = Display.getDisplay( this );
canvas = new MyCanvas( this );
}
protected void startApp(){
display.setCurrent( canvas );
}
protected void pauseApp(){
}
protected void destroyApp( boolean unconditional ){
}
public void exit(){
destroyApp( true );
notifyDestroyed();
}
}
Although this MIDlet works, it has one problem: there is no
obvious way to exit from it. You need to trap user input in some
way. There are two ways to do this: using raw input events or
command events.
A canvas receives raw input events by overriding the appropriate
event delivery method defined by the Canvas class. There are
methods for events generated by:
o Pressing the keypad (keyPressed, keyRepeated, and keyReleased)
o Using the pointer (pointerPressed, pointerDragged and
pointerReleased) if a pointer is available on the device
o Showing the canvas (showNotify, hideNotify).
For example, you could add a way to terminate the application by
defining a keyPressed event on the canvas:
protected void keyPressed( int keyCode ){
((MyMIDlet) midlet).exit();
}
In all keypad events, the keyCode identifies the key that
triggered the event. A positive value represents a Unicode
character, while a negative value is a key that cannot obviously
be converted into Unicode. Rather than figure out on a
device-by-device basis what keys map to what, the Canvas class
defines a number of constants for commonly-used keys. In
particular, it defines abstract game actions (UP, DOWN, LEFT,
RIGHT, FIRE, GAME_A, GAME_B, GAME_C, and GAME_D) whose keycode
mappings can be determined at runtime. During its initialization,
the device can call Canvas.getGameAction to choose which keys map
best to which actions.
You might define a base class like this:
public abstract class GameCanvas extends Canvas {
protected MIDlet midlet;
protected int fireKey;
protected int leftKey;
protected int rightKey;
protected int upKey;
protected int downKey;
public GameCanvas( MIDlet midlet ){
this.midlet = midlet;
fireKey = getKeyCode( FIRE );
leftKey = getKeyCode( LEFT );
rightKey = getKeyCode( RIGHT );
upKey = getKeyCode( UP );
downKey = getKeyCode( DOWN );
}
}
And then extend it like this:
public class MyCanvas extends GameCanvas {
private String message = "Press any key";
public MyCanvas( MIDlet midlet ){
super( midlet );
}
protected void paint( Graphics g ){
g.setColor( 255, 255, 255 );
g.fillRect( 0, 0, getWidth(), getHeight() );
g.setColor( 0, 0, 0 );
g.drawString( message, getWidth()/2, 0,
g.TOP | g.HCENTER );
}
protected void keyPressed( int keyCode ){
if( keyCode == fireKey ){
message = "FIRE";
} else if( keyCode == leftKey ){
message = "LEFT";
} else if( keyCode == rightKey ){
message = "RIGHT";
} else if( keyCode == upKey ){
message = "UP";
} else if( keyCode == downKey ){
message = "DOWN";
} else {
message = getKeyName( keyCode );
}
repaint();
}
}
Pointer events are optional because not all MIDP-enabled devices
have a pointer. You should take advantage of a pointer whenever
it makes sense. But you shouldn't assume that one is available.
You can check if pointer events will be triggered, by calling
Canvas.hasPointerEvents. The pointer event methods get passed the
horizontal and vertical position of the pointer:
protected void pointerPressed( int x, int y ){
// do something here
}
The other way to trap user input is to attach commands to a
canvas. A command is an abstract representation of an action.
It has a user-defined label, a type, and a priority. The device
uses the type to map the command to an appropriate key or button.
For example, if the device has a standard OK button, specifying
a command type of OK ensures that the OK button will trigger the
command. The available types are BACK, CANCEL, EXIT, HELP, ITEM,
OK, SCREEN, and STOP. Some or all of these may map onto the same
key or button. So when there are conflicts, the priority can be
used by the device to order the commands appropriately. The
priority is a positive integer, with 1 being the highest
priority.
Commands are created using the Command class, as in the
following:
Command exitCommand = new Command( "Exit", Command.SCREEN, 1 );
You attach the command to a canvas with the addCommand method:
canvas.addCommand( exitCommand );
You must also register a command listener using setListener:
canvas.setListener( listener );
The listener must implement the CommandListener interface. It's
common for the main MIDlet class to implement CommandListener to
trap exit commands, as in the following:
// Simple MIDlet
import javax.microedition.midlet.*;
public class MyMIDlet extends MIDlet implements
CommandListener {
private Display display;
private MyCanvas canvas;
private Command exitCommand = new Command(
"Exit", Command.SCREEN, 1 );
public MyMIDlet(){
display = Display.getDisplay( this );
canvas = new MyCanvas( this );
canvas.addCommand( exitCommand );
canvas.setListener( this );
}
protected void startApp(){
display.setCurrent( canvas );
}
protected void pauseApp(){
}
protected void destroyApp( boolean unconditional ){
}
public void exit(){
destroyApp( true );
notifyDestroyed();
}
public void commandAction( Command c, Displayable d ){
if( c == exitCommand ){
exit();
}
}
}
The CommandListener interface defines a single method,
commandAction, that is called whenever a command is triggered.
A reference to the triggered Command object is passed in as
well as a reference to the display object that was active when
it was triggered. (The same command can be shared across
different canvases and also by the high-level API). Of course,
the listener is responsible for actually carrying out the action.
. . . . . . . . . . . . . . . . . . . . . . .
- NOTE
Sun respects your online time and privacy. The Java Developer
Connection mailing lists are used for internal Sun
Microsystems(tm) purposes only. You have received this email
because you elected to subscribe. To unsubscribe, go to the
Subscriptions page (http://developer.java.sun.com/subscription/),
uncheck the appropriate checkbox, and click the Update button.
- SUBSCRIBE
To subscribe to a JDC newsletter mailing list, go to the
Subscriptions page (http://developer.java.sun.com/subscription/),
choose the newsletters you want to subscribe to, and click Update.
- FEEDBACK
Comments? Send your feedback on the J2ME Tech Tips to:
jdc-webmaster@sun.com
- ARCHIVES
You'll find the J2ME Tech Tips archives at:
http://java.sun.com/jdc/J2METechTips/index.html
- COPYRIGHT
Copyright 2001 Sun Microsystems, Inc. All rights reserved.
901 San Antonio Road, Palo Alto, California 94303 USA.
This document is protected by copyright. For more information,
see:
http://java.sun.com/jdc/copyright.html
- LINKS TO NON-SUN SITES
The J2ME Tech Tips may provide, or third parties may provide,
links to other Internet sites or resources. Because Sun has no
control over such sites and resources, You acknowledge and
agree that Sun is not responsible for the availability of such
external sites or resources, and does not endorse and is not
responsible or liable for any Content, advertising, products,
or other materials on or available from such sites or resources.
Sun will not be responsible or liable, directly or indirectly,
for any damage or loss caused or alleged to be caused by or in
connection with use of or reliance on any such Content, goods or
services available on or through any such site or resource.
J2ME Tech Tips
March 19, 2001
Sun, Sun Microsystems, Java, Java Developer Connection, Java
Embedded Server, and J2ME are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other
countries.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -