More On Events
Peter
Komisar © Conestoga College version 1.1
/ 2008
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
Recall from last week we saw the Command
Constructor had the following form.
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
Types
We need to investigate the significance of the
command type constants. The command type
effects the functional representation of the
command on the mobile device.
Note in the following the 'implementation' is
often referred to. Implementation
is taken to
mean the underlying application that is hosting
the
MIDlet.
SCREEN
- public static final int SCREEN
- assigned the value 1
The SCREEN command generally refers to the
entire screen's contents. Examples might be a
"Load" or a "Save". It might also refer to navigation
among screens. SCREEN is general in contrast to,
say ITEM, which pertains to an element in focus.
BACK
- public static final int BACK
- assigned the value 2
BACK represents an instruction to return to the
screen that was shown previously. The return to
the previous screen is not done automatically by
the implementation but instead by the command
Action provided by the application.
CANCEL
- public static final int CANCEL
- assigned the value 3
A CANCEL command is a standard negative answer
to a dialog presented by the current screen. Nothing is
cancelled automatically by an implementation. Cancel
is only implemented by the commandAction provided
by an application.
// a programmable CANCEL
The application 'is making the suggestion' to the
implementation that the user wants to dismiss the
current screen without taking any action regarding
anything on the current screen. Usually that the user
wants to return to the prior screen.
//
CANCEL is often used interchangeably with BACK, however
// BACK is more accurately used for
browser
oriented navigation
OK
- public static final int OK
- assigned the value 4
The OK command represents a standard positive
answer to a dialog presented by the current screen.
This sort of action, like CANCEL, is only implemented
by an application not the implementation.
This command 'suggests' to the implementation
that the user confirms the presented information is
correct in the current screen and to proceed to the
next logical screen.
//
CANCEL and OK are frequently counterparts
HELP
- public static final int HELP
- assigned the value 5
The command represents a request for on-line
help. HELP is triggered from within the context
of an application. The commandAction has the
responsibity of showing the help information.
STOP
- public static final int STOP
- assigned the value 6
The STOP command stop some process or operation
such as downloading or sending data. STOP, like
many of these commands is only called by an application,
not an implementation. The cessation is performed by
the commandAction provided by the application.
EXIT
- public static final int EXIT
- assigned the value 7
The EXIT command as we have seen, is used to exit
an application. When the user invokes this command,
the implementation does not automatically exit. The
application's commandAction will be called, and it
should manage the exit.
Example
destroyApp(true);
// ....
public void destroyApp(boolean unconditional){
notifyDestroyed();
}
ITEM
- public static final int ITEM
- assigned the value 8
The ITEM command type indicates the command
is specific to the items of the Screen or the elements
of a Choice. Normally this means the focused items
or element.
The following example summarizes these commands
in an organized MIDlet.
Matching
Priorities to Command Values
This example obtained below, from an Internet site
referenced, matches the Command classes to their
assigned priorities which seems to be a sensible
idea. the code is also nicely organized.
Notice this author has made the commands private
rather than static and final.
Another observation, which seems to be a common
trend is to summarizes actions in methods which are
sorted and called via logic in the action method.
//
This code has some event processing 'issues' to iron out
// running in current WTKs
but still presents a nice design
RoseIndia Example of Different
Command Types
//
reference: Command Midlet Example,
//
http://www.roseindia.net/j2me/command.shtml
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class CommandExample extends MIDlet implements CommandListener{
private Form form;
private Display display;
private Command ok, back, cancel, exit, help, item, screen, stop;
public CommandExample(){
form = new Form("Command Form");
screen = new Command("SCREEN", Command.SCREEN, 1);
back = new Command("BACK", Command.BACK, 2);
cancel = new Command("CANCEL", Command.CANCEL, 3);
ok = new Command("OK", Command.OK, 4);
help = new Command("HELP", Command.HELP, 5);
stop = new Command("STOP", Command.STOP, 6);
exit = new Command("EXIT", Command.EXIT,
7);
item = new Command("ITEM", Command.ITEM, 8);
}
public void startApp(){
display = Display.getDisplay(this);
form.addCommand(screen);
form.addCommand(back);
form.addCommand(cancel);
form.addCommand(ok);
form.addCommand(help);
form.addCommand(stop);
form.addCommand(exit);
form.addCommand(item);
form.setCommandListener(this);
display.setCurrent(form);
}
public void pauseApp(){}
public void destroyApp(boolean destroy){
notifyDestroyed();
}
public void backCom(){
Alert back = new Alert("BACK Command",
"Back Command Executed!", null, AlertType.INFO);
back.setTimeout(5000);
display.setCurrent(back, form);
}
public void okCom(){
Alert ok = new Alert("OK Command",
"OK Command Executed!", null, AlertType.INFO);
ok.setTimeout(5000);
display.setCurrent(ok, form);
}
public void cancelCom(){
Alert cancel = new Alert("CANCEL Command",
"Cancel Command Executed!", null, AlertType.INFO);
cancel.setTimeout(5000);
display.setCurrent(cancel, form);
}
public void exitCom(){
Alert exit = new Alert("EXIT Command",
"Exit Command Executed!", null, AlertType.INFO);
exit.setTimeout(5000);
display.setCurrent(exit, form);
}
public void commandAction(Command c, Displayable d) {
String label = c.getLabel();
if(label.equals("BACK")){
backCom();
} else if(label.equals("OK")){
okCom();
} else if(label.equals("CANCEL")){
cancelCom();
} else if(label.equals("EXIT")){
exitCom();
}
}
}
scre
In our example we saw earlier we called destroyApp( )
and set it's value to true.
BACK
Command Browsing Demonstration
We demonstrated the EXIT Command earlier.
The following code demonstrates the use of the
BACK command. This one is important as we
frequently will need to get back to a main menu
of items.
First we need a Back Command.
Example
static final Command backCommand
= new Command("Back", Command.BACK , 2 );
The MIDlet is also the Listener by implementing
Command Listener.
Example
public class GUIEvents
extends MIDlet implements CommandListener{
The list object has the Back Command added to it
and the MIDlet itself, represented by this serves as
the listener.
Example
list.setCommandListener(this);
The Back Command is added inside the command
method after a bit of sorting logic has been applied.
We include the Exit code processing.
Example
if(label.equals("Exit"))
{
System.out.println("Exit Activated!");
destroyApp(true);
}
else if(label.equals("Back"))
{
if(currentMenu.equals("Date"))
System.out.println("Today!");
display.setCurrent(list);
}
A single case switch contains the following code.
In it, a DateField is created and added to a form.
The form is then made current. The back Command
is added to the form that is displayed.
It is by this code that a BACK button is added
to the display which allows us to return to the
main menu.
Code Snippet
switch
(snapshot.getSelectedIndex())
{
case 0: {
DateField date=
new DateField("Today!",DateField.DATE);
date.setDate(new java.util.Date());
Form f = new Form("Today's date");
f.append(date);
f.addCommand(backCommand);
f.setCommandListener(this);
display.setCurrent(f);
currentMenu ="Date";
};
break;
} // switch
The getSelectedIndex( )
Method
The next question comes to mind, if we add
a number of other cases to the build how is
the appropriate display going to be selected.
A clever approach used in Qusay Mahmoud's
text, 'Learning Java' takes advantage of the
fact that each of the elements added to list
will have an index.
Using the getSelectedIndex( ) gives us a
means of selecting which display we want
to see.
A copy or a 'snapshot' of the list is created on
which the getSelectedIndex method is called.
Example
snapshot= (List) (display.getCurrent());
Following is the code for one display item all
together.
Code Sample
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
public class GUIEvents extends MIDlet implements CommandListener{
List list;
Display display;
String currentMenu;
List snapshot;
// creating
command objects
static final Command backCommand
= new Command("Back",Command.BACK,1);
static final Command mainCommand
= new Command("Main",Command.SCREEN,1);
static final Command exitCommand
= new Command("Exit",Command.EXIT,1);
// just
loading one of these initially
public void startApp() {
display = Display.getDisplay(this);
list = new List("Widgets",Choice.IMPLICIT);
list.append("Test the Date", null);
list.append("Test the Ticker", null);
list.append("Test the Gauge", null);
list.append("Test the Textfield", null);
list.addCommand(exitCommand);
list.addCommand(backCommand);
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);
}
else if(label.equals("Back"))
{
if(currentMenu.equals("Date"))
System.out.println("Today!");
display.setCurrent(list);
}
else {
snapshot= (List)
(display.getCurrent());
switch
(snapshot.getSelectedIndex())
{
case 0: {
DateField date=
new DateField("Today!",DateField.DATE);
date.setDate(new java.util.Date());
Form f = new Form("Today's date");
f.append(date);
f.addCommand(backCommand);
f.setCommandListener(this);
display.setCurrent(f);
currentMenu ="Date";
};
break;
} // switch
} // else
} // command
public void destroyApp(boolean unconditional){
notifyDestroyed();}
public void pauseApp(){}
}
Expanded Example
In the following expanded version of the above
code we add the other displays listed. Note we
first add another case to the switch and inline the
code.
After that we put the code into methods to
which makes the switch a little less cluttered.
Both ways work.
A alternative would be to create a method that
encapsulates the redundant parts that would
take the desired component as an argument
and add it to the form.
Expanded Example
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
public class GUIEvents extends MIDlet implements CommandListener{
List list;
Display display;
String currentMenu;
List snapshot;
// creating command objects
static final Command backCommand
= new Command("Back",Command.BACK,1);
static final Command mainCommand
= new Command("Main",Command.SCREEN,1);
static final Command exitCommand
= new Command("Exit",Command.EXIT,1);
// just loading one of these initially
public void startApp() {
display = Display.getDisplay(this);
list = new List("Widgets",Choice.IMPLICIT);
list.append("Test the Date", null);
list.append("Test the Ticker", null);
list.append("Test the Gauge", null);
list.append("Test the Textfield", null);
list.addCommand(exitCommand);
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);
}
else if(label.equals("Back"))
{
if(currentMenu.equals("Date"))
System.out.println("Today!");
display.setCurrent(list);
}
else {
snapshot= (List)
(display.getCurrent());
switch
(snapshot.getSelectedIndex())
{
case 0: {
DateField date=
new DateField("Today!",DateField.DATE);
date.setDate(new java.util.Date());
Form f = new Form("Today's date");
f.append(date);
f.addCommand(backCommand);
f.setCommandListener(this);
display.setCurrent(f);
currentMenu ="Date";
}
break;
case 1: {
// ticker isn't an item
// so we can't append it
Ticker ticker = new Ticker
("A Great Day to Buy Stocks!");
Form f = new Form("Motto for the
Day");
f.setTicker(ticker);
f.addCommand(backCommand);
f.setCommandListener(this);
display.setCurrent(f);
currentMenu ="Ticker";
}
break;
// putting
the code into methods
// would
clean up the switch
case 2:
setGauge();break;
case 3:
setTextField();break;
} // switch
} // else
} // command
public void destroyApp(boolean unconditional){
notifyDestroyed();}
public void pauseApp(){}
// Gauge Method
void setGauge(){
Gauge gauge = new Gauge
("Volume", true, 20,0);
Form f = new Form("Sound
Control");
f.append(gauge);
f.addCommand(backCommand);
f.setCommandListener(this);
display.setCurrent(f);
currentMenu ="Gauge";
}
// TextField
Methods
void setTextField(){
TextField tf=new TextField
("Rating: Enter A, B, C or D","****", 40,0);
Form f = new Form("Ratings");
f.append(tf);
f.addCommand(backCommand);
f.setCommandListener(this);
display.setCurrent(f);
currentMenu ="TextField";
}
}
The following example shows the OK and
CANCEL Action Types in use.
OK and CANCEL Action Types In
Use
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
public class OKCancel extends MIDlet implements CommandListener{
List list;
Display display;
String currentMenu;
List snapshot;
// creating command objects
Command OKCommand
= new Command("OK",Command.OK,4);
Command cancelCommand
= new Command("Cancel",Command.SCREEN,1);
Command exitCommand
= new Command("Exit",Command.EXIT,7);
Command backCommand
= new Command("Back",Command.OK,4);
// just loading one of these initially
public void startApp() {
display = Display.getDisplay(this);
list = new List("Forum",Choice.IMPLICIT);
list.append("Registration", null);
list.addCommand(exitCommand);
list.addCommand(backCommand);
list.setCommandListener(this);
display.setCurrent(list);
}
// action
method
// using if's
without if else for simplicity
// the
processor has to work a little more
public void commandAction(Command c, Displayable d)
{
String label=c.getLabel();
if(label.equals("Exit"))
{
System.out.println("Exit Activated!");
destroyApp(true);
}
else if(label.equals("Back"))
display.setCurrent(list);
else if(label.equals("Cancel"))
display.setCurrent(list);
else if (label.equals("OK"))
OKAction();
else {
Form f = new Form("Registration Form");
f.append("\n\nDo you want to register?");
f.addCommand(OKCommand);
f.addCommand(cancelCommand);
f.setCommandListener(this);
display.setCurrent(f);
}
} // command
public void destroyApp(boolean unconditional){
notifyDestroyed();}
public void pauseApp(){}
public void OKAction(){
Alert ok = new Alert("ALERT OK!",
"OK Let's Register!", null, AlertType.INFO);
Form f = new Form("OK! Here is the Registration
Form");
TextField tf=new TextField
("Member's Name","First & Last", 40,0);
f.append(tf);
f.append("\n\nThis takes a few minutes! ");
f.addCommand(backCommand);
f.setCommandListener(this);
display.setCurrent(ok, f);
}
}
ItemStateListener
ItemStateListener brings a sigh of relief to
developers use to the AWT model. This easy
to use listener works very much like standard
Java listeners.
ItemStateListener captures different sorts of
events noted below.
Actions Monitored by
ItemStateListener
- Adjustments on an interactive Gauge
- Enters or modifications of a TextField
- Changing the set of choices in a ChoiceGroup
- Entering a new Date or Time in a Date Field
ItemStateListener defines the following single method.
ItemStateListener's Action Method
- public void itemStateChanged(Item item)
Following is a code sample
that shows three gauges
the listeners read the actions of each gauge, get the
values and sets them to the associated StringItem.
ItemStateListener Example
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
public class ItemStates extends MIDlet implements ItemStateListener
{
Display display;
Gauge high,mid,low;
StringItem bass,midrange,treble;
// creating command objects
Command exitCommand
= new Command("Exit",Command.EXIT,7);
// just
loading one of these initially
public void startApp() {
display = Display.getDisplay(this);
Form form = new Form("Sound Controls");
high = new Gauge("High",true, 20,0);
mid = new Gauge("Mid",true, 20,0);
low = new Gauge("Low",true, 20,0);
treble = new StringItem("Treble"," " );
midrange = new StringItem("MidRange"," ");
bass = new StringItem("Bass"," ");
form.append(treble);
form.append(high);
form.append(midrange);
form.append(mid);
form.append(bass);
form.append(low);
form.setItemStateListener(this);
display.setCurrent(form);
}
public void destroyApp(boolean unconditional){
notifyDestroyed();}
public void pauseApp(){}
// Item state method
public void itemStateChanged(Item item){
//
getValue returns an int
treble.setText(high.getValue( )+"");
midrange.setText(mid.getValue()+"");
bass.setText(low.getValue()+"");
}
}
ItemCommandListener
There is also an
ItemCommandListener that uses
the J2ME model where Command objects are
associated with items.
This interface has the following method.
ItemCommandListener Method
void commandAction(Command c, Item item)
The set listener method is defined in Item and
overridden by it's descendants.
Item Set Listener Method
public void setItemCommandListener(ItemCommandListener l)
We are not going to example this listener in close
proximity to it's sibling to keep the above example
free of distraction.
Low Level Events
Game or Graphics applications will likely use low level
events such as key strokes. This would be in conjunction
with the Canvas class. Each key creates it's own
unique event. These are represented by constants
defined in the Canvas class and summarized below.
Canvas Class Constants
Representing Key Events
- FIRE //
game actions
- GAME_A
- GAME_B
- GAME_C
- GAME_D
- KEY_NUM0 // key 0 etc.
- KEY_NUM1
- KEY_NUM2
- KEY_NUM3
- KEY_NUM4
- KEY_NUM5
- KEY_NUM6
- KEY_NUM7
- KEY_NUM8
- KEY_NUM9
- KEY_POUND // #
- KEY_STAR // *
Low Levet Events Have No
Action Interface
There is no interface to implement to use these
events. They are instead built into the Canvas
class which supplies methods to process them.
These methods are the following. In the J2ME
documentation, they are referred to as Event
Delivery Methods.
Canvas Event Delivery Methods
- keyPressed()
- keyRepeated()
- keyReleased()
- pointerPressed()
- pointerDragged()
- pointerReleased()
- paint()
- showNotify()
- hideNotify()
Values associated with events are gathered
based on key codes. The getGameAction( )
method translates keys that do game functions.
Following is a simple cursory example. When
time permits we could mix in some graphics
to create a more impressive demonstration.
Low Level Event Code Example
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
public class LowEvent extends MIDlet
{
Display display;
Canvas canvas;
public void startApp(){
display = Display.getDisplay(this);
canvas =new MyCanvas();
display.setCurrent(canvas);
}
public void destroyApp(boolean unconditional){}
public void pauseApp(){}
}
class MyCanvas extends Canvas{
int y=10;
int code;
// paint is abstract and has to be overridden
// 0 is the value of TOP | LEFT
public void paint(Graphics g){
g.setColor(255,255,255);
g.drawChar((char)code, 10,y, 0 );
y=y+12;
}
protected void keyPressed(int keyCode){
code=keyCode;
repaint();
if (keyCode> 0){
System.out.println("KeyPressed: " +
(char)keyCode);
}
else
{
System.out.println("KeyPressed: " +
getGameAction(keyCode));
}
}
protected void keyReleased(int keyCode){}
}
Assignment
1 ) Create an application that lists a store or company's
three divisions in a list. Selecting an element in one
of the list takes the viewer to a page that has information
about that division or department. A Back action should
be implemented to take the viewer back to the main
menu. Also an Exit button should be present to exit
the application.