Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Tutorialj 2 Me
Tutorialj 2 Me
1. INTRODUCCIN A J2ME
Qu es J2ME ?
Java Micro Edition es una versin de Java diseada para dispositivos con capacidades
restringidas de procesamiento y memoria, y conectividad limitada e intermitente; en
concreto, para dispositivos mviles.
Fue creada para cubrir la demanda de
aplicaciones que se pudieran desarrollar en ellos aprovechando las capacidades de
cmputo que, si bien no son comparables con las de un computador personal, son
suficientemente buenas para aplicaciones sencillas que se destaquen ms por
aprovechar las ventajas de la movilidad que por la realizacin de operaciones muy
complejas.
Cuando hablamos de dispositivos mviles nos referimos en concreto a telfonos
celulares, palms, dispositivos blackberry y smartphones, entre otros. Una de las
principales ventajas de j2me es, al igual que en el caso de Java, la portabilidad. Si el
programa fuese diseado especficamente para el sistema operativo propio de cada
tipo de celular tendra capacidades ms amplias, puesto que podra acceder a los
de acceso al sistema de archivos (JSR 75), etc. Esto hay que tenerlo en cuenta porque
una aplicacin que hace uso de una API opcional que no se encuentre en el dispositivo
en el cual se desea instalar arrojar error al tratar de ser instalada.
Distribucin
Una aplicacin en J2ME se distribuye como un paquete JAR (archivo con extensin
.jar); este archivo acta como instalador de la aplicacin dentro del dispositivo. La
instalacin puede iniciarse por medio de un programa creado por el fabricante, como es
el caso del OVI PC Suite de Nokia, o el PC Suite de Sony Ericsson. En la mayora de
modelos se puede copiar al sistema de archivos del celular y ejecutarlo desde el mismo
dispositivo, o descargarlo de Internet gracias a una tecnologa llamada OTA (Over The
Air) que permite la validacin e instalacin de estos.
2. MIDLets
// Cdigo que se ejecutar cuando se pause la aplicacin (por ejemplo, cuando el usuario minimice o cambie de
//aplicacin activa)
}
public void destroyApp(boolean unconditional) {
// Cdigo que se ejecutar cuando la aplicacin finalize; el parmetro unconditional informa
// si el cierre de la aplicacin se produce por demanda de la misma o por demanda del //dispositivo.
}
}
Comandos
La manera ms comn en que la aplicacin recibe instrucciones por parte del usuario
es por medio de los comandos (Command). Un comando es equivalente a un botn o
a una opcin en un men en una aplicacion regular; es mostrado en pantalla, es decir,
es incluido en un elemento Displayable que puede contener uno o mltiples comandos.
Un comando tiene un nombre, un tipo de comando que especifica una categora
general (Atrs, Salir, Ok, Aceptar) y una prioridad. Todo esto para ayudar al dispositivo
a ubicar el comando dado que el programador no posee control absoluto sobre como
se van a mostrar los elementos; slo puede sugerir algunos parmetros y el dispositivo
ser el que determine automticamente como se ver y donde irn.
Cuando un comando es seleccionado se invoca la funcin commandAction del objeto
registrado en el Displayable para que gestione las acciones de los comandos. Este
El tipo del comando se obtiene con los campos estticos de la clase command:
Command.EXIT: Comando para salir de la aplicacin.
Command.OK: Comando para aceptar la operacin.
Command.BACK: Comando para regresar.
Command.ITEM: Comando asociado a un tem.
Command.SCREEN: Comando normal.
Command.STOP: Comando para detener la operacin.
Command.CANCEL: Comando para cancelar la operacin.
Command.HELP: Comando para obtener ayuda.
Como se dijo anteriormente, el tipo de comando no le da ninguna funcionalidad al
mismo; slo le sirve al dispositivo para encontrar el mejor lugar donde mostrar el
comando.
Ejemplo 4: Comandos y navegacin.
package hello;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.List;
import javax.microedition.midlet.*;
/**
* @author jesus.a.rueda
*/
public class HelloMIDLet extends MIDlet implements CommandListener { //Implementa la gestin de comandos
private Command cmdSalir;
private Command cmdIrAEscogerIdioma;
private Command cmdAtras;
private Command cmdEscogerIdioma;
private Form formulario;
private List listaIdiomas;
private Display pantalla;
private String[] saludos = { "Hello", "Hola", "Buon giorno", "Bonjour", "Guten Tag", "Bom dia" };
public void startApp() {
Formularios
Un formulario es un Displayable que contiene mltiples controles para la captura y
visualizacin de informacin; a estos componentes se les denomina formalmente
Items.
Estos tems son agregados secuencialmente en el formulario con el metodo append del
mismo.
tems de formulario:
1. TextField: Este tem provee la funcionalidad de una caja de texto donde el usuario
puede ingresar informacin; en su constructor se debe especificar un ttulo (label) , un
texto, una longitud mxima de caracteres permitida y una mscara, que es una opcin
que limita el conjunto de caracteres que se puede usar en este tem. Estas mscaras
se encuentran como variables estticas en la clase TextField:
TextField.ANY: Cualquier texto es admitido.
TextField.NUMERIC: Solo nmeros.
TextField.DECIMAL: Permite nmeros con decimales.
TextField.EMAILADDR: Permite caracteres usados para direcciones de email.
TextField.PHONENUMBER: Permite nmeros telefnicos.
TextField.PASSWORD: Permite contraseas, es decir, oculta el texto mientras
se escribe.
Para establecer el texto de un TextField se usa el metodo setString(String) y para
recuperar el texto que el usuario a escrito se usa el metodo String getString().
Ejemplo 5. Uso del TextField:
package hello;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.*;
/**
* @author jesus.a.rueda
*/
public class TextFieldExample extends MIDlet implements CommandListener {
private Form formulario;
private TextField tfNombre;
private TextField tfEdad;
private TextField tfEstatura;
private TextField tfUsuario;
private TextField tfClave;
private TextField tfTelefono;
private TextField tfEmail;
private Form resultados;
private Command cmdAceptar;
private Command cmdSalir;
private Command cmdNuevo;
private Display pantalla;
public void startApp() {
// Se obtiene la pantalla
pantalla = Display.getDisplay(this);
// Creacin del formulario principal
formulario = new Form("Creacion de Usuario");
tfNombre = new TextField("Nombre", "", 256, TextField.ANY); // Cualquier caracter
tfEdad = new TextField("Edad", "", 2, TextField.NUMERIC); // Solo nmeros, mximo 2
tfEstatura = new TextField("Estatura", "0", 5, TextField.DECIMAL); // Nmeros decimales
tfEmail = new TextField("Email", "", 256, TextField.EMAILADDR); // Filtro para email
tfTelefono = new TextField("Telefono", "", 20, TextField.PHONENUMBER);
tfUsuario = new TextField("Usuario", "", 256, TextField.ANY);
tfClave = new TextField("Clave", "", 256, TextField.PASSWORD);
formulario.append(tfNombre);
formulario.append(tfEdad);
formulario.append(tfEstatura);
formulario.append(tfEmail);
formulario.append(tfTelefono);
formulario.append(tfUsuario);
formulario.append(tfClave);
// Comandos del formulario principal
cmdAceptar = new Command("Crear", Command.OK, 0);
cmdSalir = new Command("Salir", Command.EXIT, 0);
formulario.addCommand(cmdSalir);
formulario.addCommand(cmdAceptar);
formulario.setCommandListener(this);
// Formulario de resultados
resultados = new Form("Resultados");
cmdNuevo = new Command("Nuevo", Command.OK, 0);
resultados.addCommand(cmdNuevo);
resultados.setCommandListener(this);
pantalla.setCurrent(formulario);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
//Funcin para validar los datos del formulario
private String Validar() {
String error = "";
String nombre = tfNombre.getString();
String strEdad = tfEdad.getString();
if(strEdad.equals(""))
strEdad = "0";
int edad = Integer.parseInt(strEdad);
String strEstatura = tfEstatura.getString();
if(strEstatura.equals(""))
strEstatura = "0";
double estatura = Double.parseDouble(strEstatura);
String usuario = tfUsuario.getString();
String clave = tfClave.getString();
if (nombre.equals("")) {
error = "Debe especificar un nombre";
}
if (edad <= 0) {
error = "Debe especificar una edad vlida";
}
if (estatura <= 0 || estatura > 2.5) {
error = "Debe especificar una altura vlida";
}
if (usuario.equals("")) {
error = "Debe escribir un nombre de usuario";
}
if (clave.length() < 8) {
error = "La clave debe ser mayor de 8 caracteres";
}
return error;
}
public void commandAction(Command c, Displayable d) {
if (c == cmdSalir) {
this.notifyDestroyed();
}
if (c == cmdNuevo) {
// Limpiar datos del formulario principal
tfClave.setString(null);
tfEdad.setString(null);
tfEmail.setString(null);
tfEstatura.setString(null);
tfNombre.setString(null);
tfTelefono.setString(null);
tfUsuario.setString(null);
// Limpiar los datos del formulario de resultados
resultados.deleteAll();
pantalla.setCurrent(formulario);
}
if (c == cmdAceptar) {
String error = Validar();
if (error.equals("")) {
// Escribir en el formulario de resultados los datos capturados
// Por el formulario principal
resultados.append("Nombre: " + tfNombre.getString());
resultados.append("\n");
resultados.append("Edad: " + tfEdad.getString());
resultados.append("\n");
resultados.append("Estatura: " + tfEstatura.getString());
resultados.append("\n");
resultados.append("Login: " + tfUsuario.getString());
resultados.append("\n");
resultados.append("Email: " + tfEmail.getString());
resultados.append("\n");
resultados.append("Telefono: " + tfTelefono.getString());
pantalla.setCurrent(resultados);
} else {
// Si ocurri un error en la validacin, se muestra como una alerta
Alert a = new Alert(error);
pantalla.setCurrent(a, formulario);
}
}
}
}
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.StringItem;
import javax.microedition.midlet.MIDlet;
public class StringItemExample extends MIDlet implements CommandListener {
private Display display;
private Form formulario;
private StringItem siPregunta;
private Command cmdRendirse;
private Command cmdSalir;
public StringItemExample() {
}
public void startApp() {
display = Display.getDisplay(this);
formulario = new Form("Pregunta");
siPregunta = new StringItem("Pregunta: ", "Si un avion se estrella en la frontera entre Colombia y Venezuela, donde se
entierran los sobrevivientes ?");
cmdRendirse = new Command("Me Rindo", Command.SCREEN, 1);
cmdSalir = new Command("Salir", Command.EXIT, 1);
formulario.addCommand(cmdSalir);
formulario.addCommand(cmdRendirse);
formulario.append(siPregunta);
formulario.setCommandListener(this);
display.setCurrent(formulario);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public void commandAction(Command command, Displayable displayable) {
if (command == cmdRendirse) {
siPregunta.setLabel("Respuesta: ");
siPregunta.setText("Los sobrevivientes no se entierran, porque no estan muertos!");
formulario.removeCommand(cmdRendirse);
} else if (command == cmdSalir) {
destroyApp(false);
notifyDestroyed();
}
}
}
pueda escoger, pero mostrar la lista como un cuadro desplegable que se abrir
cuando el usuario seleccione la opcin.
El ChoiceGroup muestra cadenas de texto como opcin. Cada una puede tener una
imagen asociada que servir como cono de la opcin. Se puede obtener dependiendo
del modo escogido, el ndice que est seleccionado, o un vector con el estado
(seleccionado o no) de cada una de las opciones.
Ejemplo 8. Uso del ChoiceGroup.
package hello;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.StringItem;
import javax.microedition.midlet.*;
/**
* @author jesus.a.rueda
*/
public class ChoiceGroupExample extends MIDlet implements CommandListener {
private Display pantalla;
private Form formulario;
private ChoiceGroup cgCiudad;
private ChoiceGroup cgSexo;
private ChoiceGroup cgBanco;
private Command cmdAceptar; // Comando para ir a la ventana de resultados
private Command cmdSalir; // Comando para salir de la aplicacin
private Command cmdVolver; //Comando para volver de la pantalla de resultados
private Form resultados;
private String[] ciudades = {"Armenia", "Barranquilla", "Bogota", "Bucaramanga", "Cali", "Cartagena", "Cucuta", "Ibague",
"Manizales", "Medellin", "Pereira"};
private String[] bancos = {"BBVA", "Bancolombia", "Davivienda", "HSBC", "Colmena", "Banco Popular", "Banco de Bogota"};
public void startApp() {
pantalla = Display.getDisplay(this);
formulario = new Form("Encuesta Bancaria");
// Se crea el ChoiceGroup de la ciudad, en modo lista desplegable
cgCiudad = new ChoiceGroup("Ciudad", ChoiceGroup.POPUP);
// Se asignan las opciones con el vector de ciudades
}
if(c==cmdAceptar){
String sexo = "Hombre";
if(cgSexo.getSelectedIndex()==1) // Obtiene el ndice seleccionado
sexo = "Mujer";
resultados.append(new StringItem("Sexo",sexo));
resultados.append(new StringItem("Ciudad",ciudades[cgCiudad.getSelectedIndex()]));
String strBancos = "";
boolean[] seleccionados = new boolean[bancos.length];
cgBanco.getSelectedFlags(seleccionados); //Obtiene el estado de cada opcin, true si est seleccionada
for(int i=0;i<bancos.length;i++){
if(seleccionados[i]) // Si est seleccionada la opcin con ndice i
strBancos += "\n"+bancos[i]; // Actualiza la cadena de bancos
}
resultados.append(new StringItem("Bancos",strBancos));
pantalla.setCurrent(resultados);
}
}
}
5. DateField: DateField es un tem que sirve para seleccionar o establecer una fecha y
hora, para el manejo de fechas J2ME provee el objeto Date, por lo que este control se
puede establecer en un Date especfico y obtener el Date que el usuario haya
especificado. El modo de seleccin de la fecha depende de la implementacin
especfica del dispositivo, mostrando en algunos un calendario completo, y en otros
solo un cuadro de texto con validacin de la integridad de la fecha.
Un DateField puede configurarse, ya sea para seleccionar fecha y hora
(DateField.DATE_TIME), o bien solo la fecha (DateField.DATE), o bien slo la hora
(DateField.TIME), dependiendo del parmetro mode en su constructor. Para obtener la
fecha que el usuario selecciona se usa el metodo Date getDate(), y para establecerla
se usa el metodo setDate(Date).
Ejemplo 9. Uso del DataField. Seleccin de Fecha
package hello;
import java.util.Calendar;
import java.util.Date;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.DateField;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.*;
/**
* @author jesus.a.rueda
*/
public class DateFieldExample extends MIDlet implements CommandListener {
private Display pantalla;
private Form formulario;
private TextField tfNombre; // Campo de texto para el nombre
private DateField dfFecha; // Seleccin de fecha para el cumpleaos
private ChoiceGroup cgRecordatorios; // Lista de los recordatorios
private Command cmdSalir; // Comando para salir
private Command cmdAgregar; // Comando para agregar una nueva entrada a la lista
private Command cmdEliminar; // Comando para eliminar las entradas seleccionadas
public void startApp() {
pantalla = Display.getDisplay(this);
formulario = new Form("Recordatorios Cumpleannos");
cgRecordatorios = new ChoiceGroup("Recordatorios", ChoiceGroup.MULTIPLE);
cgRecordatorios.setFitPolicy(ChoiceGroup.TEXT_WRAP_ON);
dfFecha = new DateField("", DateField.DATE); // Se crea en modo DATE para escoger solo la fecha
tfNombre = new TextField("Nombre", null, 256, TextField.ANY);
cmdSalir = new Command("Salir", Command.EXIT, 0);
cmdAgregar = new Command("Agregar", Command.OK, 0);
cmdEliminar = new Command("Eliminar", Command.SCREEN, 0);
formulario.append(tfNombre);
formulario.append(dfFecha);
formulario.append(cgRecordatorios);
formulario.addCommand(cmdSalir);
formulario.addCommand(cmdAgregar);
formulario.addCommand(cmdEliminar);
formulario.setCommandListener(this);
pantalla.setCurrent(formulario);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
// Funcin para obtener el nombre del mes
private String getNombreMes(int mes) {
switch (mes) {
case 1:
return "Enero";
case 2:
return "Febrero";
case 3:
return "Marzo";
case 4:
return "Abril";
case 5:
return "Mayo";
case 6:
return "Junio";
case 7:
return "Julio";
case 8:
return "Agosto";
case 9:
return "Septiembre";
case 10:
return "Octubre";
case 11:
return "Noviembre";
case 12:
return "Diciembre";
default:
return null;
}
}
public void commandAction(Command c, Displayable d) {
if (c == cmdSalir) {
this.notifyDestroyed(); // salir
}
if (c == cmdAgregar) {
String text = tfNombre.getString();
Date date = dfFecha.getDate(); // Obtiene el objeto Date que representa la fecha seleccionada
// Formatear la fecha, usando el objeto calendario para obtener informacion de la fecha (Date)
Calendar calendario = Calendar.getInstance(); // Se instancia el calendario
calendario.setTime(date); // Se le establece la fecha seleccionada
int mes = calendario.get(Calendar.MONTH) + 1; // Se obtiene el mes
int dia = calendario.get(Calendar.DAY_OF_MONTH); // Se obtiene el da del mes
String NombreMes = getNombreMes(mes); // Se obtiene el nombre del mes
text = NombreMes + ", " + dia + " - " + text;
cgRecordatorios.append(text, null); // Se agrega la entrada a la lista
tfNombre.setString(null); // Se borrra el cuadro de texto
dfFecha.setDate(new Date()); // Se establece la fecha como la fecha actual
}
if (c == cmdEliminar) {
// Se eliminan los indices seleccionados
int i = 0;
while (i < cgRecordatorios.size()) {
if (cgRecordatorios.isSelected(i)) {
cgRecordatorios.delete(i);
} else {
i++;
}
}
}
}
}
El uso del objeto Calendar es valioso cuando se trabaja con fechas, ya que otorga
informacin detallada sobre las propiedades de la fecha, como hora, minutos,
segundos, da, ao, etc. Tambin sirve para crear una fecha al establecer estos
parmetros y solicitar la fecha con la funcin getTime().
6. Gauge: El tem Gauge representa un indicador de progreso visual. El progreso
tiene asociado un valor que va desde 0 hasta un valor mximo especificado por el
usuario. Este tem es til cuando se quiere mostrar el avance de una operacin, o se
puede usar para mostrar que se est efectuando una operacin, o tambin, como un
control interactivo para que el usuario determine el progreso manualmente. Por lo tanto
el Gauge se puede configurar de 2 formas, como Interactivo y como No Interactivo.
El gauge interactivo permite que el usuario establezca su valor. Normalmente se
muestra como un grfico de barras donde el usuario determina el valor al desplazarse
desde la posicin mnima hasta la posicin deseada. La apariencia exacta de este
tem, as como la del resto, depende enteramente de la implementacin hecha por el
fabricante del dispositivo.
Un gauge no interactivo es controlado por la aplicacin, con la ventaja de que de puede
ser actualizado en cualquier momento. Tambin se puede configurar en modo
continuo, lo cual har que se muestre como un progreso que no tiene fin pero que se
est ejecutando; esto se logra estableciendo su valor mnimo como indefinido
(Gauge.INDEFINITE)
y
su
valor
mximo
como
continuo
(Gauge.CONTINUOUS_RUNNING).
Ejemplo 10. Uso de Gauge.
package hello;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Gauge;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.*;
/**
* @author jesus.a.rueda
*/
public class GaugeExample extends MIDlet implements CommandListener,Runnable {
private Display pantalla;
private Form formulario;
private Command cmdSalir;
private Command cmdIniciar; // Comando para iniciar el clculo
private Command cmdDetener; // Comando para detener el clculo
private StringItem siResultado; // Texto resultado
private StringItem siNumero; // Nmero de trmino actual
private TextField tfNumero; // Nmero de trmino mximo
private Gauge gVelocidad;
// Velocidad de la operacin de clculo
private Gauge gProgresoTarea; // Progreso del clculo
private Gauge gProgresoContinuo; // Indicador de progreso general
private boolean detener = false; // Variable para indicar si el clculo debe ser detenido
public void startApp() {
pantalla = Display.getDisplay(this);
formulario = new Form("Calculo de la Sumatoria");
// Progreso interactivo para establecer la velocidad del clculo
gVelocidad = new Gauge("Velocidad", true,10,8);
// Progreso no interactivo, para mostrar el progreso del clculo mientras se realiza
gProgresoTarea = new Gauge("Progreso", false, 1000, 0);
// Progreso no interactivo y continuo, para mostrar que el sistema est realizando una tarea
gProgresoContinuo = new Gauge("Tarea en Progreso",false,Gauge.INDEFINITE,Gauge.CONTINUOUS_RUNNING);
siResultado = new StringItem("Resultado","0");
siNumero = new StringItem("Termino No.","0");
cmdIniciar = new Command("Iniciar",Command.OK,0);
cmdDetener = new Command("Detener",Command.CANCEL,0);
cmdSalir = new Command("Salir", Command.EXIT,0);
tfNumero = new TextField("Numero maximo", "1000", 256,TextField.NUMERIC);
formulario.append(new StringItem("Informacion","El programa calcula la sumatoria de los numeros hasta el valor
especificado como valor maximo"));
formulario.append(tfNumero);
formulario.append(gVelocidad);
formulario.append(siResultado);
formulario.append(siNumero);
formulario.append(gProgresoTarea);
formulario.addCommand(cmdIniciar);
formulario.addCommand(cmdSalir);
formulario.setCommandListener(this);
pantalla.setCurrent(formulario);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public void commandAction(Command c, Displayable d) {
if(c == cmdSalir)
this.notifyDestroyed();
if(c==cmdIniciar){
formulario.removeCommand(cmdIniciar); // Se quita el comando de iniciar
formulario.addCommand(cmdDetener); // Se agrega el comando de parar el clculo
detener = false;
formulario.insert(1, gProgresoContinuo); // Se inserta en la posicin 1 (debajo del texto de informacin) el indicador de
progreso continuo
Thread hilo = new Thread(this); // Se crea un hilo para que ejecute la operacin de clculo en paralelo
hilo.start();
// Se inicia el hilo
}
if(c==cmdDetener){
detener = true;
// Se le indica al clculo que debe detenerse
}
}
this.notifyDestroyed();
}
}
if(operacion.equals("C")){
valorActual = 0;
}
tfEntrada.setString("0"); // Se limpia la entrada
siResultado.setText(String.valueOf(valorActual)); // Se visualiza el nuevo valor en el texto
}
public void commandAction(Command c, Displayable d) {
if(c ==cmdSalir)
notifyDestroyed();
}
}
Listas (List)
Una lista List es un Displayable que contiene una lista de opciones. Al ser displayable
esta lista ocupa toda la pantalla, a diferencia del tem ChoiceGroup. Su funcionalidad,
sin embargo, es muy similar a la del tem ChoiceGroup. La lista est diseada para
ejecutarse de 3 modos posibles: a) Exclusiva (Choice.EXCLUSIVE), donde se podr
seleccionar slo 1 elemento de la lista; b) Implcita (Choice.IMPLICIT), donde al
seleccionar un tem se ejecutar el comando que se ha definido para la lista con el
mtodo setSelectCommand; c) o Mltiple (Choice.MULTIPLE), donde se podrn
seleccionar varios elementos de la lista. Este Displayable es sumamente til para
generar mens de navegacin dentro de la aplicacin.
Ejemplo 13. Uso de List.
package hello;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.List;
import javax.microedition.midlet.*;
/**
* @author jesus.a.rueda
*/
public class ListExample extends MIDlet implements CommandListener {
private Display pantalla;
private List menu; // Men principal
private List subMenu; // Submen
private Command cmdSalir;
TextBox
Este Displayable muestra un cuadro de texto. Es muy similar al tem TextField de
formularios, con la diferencia que este se muestra en toda la pantalla del dispositivo,
permitiendo capturar grandes extensiones de texto con ms facilidad. La apariencia de
ste es especfica de la implementacin del fabricante del dispositivo.
Posee, al igual que el TextField, la posibilidad de establecer un filtro para que slo
permita un limitado juego de caracteres.
Ejemplo 14. Uso de Textbox: Cifrado Csar
package hello;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.*;
/**
* @author jesus.a.rueda
*/
public class TextBoxExample extends MIDlet implements CommandListener {
private Display pantalla;
private Command cmdSalir;
private Command cmdLimpiar; //Comando para limpiar la pantalla
private Command cmdEncriptar; //Comando para realizar la encriptacin
private Command cmdDesencriptar; //Comando para desencriptar el texto
private TextBox cuadroTexto; // Cuadro de texto
private String alfabeto = "abcdefghijklmnopqrstuvwxyz0123456789 "; // Alfabeto que contiene los caracteres a usar
int clave = 3; // Clave de encriptacin
public void startApp() {
pantalla = Display.getDisplay(this);
// Se crea el cuadro de texto con el mensaje incial
cuadroTexto = new TextBox("Encriptacion Cesar", "Hola Mundo", 256, TextField.ANY);
cmdSalir = new Command("Salir",Command.EXIT,0);
cmdEncriptar = new Command("Encriptar", Command.SCREEN, 0);
cmdDesencriptar = new Command("Desencriptar", Command.SCREEN, 1);
cmdLimpiar = new Command("Limpiar", Command.SCREEN, 2);
cuadroTexto.addCommand(cmdEncriptar);
cuadroTexto.addCommand(cmdDesencriptar);
cuadroTexto.addCommand(cmdLimpiar);
cuadroTexto.addCommand(cmdSalir);
cuadroTexto.setCommandListener(this); // Se establece el MIDlet como gestor de comandos del cuadro de texto
pantalla.setCurrent(cuadroTexto); // Se establece el cuadro de texto sobre la pantalla
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
// Funcin encargada de encriptar/desencriptar
private String Encriptar(String texto, int clave) {
String encriptado = "";
for (int i = 0; i < texto.length(); i++) {
char letra = texto.charAt(i); // Letra para realizar el corrimiento
int indice = alfabeto.indexOf(letra); // ndice de la letra dentro del alfabeto
if (indice < 0) {
// La letra no esta dentro del alfabeto, arroja una excepcin
throw new IllegalArgumentException("El caracter " + (i + 1) + ": '" + letra + "' no es valido");
} else {
int nuevoI = indice + clave; // Corrimiento del ndice de la letra ms la clave
if(nuevoI<0){
// En el caso de ser negativo (clave negativa para desencriptar), se usa el ndice corriendo desde atras //de la cadena
nuevoI = alfabeto.length() + nuevoI;
}
int indiceNuevo = nuevoI % alfabeto.length(); // Se usa el mdulo para asegurar caer dentro del rango de alfabeto
encriptado += String.valueOf(alfabeto.charAt(indiceNuevo)); // Se agrega la letra encriptada a la cadena
}
}
return encriptado;
}
public void commandAction(Command c, Displayable d) {
if (c == cmdSalir) {
notifyDestroyed();
}
if (c == cmdEncriptar) {
//Se obtiene el texto dentro del cuadro de texto y se pasa a minscula
String texto = cuadroTexto.getString().toLowerCase();
try {
String encriptado = Encriptar(texto, clave); // Se encripta con la funcion
cuadroTexto.setString(encriptado); // Se establece el texto encriptado en el cuadro de texto
} catch (IllegalArgumentException ex) {
// Hubo un error, se muestra un alert con el mensaje
pantalla.setCurrent(new Alert(ex.getMessage()), cuadroTexto);
}
}
if (c == cmdDesencriptar) {
String texto = cuadroTexto.getString().toLowerCase();
try {
String desencriptado = Encriptar(texto, -1*clave); // Se usa la clave negativa para desencriptar
cuadroTexto.setString(desencriptado);
} catch (IllegalArgumentException ex) {
pantalla.setCurrent(new Alert(ex.getMessage()), cuadroTexto);
}
}
if( c == cmdLimpiar){
cuadroTexto.setString(null); // Se limpia el texto en el cuadro
}
}
}
Alert
Este Displayable, como hemos visto en ejemplos anteriores, es til para mostrar
mensajes al usuario; est diseado para llamar la atencin del usuario en forma de una
alerta. En los ejemplos anteriores lo hemos usado de la forma mas bsica, pero un
alert tiene ms opciones de configuracin que slo mostrar un mensaje; por ejemplo,
puede contener un ttulo, mostrar una imagen, y al ser Displayable tambin puede
contener comandos, lo que hace que pueda ser usado para tomar decisiones basado
en su texto.
El constructor de un Alert recibe los siguientes parmetros en su forma mas larga y
completa:
Alert a = new Alert(String titulo,String texto,Image imagen,AlertType tipo);
Aqu titulo es el ttulo del alert, texto el texto que contiene el alert, imagen una
imagen asociada que se mostrar en el alert, y tipo uno de los posibles tipos de alerta
que se encuentran en J2ME que son AlertType.ALARM, AlertType.CONFIRMATION,
AlertType.ERROR, AlertType.INFO y AlertType.WARNING. Cada uno de ellos le
sugiere a la implementacin del dispositivo como debe mostrar el alert; la forma exacta
como se muestra depende enteramente del dispositivo.
Adicionalmente un Alert puede contenter un Gauge para mostrar algn progreso. Esto
se hace por medio del mtodo Alert.setIndicator(Gauge), y con la propiedad
Alert.setTimeout(int) se establecen los milisegundos que el alert debe exhibirse en
pantalla antes de cambiar a otro Displayable. Un valor especial Alert.FOREVER le dice
al alert que debe durar hasta que el programa diga lo contrario.
El Alert es un tipo especial de Displayable, ya que es un error mostrar en pantalla un
alert y despus otro. Se debe mostrar un Displayable diferente de un alert antes de
mostrar el siguiente, o se generar una excepcin.
Ejemplo 15. Uso del Alert. Tipos de alert.
package hello;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Gauge;
import javax.microedition.lcdui.List;
import javax.microedition.midlet.*;
/**
* @author jesus.a.rueda
*/
public class AlertExample extends MIDlet implements CommandListener {
private Display pantalla;
private Command cmdSalir;
private Command cmdMostrar; // Comando para mostrar los tipos de alert
private Command cmdCancelar;
private Command cmdOk;
private Alert alrtConfirmacion; // Alerta de confirmacin
private List tipos;
public void startApp() {
pantalla = Display.getDisplay(this);
tipos = new List("Tipos de Alerta", List.IMPLICIT, new String[]{"Simple", "Progreso", "Permanente", "Error", "Informacion",
"Alarma", "Advertencia"}, null);
cmdMostrar = new Command("Mostrar", Command.OK, 0);
cmdSalir = new Command("Salir", Command.EXIT, 0);
cmdCancelar = new Command("Cancelar", Command.CANCEL, 0);
break;
case 2:
Alert a2 = new Alert("Alerta", "Este Alert no se cerrara hasta que no presione el comando OK", null,
AlertType.WARNING);
a2.setCommandListener(this);
a2.removeCommand(Alert.DISMISS_COMMAND);
a2.setCommandListener(this);
a2.addCommand(cmdOk); // Se agrega el comando cmdOk al alert a2
a2.setTimeout(Alert.FOREVER);
pantalla.setCurrent(a2, tipos);
break;
case 3:
pantalla.setCurrent(new Alert("ERROR", "Alerta Tipica de Error", null, AlertType.ERROR), tipos);
break;
case 4:
pantalla.setCurrent(new Alert("Informacion", "Alerta tipica de Informacion", null, AlertType.INFO));
break;
case 5:
pantalla.setCurrent(new Alert("Alarma", "Alerta tipica de Alarma", null, AlertType.ALARM));
break;
case 6:
pantalla.setCurrent(new Alert("Advertencia", "Alerta tipica de Advertencia", null, AlertType.WARNING));
break;
}
}
}
}
4. COMUNICACIN
Como se ha mencionado anteriormente, J2ME ha sido diseado para equipos con
capacidades limitadas. Las limitaciones de cmputo se compensan entonces con las
caractersticas de movilidad, y ms aun, de conectividad en la movilidad, por lo que las
posibilidades de aplicaciones se hacen infinitas en trminos de poder poseer un
terminal movil con la capacidad de conectarse a servidores de contenido e informacion
en cualquier momento.
Las opciones de conectividad de J2ME son variadas y ofrecen diferentes servicios o,
mejor dicho, diferentes protocolos de comunicacin, que van desde conexiones bsicas
de TCP/IP y UPD hasta protocolos ms elaborados como HTTP y WebServices.
En este tutorial nos centraremos en las conexiones web usando el protocolo HTTP,
ofreciendo as una forma fcil y rpida de entregar y recibir informacion con servidores
web.
HttpConnection
J2ME ofrece un framework gnerico para manejar la conectividad, esto es, ofrece una
interfaz comn para los diversos protocolos de comunicacin que soporta, creando un
sistema facil para el programador.
Existe un objeto nico que crea las conexiones, el objeto Connector, y se usa asi:
Connection conexion = Connector.open(String cadenaConexion);
Las funciones bsicas para crear conexiones HTTP se vern en el ejemplo que se
presenta a continuacin, pero antes hay que hacer nfasis en el hecho de que se
recomienda fuertemente que toda conexin se realize en un hilo, para evitar bloqueos
en hilo principal.
import javax.microedition.midlet.*;
/**
* @author jesus.a.rueda
*/
public class HttpConnectionExample extends MIDlet implements CommandListener, Runnable {
private Display pantalla;
private Command cmdSalir;
private Command cmdConsultar;
private Command cmdVolver;
private Form formulario;
private TextField tfURL;
private TextField tfParametros;
private Gauge gProgreso;
private ChoiceGroup cgMetodo;
public void startApp() {
pantalla = Display.getDisplay(this);
formulario = new Form("Comunicacion Http");
tfURL = new TextField("URL", "http://www.javacourses.com/hello.txt", 256, TextField.URL);
tfParametros = new TextField("Parametros", null, 256, TextField.URL);
cgMetodo = new ChoiceGroup("Metodo", ChoiceGroup.EXCLUSIVE, new String[]{"GET", "POST"}, null);
gProgreso = new Gauge("Consultando Servidor", false, Gauge.INDEFINITE, Gauge.CONTINUOUS_RUNNING);
cmdSalir = new Command("Salir", Command.EXIT, 0);
cmdConsultar = new Command("Contular Web", Command.OK, 0);
cmdVolver = new Command("Volver", Command.BACK, 0);
formulario.append(tfURL);
formulario.append(tfParametros);
formulario.append(cgMetodo);
formulario.addCommand(cmdConsultar);
formulario.addCommand(cmdSalir);
formulario.setCommandListener(this);
pantalla.setCurrent(formulario);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public void run() {
Form respuesta = new Form("Resultado de la consulta");
// Los mtodos que soporta el objeto HttpConnection son HttpConnection.GET, HttpConnection.POST y
//HttpConnection.HEAD
String url = tfURL.getString();
String metodo = cgMetodo.getSelectedIndex() == 0 ? HttpConnection.GET : HttpConnection.POST;
// Los parmetros pueden ser enviados por QueryString (GET) o a travs de POST
String parametros = tfParametros.getString();
try {
// Buffer usado para almacenar la respuesta del servidor
StringBuffer buffer = new StringBuffer();
// Canal de Entrada, por donde van a venir los datos del servidor
InputStream is = null;
// Canal de Salida, por donde ira los parmetros si el mtodo es POST
OutputStream os = null;
// Manejador del canal de salida, es til para formatear correctamente los datos sobre el canal de salida
Como podemos ver en el ejemplo, el objeto HttpConnection nos sirve para conectarnos
con un servidor web para obtener informacin. Esta informacin puede no ser esttica
ya que podemos enviar parmetros al servidor tanto por GET como por POST, de esta
forma podemos recibir contenido de programas realizados en el servidor.
5. PERSISTENCIA DE DATOS
Las aplicaciones J2ME, debido a su caractersticas de portabilidad, no pueden
confiarse en el sistema de archivos del dispositivo sobre el cual residen dado que para
muchos fabricantes esto constituye un riesgo a la integridad de sus sistemas
.operativos, y por lo tanto del dispositivo como tal. Para minimizar este impacto, y
puesto que la importancia de la persistencia de los datos de la aplicacin es alta, J2ME
viene equipado con su propio modelo de persistencia de datos que garantiza que se
pueda encontrar en toda implementacin de J2ME.
El sistema que proporciona J2ME se denomina Record Management System (RMS), el
RMS es un sistema basado en almacenamientos (RecordStore) y registros (Records),
estos podrian imaginarse como tablas independientes que almacenan registros
identificados por una llave -el ndice del registro- y unos datos binarios que seran el
cuerpo del registro. El sistema RMS no es un sistema robusto de almacenamiento de
informacin como podra serlo una base de datos, pero se ajusta para el alcance de las
aplicaciones y de las capacidades de cmputo de los dispositivos moviles, proveyendo
una funcionalidad nesesaria.
Deben tomarse algunas consideraciones antes del uso del RMS: el tamao de la
informacin que se puede almacenar, tanto en la longitud de los registros como en la
cantidad de los mismos, es bastante limitada; de hecho, slo se puede asegurar que se
dispone de 8Kb por cada almacenamiento. El acceso a esta informacion es sobre
memoria no voltil, por lo que es bastante lento en comparacin con la informacin que
est en memoria. No hay que fiarse del rendimiento de los emuladores, dado que
estos usan al sistema operativo del PC para obtener acceso al RMS.
El punto mas complicado de usar el RMS es la serializacin, es decir, convertir nuestra
informacin a un arreglo de bytes para ser almacenada, y posterirmente, convertir este
arreglo de bytes de vuelta a la informacion u objetos desedos. Hay que recordar que si
hay semejanza con una tabla, esta sera una tabla que solo tiene 2 columnas, el
nmero de registro y los datos.
Ejemplo 15. Uso de RSS.
package hello;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Vector;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.DateField;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.*;
import javax.microedition.rms.RecordComparator;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
/**
* @author jesus.a.rueda
*/
public class RmsExample extends MIDlet implements CommandListener,RecordComparator {
private Display pantalla;
private Form formulario;
private TextField tfNombre;
private DateField dfFecha;
private ChoiceGroup cgRecordatorios;
private Command cmdSalir;
private Command cmdAgregar;
private Command cmdEliminar;
// Vector usado para relacionar los Recordatorios con los ndices del ChoiceGroup
private Vector recordatorios;
public void startApp() {
pantalla = Display.getDisplay(this);
formulario = new Form("Recordatorios Cumpleannos");
cgRecordatorios = new ChoiceGroup("Recordatorios", ChoiceGroup.MULTIPLE);
cgRecordatorios.setFitPolicy(ChoiceGroup.TEXT_WRAP_ON);
dfFecha = new DateField("", DateField.DATE); //se crea en modo DATE para solo escoger la fecha
tfNombre = new TextField("Nombre", null, 256, TextField.ANY);
cmdSalir = new Command("Salir", Command.EXIT, 0);
cmdAgregar = new Command("Agregar", Command.OK, 0);
cmdEliminar = new Command("Eliminar", Command.SCREEN, 0);
formulario.append(tfNombre);
formulario.append(dfFecha);
formulario.append(cgRecordatorios);
formulario.addCommand(cmdSalir);
formulario.addCommand(cmdAgregar);
formulario.addCommand(cmdEliminar);
formulario.setCommandListener(this);
recordatorios = new Vector();
pantalla.setCurrent(formulario);
try {
// Se obtienen los recordatorios guardados previamente en el RMS
ObtenerRecoratoriosDelRMS();
} catch (Exception ex) {
// Si ocurre error
ex.printStackTrace();
pantalla.setCurrent(new Alert(ex.getMessage()), formulario);
}
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
// funcion para obtener el nombre del mes
private String getNombreMes(int mes) {
switch (mes) {
case 1:
return "Enero";
case 2:
return "Febrero";
case 3:
return "Marzo";
case 4:
return "Abril";
case 5:
return "Mayo";
case 6:
return "Junio";
case 7:
return "Julio";
case 8:
return "Agosto";
case 9:
return "Septiembre";
case 10:
return "Octubre";
case 11:
return "Noviembre";
case 12:
return "Diciembre";
default:
return null;
}
}
public void commandAction(Command c, Displayable d) {
if (c == cmdSalir) {
this.notifyDestroyed(); // salir
}
if (c == cmdAgregar) {
String text = tfNombre.getString();
Date date = dfFecha.getDate();
// Se crea un nuevo objeto recordatorio, con el nombre y la fecha
Recordatorio recordatorio = new Recordatorio(text, date);
// Se deserializa el recordatorio
Recordatorio recordatorio = DeserializarRecordatorio(data);
// Se le asigna el ID
recordatorio.setID(ID);
// Se agrega a los controles de interfaz grfica
AgregarRecordatorio(recordatorio, false);
}
// Se cierra el almacen
almacen.closeRecordStore();
}
6. LOCALIZACION
La funcion de localizacin para J2ME no est incluida en todos los dispositivos; se
distribuye como un paquete opcional (JSR 179), disponible en la mayoria de
dispositivos de gama media - alta, especialmente aquellos dotados con dispositivos
GPS.
El API de localizacin provee funcionalidades de ubicacin no solo en trminos
estrictos de coordenadas latitud y longitud, sino que tambien para metodos basados en
la topologia de la red, cuando el operador lo permita, y otros sistemas basados en
referencias.
Para efectos de este tutorial, nos centraremos en el uso y captura de coordenadas
geogrficas con el uso de dispositivos dotados de GPS.
La clase LocationProvider nos brinda toda la funcionalidad para poder obtener la
posicion actual del dispositivo, para notificar la posicion actual y los cambios de esta
con el tiempo.
Se puede registrar un objeto que implemente la interfaz
LocationListener, la cual se registrara con un intervalo de tiempo en la cual se
consultara la posicin con el GPS.
Ejemplo 16. Localizacin.
package hello;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.StringItem;
import javax.microedition.location.Coordinates;
import javax.microedition.location.Criteria;
import javax.microedition.location.Location;
import javax.microedition.location.LocationException;
import javax.microedition.location.LocationListener;
import javax.microedition.location.LocationProvider;
import javax.microedition.midlet.*;
/**
* @author jesus.a.rueda
*/
public class LocalizationExample extends MIDlet implements CommandListener, LocationListener {
private Display pantalla;
BIBLIOGRAFA