Sie sind auf Seite 1von 20

J.E.D.I.

Chapter 04
Low-Level User Interface
4.1 Objectives
After finishing this lesson, the student should be able to:
understand low-level event handling in MIDP
draw and display text, images, lines, rectangles and arcs
specify color, font and stroke for drawing operations
understand and utilize the Canvas and the Graphics classes

4.2 Introduction
In the previous lesson, we discussed how to make user interfaces like lists, forms and
input fields. Those are high-level user interfaces and the programmer does not have to
worry about painting the screen pixels or positioning screen text. All the program has to
specify are the type of components and the element labels. The system would handle
screen painting, scrolling and layout.
One drawback of using only the high-level UI components is that the program does not
have full control of the screen. There are times when we want to draw lines, animate
images and have pixel-level control of the screen.
In this lesson, we will be dealing directly with drawing on the screen. We will be studying
the Canvas class, which will be the backdrop of our drawing. We will also delve into the
Graphics class, which has methods for drawing lines, rectangles, arcs and text. We will
also discuss fonts, colors and images.

4.3 Canvas
The Canvas is a subclass of Displayable. It is an abstract class that must be extended or
subclassed before an application can make use of its functionalities.
The Canvas can be mixed with the high-level Displayable subclass Screen. The program
can switch to and from a Canvas and a Screen.

Mobile Application Development

J.E.D.I.

The Canvas defines empty event-handling methods. Applications must override them in
order to handle events.
The Canvas class defines an abstract method called paint(). Applications using the Canvas
class must provide an implementation for the paint() method.

4.3.1

The Coordinate system

The coordinate system of the Canvas is zero-based. The x and y coordinates start with 0.
The upper left hand corner of the Canvas is coordinate (0,0). The x-coordinates increase
from left to right, while the y-coordinates increase from top to bottom. The methods
getWidth() and getHeight() return the width and height of the Canvas, respectively.
The lower right corner of the screen has coordinates (getWidth() -1, getHeight()-1). Any
changes to the available paintable size of the Canvas is reported to the application by the
sizeChanged() method. The available size of the Canvas may change if there is a switch
between normal and full-screen modes or addition/removal of components like
Commands.

Figure 1: The Coordinate System

4.3.2

"Hello, world!"

Mobile Application Development

J.E.D.I.

Figure 2: Hello World MIDlet using Canvas


import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class HelloCanvasMIDlet extends MIDlet {


private Display display;
HelloCanvas canvas;
Command exitCommand = new Command("Exit", Command.EXIT, 0);

public void startApp() {


if (display == null){
canvas = new HelloCanvas(this, "Hello, world!");
display = Display.getDisplay(this);
}
display.setCurrent(canvas);
}

public void pauseApp() {


}

public void destroyApp(boolean unconditional) {


}

Mobile Application Development

J.E.D.I.

protected void Quit(){


destroyApp(true);
notifyDestroyed();
}
}

class HelloCanvas extends Canvas implements CommandListener {


private Command exitCommand = new Command("Exit", Command.EXIT, 0);
private HelloCanvasMIDlet midlet;
private String text;

public HelloCanvas(HelloCanvasMIDlet midlet, String text) {


this.midlet = midlet;
this.text = text;

addCommand(exitCommand);
setCommandListener(this);
}

protected void paint(Graphics g) {


// clear the screen by filling the whole screen w/ white color
g.setColor(255, 255, 255 );
g.fillRect(0, 0, getWidth(), getHeight());

// set the pen to black


g.setColor(0, 0, 0);
// and draw the text
g.drawString(text,
getWidth()/2, getHeight()/2,
Graphics.TOP | Graphics.HCENTER);
}

public void commandAction(Command c, Displayable d) {


if (c == exitCommand){
midlet.Quit();
}
}
}

Mobile Application Development

J.E.D.I.

With the "Hello, world!" midlet, we defined a class that extends Canvas.
class HelloCanvas extends Canvas implements CommandListener {
Then we added a command ("Exit") and set the command listener.

addCommand(exitCommand);
setCommandListener(this);
We create a command listener by implementing the CommandListener class. This means
creating a class that has a commandAction method.
class HelloCanvas extends Canvas implements CommandListener {
...

public void commandAction(Command c, Displayable d) {


...
The heart of this program is the paint() method. The first set of method calls clears the
screen:

g.setColor(255, 255, 255 );


g.fillRect(0, 0, getWidth(), getHeight());
And the graphics calls that "draws" the "Hello, world!" string on the screen:
// set the pen to black
g.setColor(0, 0, 0);
// and draw the text
g.drawString(text, getWidth()/2, getHeight()/2,
Graphics.TOP | Graphics.HCENTER);

4.3.3

Commands

Just like the List, TextBox and Form, the Canvas can have Commands attached and can
listen for command events. The steps for adding a Command to a Canvas are the same:
1.

Create a Command object

private Command exitCommand = new Command("Exit", Command.EXIT, 0);

Mobile Application Development

J.E.D.I.

2.

Use addCommand() to attach the command to the Canvas (or Form, List, TextBox)

addCommand(exitCommand);
3.
Use setCommandListener() to register which class gets command events for
commands in this Displayable

setCommandListener(this);
4.
Create a commandListener by implementing the class CommandListener and
providing a commandAction() method

class HelloCanvas extends Canvas implements CommandListener {


...
public void commandAction(Command c, Displayable d) {
if (c == exitCommand){
// do something
}
}

4.3.4

Key Events

The Canvas subclasses can listen for key events by overriding these methods:
keyPressed(int keyCode)

called when a key is pressed

keyRepeated(int keyCode)

called when a key is repeated (when held


down)

keyReleased(int keyCode)

called when a key is released

Canvas defines these 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.
To get the "String" name of the key, use the method getKeyName(int keyCode).

4.3.5

Game Actions

Each key code may be mapped to a game action. A key code may be mapped to at most
one game action. The Canvas class defines these game actions: UP, DOWN, LEFT, RIGHT,
FIRE, GAME_A, GAME_B, GAME_C, GAME_D. The program can translate a key code into a
game action using the getGameAction(keyCode).

Mobile Application Development

J.E.D.I.

The getKeyCode(int gameAction) method returns the key code associated with a game
action. A game action can have more than one key code associated with it. If there are
more than one key codes associated with a game action, only one key code will be
returned.
An application should use getGameAction(int keyCode) instead of directly using the
defined key codes. Normally, if a program wants to listen for an "UP" key, it would use
KEY_NUM2 or the device-specific key code for the UP button. Programs using this method
are not portable since devices may have different key layouts and different key codes.
KEY_NUM2 might be the "UP key" for one device, but it might also be the "LEFT key" for
another device. getGameAction() would always return UP, independent of which key was
pressed as long as it is the "UP" key that is in the context of the device's key layout.

4.3.6

Pointer Events

Aside from key events, MIDP programs can also handle pointer events. This is true if the
device has a pointer and it is implemented in the Java system of the device.
The method hasPointerEvents() returns true if the device supports pointer press and
release events. The method hasPointerMotionEvents() returns true if the device supports
pointer motion events (dragging).

public boolean hasPointerEvents()


public boolean hasPointerMotionEvents()

The events that may be generated by pointer activity are: pointerPressed, pointerReleased
and pointerDragged. An application must override these methods in order to be notified
when these events occur. The (x,y) coordinates of the event (where the pointer was
pressed/released/dragged) are specified in these callback methods.
protected void pointerPressed(int x, int y)
protected void pointerReleased(int x, int y)
protected void pointerDragged(int x, int y)

4.4 Graphics
The Graphics class is the main class for drawing text, images, lines, rectangles and arcs.
It has methods for specifying color, font and stroke.

4.4.1

Color

The Display class has methods for determining if the device has color support, and the
number of colors or gray levels supported by the device.

Mobile Application Development

J.E.D.I.

public boolean isColor()

returns true if the display supports color, returns false


otherwise

public int numColors()

returns the number of colors (or gray levels if device is


does not support color) supported by the device

To set the color to be used for the next Graphics method(s), use setColor() method.
setColor() has two forms:

public void setColor(int red, int green, int blue)


public void setColor(int RGB)
With the first form, you specify the red, green and blue components of the color. With the
second form, the color components are specified in the form of 0x00RRGGBB. The calls
to setColor int the following code segment will do the same thing:

int red, green, blue;


...
setColor(red, green, blue);
setColor( (red<<16) | (green<<8) | blue );
The other methods for color manipulation are:
public int getColor()

retuns the current color in an int of the


form an integer in form 0x00RRGGBB

public int getRedComponent()

returns the red component of the current


color

public int getGreenComponent()

returns the green component of the


current color

public int getBlueComponent()

returns the blue component of the current


color

public int getGrayScale()

returns the grayscale value of the current


color

public void setGrayScale(int value)

sets the grayscale value for suceeding


drawing operations

4.4.2

Fonts

A Font has three attributes: face, style and size. Fonts are not created by the application.
Instead, the application queries the system for certain font attributes and the system
returns a font that matches these attributes. The system does not guarantee that it will
return a font with all the requested attributes. If the system does not have a font that
matches the request, it will return a font that is the closest match with respect to the

Mobile Application Development

J.E.D.I.

request attributes.
The Font is a separate class. As stated above, the application does not create the Font
objects. Instead, the static methods getFont() and getDefaultFont() are used to request a
font from the system:

public static Font


getFont(int face, int style, int size)

returns a font from the system that


matches the attributes

public static Font getDefaultFont()

returns the default font used by the


system

public
static
getFont(int fontSpecifier)

Font returns the font used for high level


UI components. fontSpecifier may
be:
FONT_INPUT_TEXT
or
FONT_STATIC_TEXT

face is one of FACE_SYSTEM, FACE_MONOSPACE, or FACE_PROPORTIONAL.


style can be STYLE_PLAIN
or a combination of STYLE_BOLD, STYLE_ITALIC, and
STYLE_UNDERLINED. style combinations are specified by using the bitwise OR
operator (|). A bold and italicized font style is declared as:

STYLE_BOLD | STYLE_ITALIC
The font size can be: SIZE_SMALL, SIZE_MEDIUM, or SIZE_LARGE
The following methods return specific font attributes:

public
public
public
public
public
public
public

4.4.3

int getStyle()
int getFace()
int getSize()
boolean isPlain()
boolean isBold()
boolean isItalic()
boolean isUnderlined()

Stroke style

The method setStrokeStyle(int style) sets the stroke style that will be used for drawing
lines, arcs, rectangles and rounded rectangles. Stroke style does not affect text, image
and fill drawing operations.

Mobile Application Development

J.E.D.I.

public void setStrokeStyle(int style)

sets the stroke style that will be used for


drawing lines, arcs, rectangles and
rounded rectangles

public int getStrokeStyle()

returns the current stroke style

The valid values for style are SOLID and DOTTED.

4.4.4

Clipping

A clipping area is a rectangular area in the current Graphics object. Any graphics
operations will only affect pixels inside the clip area. Pixels outside the clipping area are
not affected by any graphics operations.
public void
sets the current clip area to the
setClip(int x, int y, int width, int height) rectangle specified by the
corrdinates
public int getClipX()

returns the X offset of the currrent


clipping area, relative to the origin
of this Graphics context

public int getClipY()

returns the Y offset of the currrent


clipping area

public int getClipWidth()

returns the width of the currrent


clipping area

public int getClipHeight()

returns the height of the currrent


clipping area

4.4.5

Anchor Points

Text are drawn relative to an anchor point. The method drawString() expects an (x,y)
coordinate relative to an anchor point:

public void drawString(String str, int x, int y, int anchor)


The anchor must be a combination of a horizontal constant (LEFT, HCENTER or RIGHT)
and a vertical constant (TOP, BASELINE or BOTTOM). The horizontal and vertical constants
must be combined using the bitwise OR (|) operator. This means drawing text relative to
the baseline and the horizontal center would require an anchor value of BASELINE |
HCENTER.

Mobile Application Development

10

J.E.D.I.

4.4.6

Drawing Text

The methods for drawing text and characters are:

public void
drawString(String str,
int x,
int y,
int anchor)

draws the text in str using the current color


and font. (x,y) is the coordinate of the
anchor point

public void
drawSubstring(String str,
int offset,
int len,
int x,
int y,
int anchor)

same as drawString, except that it will only


draw a substring from offset (zero-based)
with length of len

public void
drawChar(char character,
int x,
int y,
int anchor)

draws the character using the current color


and font

public void

draws the characters in the char array data,

Mobile Application Development

11

J.E.D.I.

public void
drawString(String str,
int x,
int y,
int anchor)

draws the text in str using the current color


and font. (x,y) is the coordinate of the
anchor point

drawChars(char[] data,
int offset,
int length,
int x,
int y,
int anchor)

starting from the index of offset with


length of length

Here are some methods of Font that are useful in drawing text:

public int getHeight()

returns the height of text in this font. The


height returned includes extra spacing. This
ensures that two text drawn with this
distance from one anchor point to the other
anchor point would contain enough space
between the two lines of text

public int stringWidth(String str)

returns the total width in pixels of the space


occupied by this string if drawn using this
font

public int charWidth(char ch)

returns the total width in pixels of the space


occupied by this character if drawn using
this font.

public int getBaselinePosition()

returns the distance in pixels between the


TOP and the BASELINE of the text, based on
this font

Mobile Application Development

12

J.E.D.I.

g.setColor(255, 0, 0); // red


g.drawString("JEDI",
getWidth()/2, getHeight()/2,
Graphics.TOP | Graphics.HCENTER);

g.setColor(0, 0, 255); // blue


Font font = g.getFont();
g.drawString("Java Education & Development Initiative",
getWidth()/2, getHeight()/2+font.getHeight(),
Graphics.TOP | Graphics.HCENTER);

4.4.7

Drawing Lines

The lone Graphics method for drawing lines is defined as:


public void drawLine(int x1, int y1, int x2, int y2)
This method draws a line using the current color and stroke between the coordinates
(x1,y1) and (x2, y2).

g.setColor(255, 0, 0); // red

Mobile Application Development

13

J.E.D.I.

// line from the upper left corner to the lower right corner of the screen
g.drawLine(0, 0, getWidth()-1, getHeight()-1);

g.setColor(0, 255, 0); // green


// horizontal line in the middle of the display
g.drawLine(0, getHeight()/2, getWidth()-1, getHeight()/2);

g.setColor(0, 0, 255); // blue


// horizontal line at the bottom of the screen
g.drawLine(0,

getHeight()-1, getWidth()-1, getHeight()-1);

g.setColor(0, 0, 0); // black


// line from the lower left corner to the upper right corner of the screen
g.drawLine(0, getHeight()-1, getWidth()-1,

4.4.8

0);

Drawing Rectangles

The Graphics methods for drawing rectangles are:

public void drawRect(int x, int y, int width, int height)

Mobile Application Development

14

J.E.D.I.

public void drawRoundRect(int x, int y,


int width, int height,
int arcWidth, int arcHeight)
public void fillRect(int x, int y, int width, int height)
public void fillRoundRect(int x, int y,
int width, int height,
int arcWidth, int arcHeight)
The method drawRect draws a rectangle with the upper left corner at coordinates (x,y)
and with area (width+1 x height+1). The same parameters are with drawRoundRect. The
additional parameters arcWidth and ArcHeight are the horizontal and vertical diameters of
the arc of the four corners.
If you will notice, the definition of drawRect (and drawRoundRect) specifies the width of
the rectangle drawn on the screen is width+1 and the height is height+1. This is not very
intuitive, but that is how the MIDP specifications defines these methods. To aggravate this
"off-by-one" inconsistency, the fillRect (and fillRoundRect) method fills a rectangle of area
(width x height) only! You will see this inconsistency if you input the same parameters for
drawRect and fillRect (and drawRoundRect vs fillRoundRect). The right and bottom edges
of the rectangle drawn by drawRect lie beyond the area filled by fillRect.
// use black ink for drawRect
g.setColor(0, 0, 0);
g.drawRect(8, 8, 64, 32);
// use yellow ink for fillRect
// to show the diffrence between drawRect and fillRect
g.setColor(255, 255, 0);
g.fillRect(8, 8, 64, 32);

Figure 6: Output of using the same parameters for drawRect and fillRect
// set the pen color to black
g.setColor(0, 0, 0);

Mobile Application Development

15

J.E.D.I.

// draw a rectangle at (4,8) with width 88 and height 44


// the upper left rectangle
g.drawRect(4,8,88,44);

// the upper right (rounded) rectangle


g.drawRoundRect(108,8,88,44,18,18);

// the lower left rectangle


g.fillRect(4,58,88,44);

// the lower right (rounded) rectangle


g.fillRoundRect(108,58,88,44,18,18);

4.4.9

Drawing Arcs

The method for drawing circular or elliptical arcs are:

Mobile Application Development

16

J.E.D.I.

public void drawArc(int


int
int
int
int
int

x,
y,
width,
height,
startAngle,
arcAngle)

draws an arc with center on (x,y) and


dimensions (width+1 x height+1). The arc
drawn begins at startAngle and extends for
arcAngle degrees. 0 degree is at 3 o'clock.

public void fillArc(int


int
int
int
int
int

x,
y,
width,
height,
startAngle,
arcAngle)

fills a circular or elliptical arc covering the


rectangular area with the current color.

g.setColor(255, 0, 0);
g.drawArc(18, 18, 50, 50, 0, 360); // draw a circle

g.setColor(0,

255, 0);

g.drawArc(40, 40, 100, 120, 0, 180);

g.setColor(0, 0, 255);
g.fillArc(100, 200, 80, 100,

Mobile Application Development

0, 90);

17

J.E.D.I.

4.4.10 Drawing Images


Images are drawn using the method drawImage()

public void drawImage(Image img, int x, int y, int anchor)


As with drawString, x and y are the coordinates of the anchor point. The difference is that
the vertical constant of the anchor is VCENTER instead of BASELINE.
The anchor must be a combination of a horizontal constant (LEFT, HCENTER or RIGHT)
and a vertical constant (TOP, VCENTER or BOTTOM). The horizontal and vertical constants
must be combined using the bitwise OR (|) operator. This means drawing text relative to
to vertical center and the horizontal center of the image will require an anchor value of
VCENTER | HCENTER.

try {
Image image = Image.createImage("/jedi.png");
g.drawImage(image,
getWidth()/2, getHeight()/2,
Graphics.VCENTER | Graphics.HCENTER);
} catch (Exception e){}

Mobile Application Development

18

J.E.D.I.

4.5 Exercises
4.5.1

Key Codes

Create a MIDlet that will display the codes and names of the keys pressed by the user. Use
a Canvas and place the code and name at the center of the display.

Mobile Application Development

19

J.E.D.I.

Mobile Application Development

20

Das könnte Ihnen auch gefallen