|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--javax.microedition.lcdui.Displayable | +--javax.microedition.lcdui.Canvas
The Canvas class is a base class for writing applications that
need to handle low-level events and to issue graphics calls for
drawing to the display. Game applications will likely make heavy use
of the Canvas class. From an application development perspective, the
Canvas class is interchangeable with standard Screen
classes, so an application may mix and match Canvas with high-level screens
as needed. For example, a List
screen may be used to select the
track for a racing game, and a Canvas subclass would implement the actual
game.
The Canvas provides the developer with methods to handle game actions, key events, and pointer events (if supported by the device). Static methods are also provided to identify the device's capabilities and keyboard mapping. The key events are reported with respect to key codes, which are directly bound to concrete keys on the device, use of which may hinder portability. Portable applications should use game actions instead of key codes.
Like other subclasses of Displayable
, the Canvas class
allows the application to register a listener for Commands
.
Unlike other Displayables, however, the Canvas class requires applications to
subclass it in order to use it. The paint()
method is declared abstract, so the
application must provide an implementation in its subclass. Other
event-reporting methods are not declared abstract, and their
default implementations are empty (that is, they do nothing). This allows
the application to override only the methods that report events in which the
application has interest.
This is in contrast to the Screen
classes, which allows the
application to define listeners and to register them with instances of the
Screen classes. This style is not used for the Canvas class, because several
new listener interfaces would need to be created, one for each kind of event
that might be delivered. An alternative would be to have fewer listener
interfaces, but this would require listeners to filter out events in which
they had no interest.
Key Events
Applications receive keystroke events in which the individual
keys are named within a space of key codes. Every key for
which events are reported to MIDP applications is assigned a key
code. The key code values are unique for each hardware key unless two
keys are obvious synonyms for each other. MIDP defines the following
key codes: KEY_NUM0
, KEY_NUM1
,
KEY_NUM2
, KEY_NUM3
,
KEY_NUM4
, KEY_NUM5
,
KEY_NUM6
, KEY_NUM7
,
KEY_NUM8
, KEY_NUM9
,
KEY_STAR
, and KEY_POUND
.
(These key codes correspond to keys on a ITU-T standard telephone keypad.)
Other keys may be present on the keyboard, and they will generally have
keycodes distinct from those listed above. In order to guarantee
portability, applications should use only the standard key codes.
The standard key codes' values are equal to the Unicode encoding for the character that represents the key. If the device includes any other keys that have an obvious correspondence to a Unicode character, their key code values should equal the Unicode encoding for that character. For keys that have no corresponding Unicode character, the implemention must use negative values. Zero is defined to be an invalid key code. It is thus possible for an application to convert a keyCode into a Unicode character using the following code:
if (keyCode > 0) {
char ch = (char)keyCode;
// ...
}
This technique is useful only in certain limited cases. In particular, it is
not sufficient for full textual input, because it does not handle upper and
lower case, keyboard shift states, and characters that require more than one
keystroke to enter. For textual input, applications should always use
TextBox
or TextField
objects.
It is sometimes useful to find the name of a key in order to display a
message about this key. In this case the application may use the
getKeyName(int keyCode)
method to find a key's name.
Game Actions
Portable applications that need arrow key events and gaming-related events
should use game actions in preference to key codes and key names.
MIDP defines the following game actions: UP
, DOWN
,
LEFT
, RIGHT
, FIRE
,
GAME_A
, GAME_B
, GAME_C
,
GAME_D
Each key code may be mapped to at most one game action. However, a game
action may be associated with more than one key code. The application can
translate a key code into a game action using the
getGameAction(int keyCode)
method, and it
can translate a game action into a key code using the
getKeyCode(int gameAction)
method. The
implementation is not allowed to change the mapping of game actions and key
codes during execution of the application.
Portable applications that are interested in using game actions should
translate every key event into a game action by calling the
getGameAction(int keyCode)
method and then testing the result. For example, on some devices the game
actions UP, DOWN, LEFT and RIGHT may be mapped to 4-way navigation arrow
keys. In this case getKeyCode(UP)
would return a
device-dependent code for the up-arrow key. On other devices, a possible
mapping would be on the number keys 2, 4, 6, and 8. In this case,
getKeyCode(UP) would return KEY_NUM2. In both cases, the getGameAction()
method would return the LEFT game action when the user presses the key that
is a "natural left" on that device.
Commands
It is also possible for the user to issue a Command
when a
Canvas is current. Commands are mapped to keys and menus in a device-specific
fashion. For some devices the keys used for commands may overlap with the
keys that will deliver key code events to the Canvas. If this is the case,
the device will provide a means transparent to the application that
enables the user to select a mode that determines whether these keys
will deliver commands or key code events to the application. The set
of key code events available to a Canvas will not change depending
upon the number of Commands that are present on the Canvas. Game developers
should be aware that access to Commands will vary greatly across devices, and
that requiring the user to issue Commands during game play may have a great
impact on playability
Event Delivery
The Canvas object defines several methods that are called by the implementation. These methods are primarily for the purpose of delivering events to the application, and so they are referred to as event delivery methods. The set of methods is:
showNotify()
hideNotify()
keyPressed()
keyRepeated()
keyReleased()
pointerPressed()
pointerDragged()
pointerReleased()
paint()
commandAction
These methods are all called serially. That is, the implementation will never call an event delivery method before a prior call to any of the event delivery methods has returned. (But see the note below.) This property enables applications to be assured that processing of a previous user event will have completed before the next event is delivered.
Calls to the run()
method of
Runnable
objects passed to
callSerially(Runnable r)
will also be
serialized along with calls to the event delivery methods.
Note: The serviceRepaints()
method
is an exception to this rule, as it
blocks until paint()
is called and returns. This
will occur even if the application is in the midst of one of the event
delivery methods and it calls serviceRepaints().
The key-related, pointer-related, and paint() methods will only be called while the Canvas is actually visible on the output device. These methods will therefore only be called on this Canvas object after a call to showNotify() and before a call to hideNotify(). After hideNotify() has been called, none of the key, pointer, and paint methods will be called until after a subsequent call to showNotify() has returned. A call to a run() method resulting from callSerially() may occur irrespective of calls to showNotify() and hideNotify().
The showNotify()
method is called prior to the Canvas
actually being made visible on the display, and the
hideNotify()
method is called after the
Canvas has been removed from the display. The visibility state of a Canvas
(or any other Displayable
object) may be queried through
the use of the Displayable.isShown()
method.
The change in visibility state of a Canvas may be caused by
the application management software moving MIDlets between foreground and
background states, or by the system obscuring the Canvas with system screens.
Thus, the calls to showNotify() and hideNotify() are not
under the control of the MIDlet and may occur fairly frequently. Application
developers are encouraged to perform expensive setup and teardown tasks
outside the showNotify()
and
hideNotify()
methods in order
to make them as lightweight as possible.
Field Summary | |
static int |
DOWN
Constant for the DOWN game action. |
static int |
FIRE
Constant for the FIRE game action. |
static int |
GAME_A
Constant for the GAME_A game action. |
static int |
GAME_B
Constant for the GAME_B game action. |
static int |
GAME_C
Constant for the GAME_C game action. |
static int |
GAME_D
Constant for the GAME_D game action. |
static int |
KEY_NUM0
Keycode for ITU-T key 0. |
static int |
KEY_NUM1
Keycode for ITU-T key 1. |
static int |
KEY_NUM2
Keycode for ITU-T key 2. |
static int |
KEY_NUM3
Keycode for ITU-T key 3. |
static int |
KEY_NUM4
Keycode for ITU-T key 4. |
static int |
KEY_NUM5
Keycode for ITU-T key 5. |
static int |
KEY_NUM6
Keycode for ITU-T key 6. |
static int |
KEY_NUM7
Keycode for ITU-T key 7. |
static int |
KEY_NUM8
Keycode for ITU-T key 8. |
static int |
KEY_NUM9
Keycode for ITU-T key 9. |
static int |
KEY_POUND
Keycode for ITU-T key "pound" (#). |
static int |
KEY_STAR
Keycode for ITU-T key "star" (*). |
static int |
LEFT
Constant for the LEFT game action. |
static int |
RIGHT
Constant for the RIGHT game action. |
static int |
UP
Constant for the UP game action. |
Constructor Summary | |
protected |
Canvas()
Constructs a new Canvas object. |
Method Summary | |
int |
getGameAction(int keyCode)
Gets the game action associated with the given key code of the device. |
int |
getHeight()
Gets height of the displayable area in pixels. |
int |
getKeyCode(int gameAction)
Gets the key code that corresponds to the specified game action on the device. |
String |
getKeyName(int keycode)
Gets an informative key string for a key. |
int |
getWidth()
Gets width of the displayable area in pixels. |
boolean |
hasPointerEvents()
Checks if the platform supports pointer press and release events. |
boolean |
hasPointerMotionEvents()
Checks if the platform supports pointer motion events (pointer dragged). |
boolean |
hasRepeatEvents()
Checks if the platform can ganerate repeat events when key is kept down. |
protected void |
hideNotify()
The implementation calls hideNotify() shortly after the Canvas has been removed from the display. |
boolean |
isDoubleBuffered()
Checks if the Graphics is double buffered by the
implementation |
protected void |
keyPressed(int keyCode)
Called when a key is pressed. |
protected void |
keyReleased(int keyCode)
Called when a key is released. |
protected void |
keyRepeated(int keyCode)
Called when a key is repeated (held down). |
protected abstract void |
paint(Graphics g)
Renders the Canvas. |
protected void |
pointerDragged(int x,
int y)
Called when the pointer is dragged. |
protected void |
pointerPressed(int x,
int y)
Called when the pointer is pressed. |
protected void |
pointerReleased(int x,
int y)
Called when the pointer is released. |
void |
repaint()
Requests a repaint for the entire Canvas. |
void |
repaint(int x,
int y,
int width,
int height)
Requests a repaint for the specified region of the Canvas. |
void |
serviceRepaints()
Forces any pending repaint requests to be serviced immediately. |
protected void |
showNotify()
The implementation calls showNotify() immediately prior to this Canvas being made visible on the display. |
Methods inherited from class javax.microedition.lcdui.Displayable |
addCommand,
isShown,
removeCommand,
setCommandListener |
Methods inherited from class java.lang.Object |
equals,
finalize,
getClass,
hashCode,
notify,
notifyAll,
toString,
wait,
wait,
wait |
Field Detail |
public static final int DOWN
Constant value 6 is set to DOWN.
public static final int FIRE
Constant value 8 is set to FIRE.
public static final int GAME_A
Constant value 9 is set to GAME_A.
public static final int GAME_B
Constant value 10 is set to GAME_B.
public static final int GAME_C
Constant value 11 is set to GAME_C.
public static final int GAME_D
Constant value 12 is set to GAME_D.
public static final int KEY_NUM0
Constant value 48 is set to KEY_NUM0.
public static final int KEY_NUM1
Constant value 49 is set to KEY_NUM1.
public static final int KEY_NUM2
Constant value 50 is set to KEY_NUM2.
public static final int KEY_NUM3
Constant value 51 is set to KEY_NUM3.
public static final int KEY_NUM4
Constant value 52 is set to KEY_NUM4.
public static final int KEY_NUM5
Constant value 53 is set to KEY_NUM5.
public static final int KEY_NUM6
Constant value 54 is set to KEY_NUM6.
public static final int KEY_NUM7
Constant value 55 is set to KEY_NUM7.
public static final int KEY_NUM8
Constant value 56 is set to KEY_NUM8.
public static final int KEY_NUM9
Constant value 57 is set to KEY_NUM9.
public static final int KEY_POUND
Constant value 35 is set to KEY_POUND.
public static final int KEY_STAR
Constant value 42 is set to KEY_STAR.
public static final int LEFT
Constant value 2 is set to LEFT.
public static final int RIGHT
Constant value 5 is set to RIGHT.
public static final int UP
Constant value 6 is set to UP.
Constructor Detail |
protected Canvas()
Method Detail |
public int getGameAction(int keyCode)
The mapping between key codes and game actions will not change during the execution of the application.
keyCode
- the key codepublic int getHeight()
public int getKeyCode(int gameAction)
Note that a key code is associated with at most one game action, whereas a game action may be associated with several key codes. Then, supposing that g is a valid game action and k is a valid key code for a key associated with a game action, consider the following expressions:
g == getGameAction(getKeyCode(g)) // (1)
g == getKeyCode(getGameAction(k)) // (2)
Expression (1) is always true. However, expression (2) might be true but is not necessarily true.
The mapping between key codes and game actions will not change during the execution of the application.
gameAction
- the game actionpublic String getKeyName(int keycode)
This method will return a non-empty string for every valid key code.
There is no direct mapping from game actions to key names. To get the string name for game action GAME_A, the application must call
getKeyName(getKeyCode(GAME_A))
keyCode
- the key code being requestedpublic int getWidth()
public boolean hasPointerEvents()
public boolean hasPointerMotionEvents()
public boolean hasRepeatEvents()
protected void hideNotify()
public boolean isDoubleBuffered()
Graphics
is double buffered by the
implementationprotected void keyPressed(int keyCode)
The getGameAction
method can be called to
determine what game action, if any, is mapped to the key. Class Canvas
has an empty implementation of this method, and the subclass has to
redefine it if it wants to listen to this method.
keyCode
- The key code of the key that was pressed.protected void keyReleased(int keyCode)
The getGameAction
method can be called to
determine what game action, if any, is mapped to the key. Class Canvas
has an empty implementation of this method, and the subclass has to
redefine it if it wants to listen to this method.
keyCode
- The key code of the key that was releasedprotected void keyRepeated(int keyCode)
The getGameAction
method can be called to
determine what game action, if any, is mapped to the key. Class Canvas
has an empty implementation of this method, and the subclass has to
redefine it if it wants to listen to this method.
keyCode
- The key code of the key that was repeatedhasRepeatEvents()
protected abstract void paint(Graphics g)
The Graphics object's clip region defines the area of the screen that is considered to be invalid. A correctly-written paint() routine must paint every pixel within this region. Applications must not assume that they know the underlying source of the paint() call and use this assumption to paint only a subset of the pixels within the clip region. The reason is that this particular paint() call may have resulted from multiple repaint() requests, some of which may have been generated from outside the application. An application that paints only what it thinks is necessary to be painted may display incorrectly if the screen contents had been invalidated by, for example, an incoming telephone call.
Operations on this graphics object after the paint() call returns are undefined. Thus, the application must not cache this Graphics object for later use or use by another thread. It must only be used within the scope of this method.
The implementation may postpone visible effects of graphics operations until the end of the paint method.
The contents of the Canvas are never saved if it is hidden and then is
made visible again. Thus, shortly after showNotify() is called, paint()
will always be called with a Graphics object whose clip region specifies
the entire displayable area of the Canvas. Applications must not
rely on any contents being preserved from a previous occasion when the
Canvas was current. This call to paint() will not necessarily occur
before any other key, pointer, or commandAction() methods are called on
the Canvas. Applications whose repaint recomputation is expensive may
create an offscreen Image
, paint into it, and then draw\
this image on the Canvas when paint() is called.
The application code must never call paint(); it is called only by the implementation.
The Graphics object passed to the paint() method has the following properties:
Font.getDefaultFont()
SOLID
Displayable.isShown()
will return
true
g
- the Graphics object to be used for rendering the Canvas.protected void pointerDragged(int x, int y)
The hasPointerMotionEvents()
method
may be called to determine if the device supports pointer events.
Class Canvas has an empty implementation of this method, and the
subclass has to redefine it if it wants to listen this method.
x
- The horizontal location where the pointer was dragged
(relative to the Canvas)y
- The vertical location where the pointer was dragged
(relative to the Canvas)hasPointerMotionEvents()
protected void pointerPressed(int x, int y)
The hasPointerEvents()
method may be
called to determine if the device supports pointer events. Class
Canvas has an empty implementation of this method, and the subclass
has to redefine it if it wants to listen this method.
x
- The horizontal location where the pointer was pressed
(relative to the Canvas)y
- The vertical location where the pointer was pressed
(relative to the Canvas)hasPointerEvents()
protected void pointerReleased(int x, int y)
The hasPointerEvents()
method may be
called to determine if the device supports pointer events. Class
Canvas has an empty implementation of this method, and the subclass
has to redefine it if it wants to listen this method.
x
- The horizontal location where the pointer was released
(relative to the Canvas)y
- The vertical location where the pointer was released
(relative to the Canvas)hasPointerEvents()
public final void repaint()
repaint(0, 0, getWidth(), getHeight());
public final void repaint(int x, int y, int width, int height)
If the Canvas is not visible, or if width and height are zero or less, or if the rectangle does not specify a visible region of the display, this call has no effect.
The call to paint() occurs independently of the call to repaint(). That is, repaint() will not block waiting for paint() to finish. The paint() method will either be called after the caller of repaint() returns to the implementation (if the caller is a callback) or on another thread entirely.
To synchronize with its paint() routine,
applications can use either Display.callSerially()
or serviceRepaints()
, or they can code explicit synchronization
into their paint() routine.
The origin of the coordinate system is above and to the left of the pixel in the upper left corner of the displayable area of the Canvas. The X-coordinate is positive right and the Y-coordinate is positive downwards.
x
- the x coordinate of the rectangle to be repaintedy
- the y coordinate of the rectangle to be repaintedwidth
- the width of the rectangle to be repaintedheight
- the height of the rectangle to be repaintedDisplay.callSerially(Runnable)
,
serviceRepaints()
public final void serviceRepaints()
WARNING:
This method blocks until the call to the application's paint()
method returns. The application has no control over which thread
calls paint(); it may vary from implementation to implementation.
If the caller of serviceRepaints() holds a lock that the paint()
method acquires, this may result in deadlock. Therefore, callers
of serviceRepaints() must not hold any locks that might
be acquired within the paint() method. The Display.callSerially()
method
provides a facility where an application can be called back after
painting has completed, instead of issuing a blocking method
call.
Display.callSerially(Runnable r)
protected void showNotify()
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |