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

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
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

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

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

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
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


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

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

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

ItemStateListener defines the following single method.


ItemStateListener's Action Method


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

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
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.