Graphic and Events
Peter
Komisar © Conestoga College version 1.3
/ 2009
reference: Learning Wireless Java, Qusay
H. Mahmoud,
O'Reilly, User’s Guide Sun JavaTM Wireless Toolkit for
CLDC Version 2.5.2, Sun MicroSystems, 'Java 2ME and
MIDP Development', John Muchow, The Mobile Information
Device Profile and MIDlets, Part 2, Kim Topley, onjava.com
Graphics
The Graphic class used in the Micro edition is very
robust and supports a similar set of actions as can
be found in the Standard edition plus a set of new
elements.
You don't have the option to cast the Graphics
class to the 2DGraphics class as you do with the
standard edition of Java.
Following are the methods in minimal signature
form without return types and arguments.
Graphics Methods in Minimal Form
clipRect()
copyArea()
drawArc()
drawChar()
drawChars()
drawImage()
drawLine()
drawRect()
drawRegion()
drawRGB()
drawRoundRect()
drawString()
drawSubstring()
fillArc()
fillRect()
fillRoundRect()
fillTriangle()
getBlueComponent()
getClipHeight()
|
getClipWidth()
getClipX()
getClipY()
getColor()
getDisplayColor()
getFont()
getGrayScale()
getGreenComponent()
getRedComponent()
getStrokeStyle()
getTranslateX()
getTranslateY()
setClip()
setColor()
setColor()
setFont(t)
setGrayScale()
setStrokeStyle()
translate() |
Differences Between the Standard and
Micro Edition Graphics
On first glance the two
editions look similar but there
are major differences between the Graphics models.
A first difference regards the use of colors.
The
Color Model
As in the Standard Edition,
the MicroEdition uses
a Red, Green Blue Model which is described as
24 bits, with 8 bits used for color. Eight bits may
also be used to describe an alpha or transparency
value.
Alpha Red Green Blue Bit Mapping
|
alpha bits 31 - 24 | red bits 23 - 16 | green bits 15 - 8 | blue
bits 7 - 0 |
No Color Class
In the Micro Edition you do not have a Color class
to supply color constants or constructors to build
colors. Instead, in Wireless Java, this stage is by-
passed and the red, green blue values are supplied
directly to the appropriate setColor( ) method.
Following are the forms of the setColor methods
found in the Graphics class.
The setColor( ) Methods
- void setColor(int RGB)
- void setColor(int red, int green, int blue)
Example
g. setColor( 44,44,44 );
Many methods of the standard
edition methods are
not supported. A few examples are shown below.
Examples of Standard Methods
Not Supported
- g.draw3DRect( )
- g.drawOval( )
- drawPolygon( )
//
unavailable in both draw and fill
The
drawRect( ) and fillRect( ) Methods
The draw and fill rectangle methods are based
on specifying four integers, two for x,y coordinates
and two for width and height.
Signature for the drawRect( )
Method
public void drawRect
(int x, int y, int width, int height)
Following is an example where the coordinate
is (10,10) with respect to the upper left corner,
the width is 50, and the height is 80.
Example
g.drawRect(10,10, 50,80);
Several other methods use the drawRect( ) format
as a basis for creating more complex forms. You
will be familiar with the approach from standard Java.
The approach is to regard the initial rectangle as an
imaginary container for a rounded rectangle, an oval,
eclipse or an arc, where the rounded forms have edges
that touch the imaginary rectangle that frames the form.
You will see this basic form underlying the next methods
that are mentioned, the draw and fillRoundRect( )
methods.
The draw and fillRoundRect( ) Methods
Again we see the MicroEdition is focused on being
economical. Recognize that the drawRoundRect( )
method and it's fill counterpart can be used to round
corners on squares but also to draw fully round
shapes.
The signature for the draw and fillroundRect( )
methods is as follows.
The draw and fillRoundRect
Signatures
void drawlRoundRect
(int x, int y,
int width, int height,
int arcWidth, int arcHeight)
void fillRoundRect
(int x, int y,
int width, int height,
int arcWidth, int arcHeight)
The first coordinates are the upper left hand corner
coordinates. The next two ints are width and height.
The additional two coordinates describe the width
and height of an imaginary rectangle that contains
an ellipse.
When a Rounded Square Becomes
an Oval or Circle
If the ellipse values are the same as the width and
height an oval or a circle is created.
Example
g.drawRoundRect(40,50,40,50,40,50);
The draw
and fillArc( ) Methods
Similarly the draw and fillArc() methods
may be used to draw or fill a circle. Following
are the method signatures.
The draw and fillArc( ) Methods
The draw and fillArc( ) methods
void drawArc
(int x, int y,
int width, int height,
int startAngle, int
arcAngle)
void fillArc
(int x, int y,
int width, int height,
int startAngle, int arcAngle)
In the case of the arc methods, x and y are the
upper left hand coordinates, width and height
describe an imaginary rectangle and the next two
ints describe a start angle and a degrees of sweep.
Example
g.fillArc( 40,220,130,40,180,180);
// a half
circle that could be the bottom of a boat
Drawing
Circles with draw and fillArc( )
Similarly the draw and fillArc()
methods may
be used to draw or fill a circle.
Putting the last argument to 360 will complete the
sweep. If the width is the same as the height a
circle is drawn.
Example
g.fillArc(100,100,30,30,0,360);
The draw and fill Polygon( ) methods can be
replaced with drawString though not as conveniently.
Draw
String and Character Methods are Anchored
Another aspect that is different in the Micro edition
is the use of anchor points. Anchor points will
position text or characters to the four corners of
a specified point.
drawString( )
and drawChar( ) Methods and Anchor Points
Anchor points minimize computation when placing
text. The method to draw a String of text is defined
below.
Example
public void drawString(String text, int x, int y, int anchor);
The anchor point is represented by the ( x, y ) coordinate.
The method then draws text relative to that point based
on anchor constants. These are as follows.
Anchor Constants
- LEFT
- HCENTER
- RIGHT
- TOP
- BASELINE
- BOTTOM
As with other positioning constants they can be
combined with the OR operator.
Example
TOP | LEFT
They are defined in the graphics class so you
will see them referenced from the graphics
context reference as in the following example.
Example
g.TOP | g.LEFT
To show the effect of anchors consider the
following code which shows the same character
being printed to the same point but with different
anchoring about that point.
For a reference the code draws an 'X' at the
reference point by drawing two intersecting
lines.
Following is the code that will do this. First
we give the drawLine( ) method a mention.
The
drawLine( ) Method
The drawLine( ) method in Java is based on
the 'shortest distance between two points. The
developer supplies the two coordinates and the
system connects them together.
drawLine( ) Signature
void drawLine(int x1, int y1, int x2, int y2)
The following snippet draws a center point
at (60,60) using two lines. The anchors are
then demonstrated with respect to this point.
Anchor Code Snippet
g.drawLine(59,59,61,61);
g.drawLine(59,61,61,59);
g.drawString("O",60,60,g.TOP | g.LEFT);
g.drawString("O",60,60,g.TOP | g.RIGHT);
g.drawString("O",60,60,g.BOTTOM | g.LEFT);
g.drawString("O",60,60,g.BOTTOM | g.RIGHT);
Emulation of Output
O O
x
O O
There are
also drawChar methods and a drawSubString( )
method. Their method signatures are shown below.
These allow drawing a character, a part of an array
of characters or part of a string. These methods, like
drawString make use of anchors.
drawChar( ) and draw
void drawSubstring
(String str, int offset, int len, int x, int y, int anchor)
void drawChar
(char character, int x, int y, int anchor)
void drawChars
(char[] data, int offset, int length, int x, int y, int anchor)
General Approaches For Creating Graphics
The intersect point (0,0) refers to the upper left
hand corner. Calls are made off of the Graphics
object which is provided by the system.
In the following example a Canvas class is
subclassed and the graphics calls are made in it.
This class is added to a Display in a Midlet class.
The source code for each class was saved separately
in the src directory of a new MIDlet project. Note
though only the MIDlet class is marked public.
Included are the work around described above
for drawing round or oval objects.
Notice the Canvas class has it's paint method
overridden. It is the argument of the paint method
that supplies the Graphics context for doing the
graphics routines.
//
both were saved as separate source codes
// with their own imports in the
'src' directory
// of their project
Canvas Class Example
import javax.microedition.lcdui.*;
class Drawing extends Canvas{
public void paint(Graphics g){
g.drawLine(59,59,61,61);
g.drawLine(59,61,61,59);
g.drawString("O",60,60,g.TOP | g.LEFT);
g.drawString("O",60,60,g.TOP | g.RIGHT);
g.drawString("O",60,60,g.BOTTOM | g.LEFT);
g.drawString("O",60,60,g.BOTTOM | g.RIGHT);
// draws an oval
g.setColor(33,111,33);
g.drawRoundRect(35,40,50,70,50,70);
// using an int as color value
// draws the boat bottom
g.setColor(180999);
g.fillArc( 40,220,130,40,180,180);
g.setColor(255,33,55);
g.fillArc(100,100,30,30,0,360);
// black outline
g.setColor(0,0,0);
g.drawArc(100,100,30,30,0,360);
char[] characters=new
char[]{'A','-','B','-','C','-','D' };
g.drawChars(characters,2,3,170,140, g.TOP | g.RIGHT);
// the original
intent of the round rect method
g.setColor(10,50,200);
g.drawRoundRect(140,130,50,90,10,20);
}
}
The MIDlet Runner Class
import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
public class GraphX extends MIDlet{
public void startApp() {
Display display = Display.getDisplay(this);
Drawing drawing =new Drawing();
display.setCurrent(drawing);
}
public void destroyApp(boolean unconditional){}
public void pauseApp(){}
}
Drawing in an Inner Class
For a small graphic
an inner class might have
been used but there is really no obvious advantage
to using one except to have the MIDlet and graphics
call all in one source code.
import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
public class GraphZ extends MIDlet{
public void startApp() {
Display display = Display.getDisplay(this);
InnerSelf inner=new InnerSelf();
display.setCurrent(inner);
}
public void destroyApp(boolean unconditional){}
public void pauseApp(){}
class InnerSelf extends Canvas{
public void paint(Graphics g){
g.setColor(0,50,100);
g.fillTriangle(100,100,150,100,75,50);
g.setColor(255,33,77);
g.fillTriangle(100,100,100,150,125,125);
g.setColor(55,233,10);
g.fillTriangle(100,100,50,50,60,90);
}
}
}
|
More Graphics Methods
The drawTriangle( ) Method
A great many complex shapes
can be created
using triangles The method is easy to use
calling for three points to be specified as ints.
There is no drawTriangle( ), presumably because
you can create a triangle outline with drawLine( ).
The
fillTriangle( ) method Signature
void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3)
Following is an example.
Triangle Example
import javax.microedition.lcdui.*;
class Drawing2 extends Canvas{
public void paint(Graphics g){
g.setColor(0,50,100);
g.fillTriangle(100,100,150,100,75,50);
g.setColor(255,33,77);
g.fillTriangle(100,100,100,150,125,125);
g.setColor(55,233,10);
g.fillTriangle(100,100,50,50,60,90);
}
}
The
translate( ) Method
The translate method changes the system
reference point. For instance, assuming your
screen is 240 by 320, you could translate
using the translate( ) method as follows.
Example
g.translate(120,160)
This makes the center of the screen act effectively
like (0,0).
The translate( ) Method
Signature
void translate( int x, int y)
Sample Code
import javax.microedition.lcdui.*;
class Drawing3 extends Canvas{
public void paint(Graphics g){
g.translate(120,160);
g.drawLine(-5,-5,5,5);
g.drawLine( 5,-5,-5,5);
}
}
//
draws an x at the center of the screen
// offsetting the default setting
Events
In this note we do a quick overview of the Event
model used in the Micro Edition. Next week we
go into detail.
There are similarities in the Event Model used
in the Micro Edition to that of the Standard Edition,
namely the definition of listener interfaces.
Also similar to the standard model is the
implementation of ItemStateListener. It works
more or less the same as the model used in
standard Java.
On the other hand, the Micro Edition uses a
Command class in a unique way. The details
regarding implementing this class are quite
different so the developer may as well treat the
processing of events in the Micro edition, at
least with respect to the Command class as a
new architecture.
Technical
Details
In the Micro Edition calls to action methods are
serialized or called in order in a single thread of
execution. Additionally the MIDP thread model is
'thread safe' and includes a mechanism for event
synchronization.
High
and Low Level Events
In the Micro Edition there are two sorts of events
described. High level events are those created by
working with high level components, such as
clicking an item on a list. (These are similar to
semantic events that are described in the standard
event model.) Low level events come from keyboard
clicks or other input devices.
//
high level or 'semantic' events are composed of
// low level event processing
calls
Command
Class
Much of the event model in Wireless Java is based
on a Command class which has the following single
constructor.
Command Class Constructor
public Command(String label, int commandType, int priority)
The constructor takes the following three arguments.
Command Constructor Arguments
- label
- a visualization of the command as a string
- positioned beside the trigger element
- command type
- static constants
- BACK
- CANCEL
- EXIT
- HELP
- ITEM
- OK
- SCREEN
- STOP
- priority
- highest priority is 1
- lesser priorities are higher values
The Command class supplies the following methods
for getting Command argument information.
Methods for returning Argument Information
- getCommandType( )
- getLabel( )
- getPriority( )
Displayable Command Methods
Displayable defines the following command methods
which are inherited by Screen and Canvas.
Displayable Command Methods
- public void addCommand(Command c)
- public void removeCommand(Command c)
The commands allow binding commands to
objects
that inherit from Displayable.
The following code uses the Command constructor
and the addCommand( ) method to set up a menu
box with these commands associated. No action
processing has been coded in yet.
Action Code Sample // no
action processing yet
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
//This doesn't
do much note a menu has been added
// with associated labels. No actions have been
// associated yet
public class Actions extends MIDlet{
public void startApp() {
Display display = Display.getDisplay(this);
TextBox tb = new TextBox("The Store",
"Welcome to the Store",40,TextField.ANY);
Command exit = new Command("Exit",Command.SCREEN,1);
Command products=new Command("Products",Command.SCREEN,2);
Command add2Cart=new Command("Add to Cart",Command.SCREEN,2);
tb.addCommand(exit);
tb.addCommand(products);
tb.addCommand(add2Cart);
display.setCurrent(tb);
}
public void destroyApp(boolean unconditional){}
public void pauseApp(){}
}
Event
Interfaces
User activated events are invoked via 'callback methods'.
Qusay Mahmoud offers the following definition for a callback
in his book 'Learning Wireless Java'.
"Callbacks are actually invocations of programmer-
defined methods performed by the underlying
application in response to actions taken by a user
at runtime." - Qusay
Mahmoud
Four kinds of callbacks are
described in MIDP.
- High Level API Commands
- Low Level Events
- single-key presses and releases
- Calls to paint( )
- Calls to Runnable's run( ) method
- via Display's callSerially( ) method
The methods spoken of here are defined inside
interfaces that the developer needs to provide
implementations for.
Following are the three Event Listener interfaces
all defined inside the javax.microedition.lcdui
package.
The first two of these event interfaces are used
in a similar fashion which is unique to the Micro
edition while the last of these, ItemStateListener
is used more like the model that is defined for the
Java standard edition.
Micro Event Interfaces
- CommandListener
- ItemCommandListener
- ItemStateListener
//
the other lcdui interface is Choice but it isn't an event interface
The CommandListener Interface
The CommandListener Interface defines the
following method.
CommandListener Interface Method
public void commandAction
(Command c, Displayable d)
// a command
event has occurred on Displayable d
Listeners
Listeners are classes that
implement the Listener
intefaces. Both Screen and Canvas can have listeners
for command events.
Registration
The listener has to be registered with the source
of the event. This is done with a registration method.
In the Micro edition a set method( ) is used.
Registration Method for
CommandListeners
public void setCommandListener
(CommandListener cl)
A
First Action Example
How the following code work may not be as
you first envisioned. The list supplies a set of
choices. The action processing though happens
via the pop-up menu that is activated separately.
Adding two or more CommandActions of Screen
type will result in a menu being created for those
items. It is from this menu that you see the actions
processed.
We tied the actions to the choices on the list
using the following list methods in combination.
One gets the string associated with the item
based on the index that is selected.
Example
list.getString(list.getSelectedIndex())
A command of Exit type will activate the left upper
button to trigger the MIDlets exit.
Calling and Overriding destroyApp( ) will give
some teeth to this action. Comment the destroyApp( )
method after first running it and then compile and
run the MIDlet again.
Today's example causes a print to console. Later
we will send output back into our display.
CommandListener Code Example
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
public class Actions2 extends MIDlet implements CommandListener{
List list;
Display display;
static final Command infoCommand
= new Command("Information",Command.ITEM,2);
static final Command buyCommand
= new Command("Add To Cart",Command.ITEM,2);
static final Command exitCommand
= new Command("Exit",Command.STOP,2);
public void startApp() {
display = Display.getDisplay(this);
list = new List("Vehicles",Choice.EXCLUSIVE);
list.append("Gas", null);
list.append("Diesel", null);
list.append("Electric", null);
list.append("Hybrid", null);
list.append("(***Items are not
activated!****)",null);
list.addCommand(exitCommand);
list.addCommand(buyCommand);
list.addCommand(infoCommand);
list.setCommandListener(this);
display.setCurrent(list);
}
// action method
public void commandAction(Command c, Displayable d){
String label=c.getLabel();
if(label.equals("Exit")){
System.out.println("Exit Activated!");
//
destroyApp(true);
}
if(label.equals("Information"))
System.out.println("Get the Information Page!\n" +
"Vehicle Type: " +
list.getString(list.getSelectedIndex()));
if(label.equals("Add To Cart"))
System.out.println("Get the Buy Page!\n" +
"Vehicle Type: " +
list.getString(list.getSelectedIndex()));
}
public void destroyApp(boolean unconditional){
notifyDestroyed();}
public void pauseApp(){}
}
Assignment
Put all the following in a single Midlet.
1 ) Between each of the following elements,
change the color of the component being drawn.
2 ) Use the drawTriangle( ) method to draw a
five pointed star.
3) Again use the drawTriangle method to draw
a diamond in the center of the star.
4) Create a rectangle with rounded corners that
contains the star.
5) Set some text into the display using drawString( )
or drawChar( ).
Screenshot the output and submit code.
//
We will tie the above event coverage into the next assignment