5. Putting It All Together: UIExampleMIDlet
We use our new knowledge of the high- and low-level APIs to build a showcase of most LCDUI components: Form, Item (ImageItem, StringItem, ChoiceGroup, DateField and Gauge), Ticker, List, TextBox, and Canvas. We also use the Command class and its notification interface, CommandListener, to show how you can handle these abstract events to produce concrete behavior in your application.
The application also shows how to build a menu using Commands
and how to create high- and low-level UI components and switch between
them, emulating what we would have in a real-world application. For the
sake of simplicity and readability, we skip some code sections which are
common knowledge among Java programmers, such as the list of imported
packages and empty method implementations. This allows us to focus
instead on the behavior of the UI components we have described in so
much detail.
To get started, open the WTK and create a new project, called UIExampleMIDlet. Our application has two classes in the example package: UIExampleMIDlet (the main class) and MenuCanvas.
5.1. UIExampleMIDlet Class
Class UIExampleMIDlet
package example;
/*
Import list omitted for readability
*/
public class UIExampleMIDlet extends MIDlet implements CommandListener {
private Form form = null;
private List list = null;
private TextBox textBox = null;
private Canvas canvas = null;
private TextField textField = null;
private DateField dateField = null;
private Alert alert = null;
private ChoiceGroup choiceGroup = null;
private StringItem stringItem = null;
private Image image = null;
private ImageItem imageItem = null;
private Command backCommand = null;
private Command exitCommand = null;
private Ticker ticker = null;
private Gauge gauge = null;
public UIExampleMIDlet() throws IOException {
// creating commands
backCommand = new Command("Back",Command.BACK,0);
exitCommand = new Command("Exit",Command.EXIT,0);
// creating Form and its items
form = new Form("My Form");
textField = new TextField("MyTextField","",20,TextField.ANY);
dateField = new DateField("MyDateField",DateField.DATE_TIME);
stringItem = new StringItem("MyStringItem","My value");
choiceGroup = new ChoiceGroup("MyChoiceGroup",Choice.MULTIPLE,
new String[] {"Value 1","Value 2","Value 3"}, null);
image = Image.createImage("/test.png");
imageItem = new ImageItem("MyImage",image,ImageItem.LAYOUT_CENTER,
"No Images");
gauge = new Gauge("My Gauge",true,100,1);
form.append(textField);
form.append(dateField);
form.append(stringItem);
form.append(imageItem);
form.append(choiceGroup);
form.append(gauge);
form.addCommand(backCommand);
form.setCommandListener(this);
// creating List
list = new List("MyList",Choice.IMPLICIT,
new String[] {"List item 1","List item 2",
"List item 3"},null);
list.addCommand(backCommand);
list.setCommandListener(this);
// creating textBox
textBox = new TextBox("MyTextBox","",256,TextField.ANY);
textBox.addCommand(backCommand);
textBox.setCommandListener(this);
// creating main canvas
canvas = new MenuCanvas();
canvas.addCommand(exitCommand);
canvas.setCommandListener(this);
// creating ticket
ticker = new Ticker("My ticker is running....");
canvas.setTicker(ticker);
// creating alert
alert = new Alert("Message","This is a message!",null,AlertType.INFO);
}
public void commandAction(Command c, Displayable d) {
if(c == exitCommand) {
notifyDestroyed();
}
if(c == backCommand) {
setDisplayable(canvas);
}
if(d == canvas) {
if(c.getLabel().equals("Form")) {
setDisplayable(form);
}
else if(c.getLabel().equals("List")) {
setDisplayable(list);
}
else if(c.getLabel().equals("TextBox")) {
setDisplayable(textBox);
}
else if(c.getLabel().equals("Canvas")) {
setDisplayable(canvas);
}
else if(c.getLabel().equals("Alert")) {
setDisplayable(alert);
}
}
}
private void setDisplayable(Displayable d) {
Display.getDisplay(this).setCurrent(d);
}
protected void startApp() throws MIDletStateChangeException {
setDisplayable(canvas);
}
protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException {
// empty implementation, as there are no resources to be released
}
protected void pauseApp() {
// empty implementation, as there are no resources to be released
}
}
All of our instance variables, references to the UI components in our application, are declared and initialized to NULL.
In the class constructor, we assign each variable to a newly-created
object of the proper class. First, we create a couple of commands (Back
and Exit) that will be used to handle the high-level user actions
defined by the device implementation, assigned to the UI components and
passed to us via the commandAction(Command, Displayable) method:
backCommand = new Command("Back",Command.BACK,0);
exitCommand = new Command("Exit",Command.EXIT,0);
Following this, we begin to create the actual UI components. For example, let's see how a new Form object is constructed:
form = new Form("My Form");
textField = new TextField("MyTextField","",20,TextField.ANY);
dateField = new DateField("MyDateField",DateField.DATE_TIME);
stringItem = new StringItem("MyStringItem","My value");
choiceGroup = new ChoiceGroup("MyChoiceGroup",Choice.MULTIPLE,
new String[] {"Value 1","Value 2","Value 3"}, null);
image = Image.createImage("/test.png");
imageItem = new ImageItem("MyImage",image,ImageItem.LAYOUT_CENTER,
"No Images");
gauge = new Gauge("My Gauge",true,100,1);
form.append(textField);
form.append(dateField);
form.append(stringItem);
form.append(imageItem);
form.append(choiceGroup);
form.append(gauge);
form.addCommand(backCommand);
form.setCommandListener(this);
As outlined before, a Form is a flexible UI component that can hold other components, instances of the Item class, and show them on the screen. Users expect Form
components to present information that is related in meaning, such as
settings for an application. Doing otherwise can be confusing and result
in bad user interaction with the application.
After instantiating a Form, we create its items (textField, date-Field, stringItem, choiceGroup, imageItem and Gauge) and use the Form.append() method to add them to the Form components list. They are then displayed with the Form. One important detail: the Image object we use to create the ImageItem
retrieves a PNG image from the root of the JAR file. In order to
replicate this behavior in your own project, just copy a file called test.png to the res folder of the project.
After creating and appending the items, we add the Back command to the Form; the emulator's implementation maps it to one of the softkeys. Finally, we set the CommandListener to be our own MIDlet, which implements the commandAction() method (defined in the CommandListener interface) to handle user actions.
The rest of the constructor
creates the other UI components, adds the Back command to them and sets
the MIDlet itself as their event listener. The following lines create an
instance of MenuCanvas and add the Exit command to it:
canvas = new MenuCanvas();
canvas.addCommand(exitCommand);
canvas.setCommandListener(this);
This canvas is the main screen for our application.
The commandAction() method reacts to the events of the Back and Exit buttons and the MenuCanvas, changing screens according to the user's choices. The startApp() method simply sets the MenuCanvas instance as the main display, using the setDisplayable() utility.
5.2. MenuCanvas Class
package example;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Graphics;
public class MenuCanvas extends Canvas {
private Command[] options = new Command[] {
new Command("Form",Command.OK,1),
new Command("List",Command.OK,2),
new Command("Canvas",Command.OK,3),
new Command("TextBox",Command.OK,4),
new Command("Alert",Command.OK,4)
};
public MenuCanvas() {
for(int i=0;i<options.length;i++) {
this.addCommand(options[i]);
}
}
protected void paint(Graphics g) {
g.setColor(0,0,0);
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(255,255,255);
g.drawString("This is a canvas.",0,0,Graphics.TOP | Graphics.LEFT);
g.drawString("Check Options menu",0,20, Graphics.TOP | Graphics.LEFT);
g.drawString("for more UI components",0,40,
Graphics.TOP | Graphics.LEFT);
}
}
The options instance variable holds an array of Commands which serves as the main menu of the application. Each command has a label, a positioning guide (Command.OK) and a priority value. In the constructor, we loop through the array, adding all the commands to the Canvas so they are displayed on the screen. The abstract paint(Graphics) method is implemented so that the Canvas can be drawn upon, using the Graphics
object passed in as a parameter. In this case, we set the context color
to black, paint a screen-sized rectangle, set the color to white and
draw some strings to instruct the user how to use the application.
Save UIExampleMIDlet in a file called UIExampleMIDlet.java and MenuCanvas in a file called MenuCanvas.java in your project's src/example folder, then build and package the project using the WTK. Figure 1 shows the application running on the WTK emulator.