MorkaLork Development

Interesting stuff I've picked up over the years...

Using forms and Commands

2009-06-17 18:37:08 | 793 views | MIDlet Java J2ME forms textbox stringitem commands

The premise


What are we going to create?


We are going to create a MIDlet that has a textbox and a menu. The user will be able to write anything in the textbox and then select a command in the menu that will do something with the text.


What are we gonna use?


We are going to use the Form class and derriving item classes together with the CommandListener interface for the menu.


What do we need to get started?


We need to start a project and add a file:
File->New Project ["FormMIDlet"]
File->New File ["TextHandler"]

We also need to import two packages into the FormMIDlet class:


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


The FormMIDlet class needs to inherit from the MIDlet class AND implement the CommandListener interface:


public class FormMIDlet extends MIDlet implements CommandListener



Good to know


The MIDP-GUI classes are contained in the javax.microedition.lcdui package and are structured like this:

The MIDP-GUI API

Creating our FormMIDlet


We start by declaring some member variables for the class, we're gonna need a Display object, 4 Command objects, a Form object, a TextField object and a StringItem.
The Command objects will be instantiated immediately like this:



private Command exitCommand = new Command("Exit", Command.EXIT, 1);
private Command reverseCommand = new Command("Reverse letters", Command.SCREEN, 1);
private Command asciiValueCommand = new Command("Letter ASCII value", Command.SCREEN, 1);
private Command countCommand = new Command("Count letters", Command.SCREEN, 1);


[invDivClosed]
The Command syntax:
public Command (java.lang.String label, int commandType, int priority)

The label is what will actually be visible on the screen (notice that our exitCommand sets this to "Exit" and so, there will be a button saying "Exit" in the lower left).

The commandType specifies what intent you have with this command. Most cellular phones are designed the same way with an "exit"-button being placed to the lower left, and "ok" or "menu"-button placed to the lower right and so on. This will make sure that if you create an "Exit"-button it will be placed where exit buttons are normally placed on the cell-phone in question.

The priority decides in what order the buttons are displayed on the screen. If you have two buttons on the same spot you might have to switch views to see the second button, the priority sets which order they appear in.
[/invDivClosed]


So we will have this:


public class FormMIDlet extends MIDlet implements CommandListener{
private Display display;
private Command exitCommand = new Command("Exit", Command.EXIT, 1);
private Command reverseCommand = new Command("Reverse letters", Command.SCREEN, 1);
private Command asciiValueCommand = new Command("Letter ASCII value", Command.SCREEN, 1);
private Command countCommand = new Command("Count letters", Command.SCREEN, 1);
private Form form;
private TextField txtInput;
private StringItem strOutput;
private TextHandler textHandler;


We will now add a constructor to our class where we instantiate our fields:


public FormMIDlet(){
textHandler = new TextHandler();
txtInput = new TextField("Write anything", "", 25, TextField.ANY);
strOutput = new StringItem("Output: ", "");
form = new Form("The magic box!");
form.append(txtInput);
form.append(strOutput);
form.addCommand(exitCommand);
form.addCommand(reverseCommand);
form.addCommand(asciiValueCommand);
form.addCommand(countCommand);
form.setCommandListener(this);
}


Notice here that after creating control objects (txtInput[textfield] and strOutput[StringItem]) we append them to the form object.
We also add the commands to the form and set the command listener to the FormMIDlet.

Now, the Commands will show on screen, but they won't do anything, so we need to implement the single method in the CommandListener interface, commandAction():


public void commandAction(Command c, Displayable d){
}


Now, before we put anything in there we need to decide what our Commands are going to do.

Let's start with the exitCommand, it should exit the MIDlet, that's obvious, so we'll make a method for exiting the MIDlet:


public void exitMIDlet(){
destroyApp(true);
notifyDestroyed();
}


Now we can add this method to the commandAction method:


public void commandAction(Command c, Displayable d){
if(c == exitCommand){
this.exitMIDlet();
}
}


When this method is called, the commandAction method takes two parameters, Command c and Displayable d.
Command c is the command identifier.
Displayable d is the displayable object from which the command has been sent. In this case, the Form object form.


Having added the exitCommand to the command event handler we still have three more commands to go. Since all these methods deal with text we'll create a separate class for them so we keep our main MIDlet file clean.

We'll create a new java class file and add the class TextHandler to it. TextHandler will have three methods; getReverseLetters(), getASCIIValue() and getLetterCount().


public class TextHandler {

/**
* A method to reverse the order of the characters in a string
*
* @param s Any string
* @return The string in reverse order
*/
public String getReverseLetters(String s){

String reversed = "";

for(int i = s.length() - 1; i >= 0; i--){
reversed += String.valueOf(s.charAt(i));
}

return reversed;
}

/**
* A method to get the sum of the characters ASCII values
*
* @param s Any string
* @return An int representing the ASCII value of the string
*/
public int getASCIIValue(String s){

int sum = 0;

for(int i = 0; i < s.length(); i++){
sum += s.charAt(i);
}

return sum;
}

/**
* A method to get the amount of characters in a string
*
* @param s Any string
* @return An int representing the number of characters in the string
*/
public int getLetterCount(String s){
return s.length();
}
}


Now we have three methods to connect to the commands that we want to add. So we'll expand our commandAction method to include the rest of the commands:


public void commandAction(Command c, Displayable d){
if(c == exitCommand){
this.exitMIDlet();
}
else if(c == reverseCommand){
String input = txtInput.getString();
String reversedInput = textHandler.getReverseLetters(input);
strOutput.setText(reversedInput);
}
else if(c == asciiValueCommand){
String input = txtInput.getString();
int asciiValue = textHandler.getASCIIValue(input);
strOutput.setText(Integer.toString(asciiValue));
}
else if(c == countCommand){
String input = txtInput.getString();
int sum = textHandler.getLetterCount(input);
strOutput.setText(Integer.toString(sum));
}

}


This could be shortened down of course, but this is just an example. As we can see we have now identified all the commands added to the form, and so we are ready to run our application:

Our application with its menu

Our application after running the reverseCommand

As we can see, at least the reverseCommand works =D


The full code:



FormMIDlet.java


/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package org.MorkaLork.FormsExample;

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

/**
* @author maffelu
*/
public class FormMIDlet extends MIDlet implements CommandListener{
private Display display;
private Command exitCommand = new Command("Exit", Command.EXIT, 1);
private Command reverseCommand = new Command("Reverse letters", Command.SCREEN, 1);
private Command asciiValueCommand = new Command("Letter ASCII value", Command.SCREEN, 1);
private Command countCommand = new Command("Count letters", Command.SCREEN, 1);
private Form form;
private TextField txtInput;
private StringItem strOutput;
private TextHandler textHandler;

public FormMIDlet(){
textHandler = new TextHandler();
txtInput = new TextField("Write anything", "", 25, TextField.ANY);
strOutput = new StringItem("Output: ", "");
form = new Form("The magic box!");
form.append(txtInput);
form.append(strOutput);
form.addCommand(exitCommand);
form.addCommand(reverseCommand);
form.addCommand(asciiValueCommand);
form.addCommand(countCommand);
form.setCommandListener(this);
}

public void initMIDlet(){
display = Display.getDisplay(this);
display.setCurrent(form);
}

public void exitMIDlet(){
destroyApp(true);
notifyDestroyed();
}

public void startApp() {
if(display == null){
initMIDlet();
}
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}

public void commandAction(Command c, Displayable d){
if(c == exitCommand){
this.exitMIDlet();
}
else if(c == reverseCommand){
String input = txtInput.getString();
String reversedInput = textHandler.getReverseLetters(input);
strOutput.setText(reversedInput);
}
else if(c == asciiValueCommand){
String input = txtInput.getString();
int asciiValue = textHandler.getASCIIValue(input);
strOutput.setText(Integer.toString(asciiValue));
}
else if(c == countCommand){
String input = txtInput.getString();
int sum = textHandler.getLetterCount(input);
strOutput.setText(Integer.toString(sum));
}

}
}


TextHandler.java


package org.MorkaLork.FormsExample;

/**
*
* @author maffelu
*/
public class TextHandler {

/**
* A method to reverse the order of the characters in a string
*
* @param s Any string
* @return The string in reverse order
*/
public String getReverseLetters(String s){

String reversed = "";

for(int i = s.length() - 1; i >= 0; i--){
reversed += String.valueOf(s.charAt(i));
}

return reversed;
}

/**
* A method to get the sum of the characters ASCII values
*
* @param s Any string
* @return An int representing the ASCII value of the string
*/
public int getASCIIValue(String s){

int sum = 0;

for(int i = 0; i < s.length(); i++){
sum += s.charAt(i);
}

return sum;
}

/**
* A method to get the amount of characters in a string
*
* @param s Any string
* @return An int representing the number of characters in the string
*/
public int getLetterCount(String s){
return s.length();
}
}




Article comments

Feel free to comment this article using a facebook profile.

I'm using facebook accounts for identification since even akismet couldn't handle all the spam I receive every day.