PROGRAMACIÓN MIDP  

Posted by Danny in

PROGRAMACIÓN MIDP

En el presente capítulo se tratarán las características básicas de la programación de aplicaciones MIDP, NO se trata de un tutorial de programación, únicamente se revisarán los aspectos generales que hacen a la programación MIDP diferente de el resto de las aplicaciones Java. En el siguiente capítulo se desarrollará una aplicación y se explicará el funcionamiento de cada instrucción o bloque de instrucciones.

Pero primero se deben conocer los pasos a seguir en el proceso de desarrollo para facilitar su comprensión y dar una idea previa de lo que se deberá hacer.

5.1.Herramientas necesarias

A continuación se proporciona una lista con las herramientas necesarias para programar MIDlets.

-Plataforma de desarrollo Java (J2SDK, por ejemplo) disponible en java.sun.com.

-Editor de textos (block de notas, edit, vi, emacs, etc.).

-Compilador CLDC (1.0, 1.1) y al menos un perfil (MIDP, PDAP), ambos disponibles en java.sun.com.

Hay algunos paquetes de desarrollo Java que incluyen los dos últimos requisitos, además de proveer de otras herramientas que pueden facilitar la programación.

-Java Wireless Toolkit: Este paquete se puede descargar del sitio Java de Sun Microsystems, provee de un compilador (incluye CLDC y MIDP) y organizador de proyectos. Se crea en este programa un proyecto y automáticamente se generan las carpetas donde se han de guardar los códigos fuente, las clases, imágenes y otros accesorios que la aplicación utilice. Disponible para Windows y Linux. En la figura 5.1 se muestra la barra de herramientas de JWT (Java Wireless Toolkit).

Figura 5.1. Java Wireless Toolkit.

-Nokia Developer Suite for J2ME: En la sección de desarrolladores de Nokia (www.nokia.com) se puede descargar este entorno de desarrollo, incluye todo lo que se necesita para la programación de MIDlets (a excepción del SDK). Se puede instalar en plataformas Windows 2000, XP y Linux.

Este paquete puede resultar poco conveniente para computadoras poco actuales, ya que entre sus requerimientos se mencionan 256 MB de memoria RAM y procesador de 300 Mhz.

-Motorola SDK for J2ME. Sólo existe para Windows, es otro kit de desarrollo completo al que sólo hay que agregar el SDK de Java.

-Code Warrior. Quizá uno de los mejores entornos integrados de desarrollo (IDE) para la edición micro de la plataforma Java. Se puede descargar gratis después de suscribirse en el sitio de programadores de Motorola, aunque en versión de evaluación por treinta días.

-Sun ONE Studio: Otro entorno completo, bastante útil, incluye editor de texto, compilador, preverificador y simuladores para probar las aplicaciones. En el sitio oficial de Sun se puede descargar una evaluación de 60 días o comprar la versión completa.

En el presente documento se utilizará el Wireless Toolkit de Java, debido a que es más pequeño (en espacio de disco) y, por lo tanto, más fácil de obtener con una conexión telefónica a Internet, además de que está disponible para Linux que será la plataforma empleada para la programación.

5.2. Ciclo de desarrollo de una aplicación MIDP

Las aplicaciones MIDP (MIDlets) siguen un proceso desde que son ideadas hasta que están instaladas y ejecutándose en los dispositivos. Dicho proceso es el siguiente:

-Escritura.

-Compilación y preverificación.

-Prueba y corrección.

-Empaquetado.

-Prueba del paquete.

5.2.1. Escritura de la aplicación

Hay algunas reglas para el desarrollo de MIDlets, además de las establecidas por el lenguaje, que deben ser consideradas:

-Toda MIDlet debe importar los paquetes javax.microedition.midlet.* y javax.microedition.lcdui.*.

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

-javax.microedition.midlet.*. Define que se utilizará MIDP.

-javax.microedition.lcdui.*. Proporciona las apis de interfaz de usuario.

-Cada MIDlet debe extender la clase MIDlet.

public class FirstMIDlet extends MIDlet {

-Una MIDlet no debe tener ningún método public static void main(), contrario a lo que sucede en las aplicaciones Java de escritorio.

Constructor de la clase

public FirstMIDlet() { }

Inicia la MIDlet, en lugar de main().

public void startApp() { }

5.2.2. Compilar y preverificar

Cuando se utiliza Java Wireless Toolkit, o algún otro entorno de desarrollo, el proceso de compilación y preverificación es sumamente sencillo:

Una vez escrito el código de las clases que compongan la aplicación se ejecuta JWT y se abre la aplicación a compilar. En JWT se puede también depurar el código, probar y empaquetar la aplicación, etc.

Para compilar la MIDlet, una vez abierta, hay que seleccionar la opción "Build", esto creará el archivo de clase o bien indicará los errores que se tengan. El compilado con JWT incluye la preverificación.

También se puede compilar y preverificar el código fuente desde la linea de comando del sistema operativo. Teniendo correctamente instalado el SDK de Java y CLDC se utiliza:

javac -d .| bootclasspath [ruta] [archivo.java]

para crear el archivo de clase en el mismo directorio (-d .\) que el de código y para preverificar el resultado de la compilación se utiliza el comando:

preverify -classpath [ruta_clases]

este comando preverifica todos los archivos de clases en el directorio ruta_clases y guarda el resultado en un subdirectorio, dentro de esa ruta, llamado "output", para preverificar una sola clase hay que especificar su nombre.

5.2.3. Probando la MIDlet

Si no se utiliza JWT la aplicación puede ser probada, desde linea de comandos, con la siguiente instrucción:

midp [nombre_MIDlet]

Aunque si su aplicación consta de varias MIDlets o archivos de clase y requiere dejar que el usuario escoja cuales ejecutar, entonces es necesario empaquetar la aplicación.

Utilizando JWT este trabajo se simplifica bastante, sólo se abre un proyecto y, si ya está compilado y preverificado, se selecciona "Run" o "Ejecutar" para ver el resultado en un emulador (Fig. 5.2).

Figura 5.2. Una de las vistas del emulador de JWT

5.2.4. Empaquetado

Si una aplicación consta de múltiples clases, una archivo .jar es usado para agruparlas, así es más fácil de distribuir y desplegar. esto se puede hacer desde linea de comandos de la siguiente manera:

jar cf [archivo.jar] [clases]

El siguiente paso es crear el archivo descriptor de la aplicación (archivo .jad), el cual provee información sobre el contenido del archivo .jar. Un ejemplo de archivo descriptor de aplicación es el siguiente:

MIDlet-Name: MID1

MIDlet-Version:1.0.0

MIDlet-Vendor:Sun Microsystems, Inc.

MIDlet-Description: Primera MIDlet

MIDlet-Info-URL: http://java.sun.com/j2me.

MIDlet-Jar-URL: MID1.jar

MIDlet-Jar-Size: 1063

MicroEdition-Profile: MIDP-2.0

MicroEdition-Configuration: CLDC-1.0

MIDlet-1: MID,icono.png, MIDlet1

MIDlet-2: MID1,MIDlet2

Las primeras lineas resultarán, seguramente, más que obvias así que se explicará únicamente el último elemento (MIDlet-1), este contiene los datos de la primera MIDlet integrante del paquete (hay que recordar que un paquete se puede componer de muchas MIDlets) y consta de tres partes: nombre de la aplicación, ícono (opcional) y clase. El nombre aparecerá en la pantalla del dispositivo, acompañado del ícono (si existe), para que pueda ser seleccionado y la clase es el archivo compilado que se ejecuta al seleccionar un nombre.

5.2.5. Probar la aplicación empaquetada

Una vez que se ha empaquetado la aplicación, se puede probar para asegurar su funcionamiento agregando la opción -descriptor al comando midp.

midp -descriptor MID1.jad

Utilizando en kit de Java es el mismo proceso que probar la aplicación sin empaquetar, ya que al realizar el paquete se genera automáticamente el archivo descriptor.

5.3. Mapeo de teclas

Se le llama mapeo de teclas a la distribución que tienen las funciones del dispositivo (navegación, comandos, selección, etc.) sobre las teclas exteriores, es decir, la función desplazarse hacia la derecha, puede estar colocada en la tecla con el número 6 de un teléfono y esa misma función puede operar sobre la tecla "é" de otro dispositivo.

Cuando el programador requiere de aplicaciones altamente portables debe darle a este aspecto una gran importancia, no se puede permitir que un comando o función de su MIDlet quede inhabilitada a causa de un descuido de ese tipo.

5.4. Manejo de eventos

Cuando no se utilizan cajas de texto, listas o formularios en una pantalla, se puede tomar el control de las acciones a realizar cuando se presione, libere o mantenga presionada cierta tecla del dispositivo. A la presión (rápida o detenida) y liberación de teclas se les conoce como eventos, aunque no son el único tipo de eventos, también pueden serlo el cierre repentino y deliberado de la aplicación, la llegada de un mensaje o una llamada telefónica, el encendido del teléfono, en fin, un evento es toda acción llevada a cabo por un agente exterior a la MIDlet y que influya sobre su operación.

Un evento es, por tanto, una acción sobre la MIDlet, tomada por el usuario en tiempo de ejecución.

5.4.1.Llamadas

Se conoce como Llamada (Callback en inglés) a las invocaciones a métodos definidos por el programador que son ejecutados por la aplicación en respuesta a eventos.

Además de J2ME, los conceptos de llamadas y eventos son utilizados en muchos entornos de programación, principalmente aquellos con desarrollo de interfaces gráficas (Visual Basic, Delphi, Visual J, etc.).

En lenguajes como C++, las llamadas se implementan mediante apuntadores, una función desvía su apuntador a otra al ocurrir un evento. Como Java no utiliza apuntadores, las llamadas se implementan mediante interfaces, las interfaces son clases que únicamente tienen métodos únicamente definidos, las acciones a tomar en cada método dependen del programador, es decir, una interfaz es como el esqueleto de una clase que debe ser llenado por el programador.

En MIDP hay cuatro clases de llamadas de interfaces de usuario.

-Comandos abstractos que son parte de la API de alto nivel.

-Eventos de bajo nivel que representan presión y liberación de teclas.

-Llamadas al método paint() de una clase Canvas.

-Llamadas al método Run de objetos ejecutables (de la interfaz Runnable) solicitados por una llamada al método CallSerially de la clase Dispaly.

5.4.2.Navegación en pantalla

Un aplicación MIDP, a excepción de las demasiado sencillas, siempre utilizará más de una pantalla, por lo que resulta necesaria una herramienta que permita a los usuarios desplazarse de una pantalla a otra según lo requiera la propia MIDlet.

El paquete javax.microedition.lcdui proporciona la clase Command, la cual captura la información de un evento. Un comando creado con la clase Command solamente contiene información sobre él mismo, no de la acción que realiza cuando está activado, la acción está definida en un objeto de la interfaz CommandListener asociado con la pantalla. A continuación se muestra como declarar un comando:

Command miComando=new Command("Mio", Command.SCREEN,2);

Los tres parámetros que el constructor de la clase Command debe incluir son los siguientes:

-Etiqueta: Una cadena de caracteres usada para la presentación visual del comando.

-Tipo: Especifica su intención, es decir, la acción que realizará el comando. Algunos tipos pueden ser:

-Command.SCREEN.

-Command.EXIT.

-Command.BACK.

-Command.ITEM

-Prioridad: Describe la importancia del comando con respecto a otros en pantalla. Una prioridad de 1 indica al comando más importante.

Cuando una MIDlet se ejecuta, el dispositivo escoge el lugar de un comando basándose en su tipo (abajo y a la izquierda para salir, por ejemplo) y coloca los comandos similares con base en su valor de prioridad. Considérese una aplicación con los siguientes comandos:

Command Salir=new Command("Exit", Command.EXIT,1);

Command miCom=new Command("Mio1", Command.SCREEN,2);

Command miCom2=new Command("Mio2", Command.SCREEN,2);

En este ejemplo, el manejador de la aplicación coloca el comando Exit en la pantalla y crea un menú para mantener Info y Buy. Presionando la tecla correspondiente al menú, el usuario, es llevado a otra pantalla donde puede seleccionar alguna de las dos opciones. (Fig. 5.3)

La clase Command provee de tres métodos para conocer tipo, etiqueta y prioridad del comando.

-int getCommandType().

-String getLabel().

-int getPriority().

Figura 5.3. Ejemplo de la clase Command.

5.4.3. Eventos de alto nivel

El manejo de eventos en la api de alto nivel se basa en un modelo de escucha o escuchante (listener, en inglés). Los objetos Screen y Canvas pueden tener "escuchantes" para comandos. Para que un objeto pueda ser un escuchante, debe implementar la interfaz CommandListener.

Los comandos se agregan a un objeto con el método addCommand y se registra un escuchante con el método CommandListener. Ambos métodos pertenecen a la clase Displayable y son heredados por Screen y Canvas.

5.4.3.1.La interfaz CommandListener

Esta interfaz es para MIDlets que necesitan recibir eventos de alto nivel. Esta interfaz tiene un método que todo escuchante debe implementar, el método CommanAction.

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

El parámetro c es un objeto Command que identifica al comando que fue agregado al d (objeto Displayable) con el método addCommand. El parámetro d es el objeto visible (Form, Canvas, Screen) donde el evento ocurre. Dentro de las llaves ({ }) se introduce el código que se habrá de ejecutar al ocurrir un evento.

public void commandAction(Command c, Displayable s) {

if (c == CmdSalir) {

destroyApp(false);

notifyDestroyed();

}

En el trozo de código mostrado arriba se emplea una decisión if para identificar qué comando es el que ha sido activado, si se trata del comando CmdSalir se destruye la aplicación, es decir, se cierra y se notifica su destrucción.

5.4.3.2.La interfaz ItemStateListener

Las aplicaciones usan esta interfaz para recibir eventos que indican cambios en el estado interno de los elementos en una pantalla, formulario. Esto pasa cuando el usuario hace cualquiera de las siguientes cosas.

-Ajustar el valor de una barra de avance interactiva.

-Ingresar o modificar el valor de un TextField.

-Ingresar una nueva fecha u hora en una DateField.

-Cambiar los valores seleccionados en un ChoiceGroup.

Esta interfaz tiene un único método que un escuchante debe implementar.

public void itemStateChanged(Item i){ }

Para registrar un escuchante de esta interfaz se utiliza el método setItemStateListener.

ItemStateListener listener = new ItemStateListener();

Form.setItemStateListener(listener);

public void itemStateChanged(Item item) {

}

5.4.4.Eventos de bajo nivel

Si se usa la clase Canvas para tener acceso a eventos de entrada o para dibujar gráficos en la pantalla, es necesario manejar los eventos de bajo nivel. Aplicaciones como los juegos, pueden ser realizadas utilizando la clase Canvas, gracias a que esta posee métodos para controlar eventos de teclas y los llamados "eventos de juego". Los eventos de teclas se registran como códigos específicos que están directamente relacionados a las teclas del aparato. Los eventos de juego producen un código relacionado con la acción asignada a una tecla del dispositivo.

5.4.4.1.Eventos de teclas

Como ya se mencionó, los eventos de teclas están relacionados directamente con las teclas del dispositivo. Los eventos de teclas definidos en la clase Canvas son:

-KEY_NUM0.

-KEY_NUM1.

-KEY_NUM2.

-KEY_NUM3.

-KEY_NUM4.

-KEY_NUM5.

-KEY_NUM6.

-KEY_NUM7.

-KEY_NUM8.

-KEY_NUM9.

-KEY_STAR.

-KEY_POUND.

Los números del 0 al 9, el asterisco "*" y la almohadilla "#" son las teclas genéricas en todos los dispositivos, quizá existan otros eventos en diferentes dispositivos, pero por motivos de portabilidad, se recomienda solamente usar estos.

5.4.4.2.Eventos de juego

Debido a que en los equipos actuales varía mucho la distribución de las teclas, si se requiere una localización específica de estas, flechas de dirección, por ejemplo; es necesario utilizar los eventos de juego, estos eventos son los siguientes:

-DOWN.

-LEFT.

-RIGHT.

-UP.

-FIRE.

-GAME_A.

-GAME_B.

-GAME_C.

-GAME_D.

Anteriormente se explicó que cada aparato mapea sus teclas de forma diferente al resto. Con los eventos de juego se puede lograr que la aplicación reaccione a la presión de una tecla que indique movimiento hacia arriba en el dispositivo anfitrión, independientemente del código de esta tecla.

5.4.5.Métodos de manejo de eventos

Para el manejo de eventos de bajo nivel, J2ME provee al programador de los siguientes métodos:

-protected void keyPressed (int keyCode).

-protected void keyReleased (int keyCode)

-protected void keyRepeated (int keyCode)

-protected void pointerPressed (int x, int y)

-protected void pointerDragged (int x, int y)

-protected void pointerReleased (int x, int y)

-protected void showNotify ()

-protected void hideNotify ()

-protected abstract void paint (Graphics g)

-commandAction(). De la interfaz CommandListener.

Cabe aclarar que los eventos de apuntador (pointer) no son aplicables a todos los dispositivos, sólo para aquellos que cuenten con un indicador de ese tipo (apuntador de ratón, por ejemplo), se puede comprobar si el equipo lo soporta utilizado los métodos hasPointerEvents y hasPointerMotionEvents. Otro método que podría no estar disponible en algún dispositivo es keyRepeated, se puede comprobar su operabilidad con el método hasRepeatEvents.

5.5. Principales componentes

Son muchos y muy variados los componentes que incluyen las apis de MIDP y CLDC, además cada programador puede crear componentes propios tomando como base los ya existentes.

Por lo anterior, se explicarán sólo aquellos que son considerados cómo básicos para la realización de aplicaciones en general.

En la tabla 5.1 se muestra cada uno de los componentes y una breve descripción de estos.

Tabla 5.1. Clases del paquete lcdui.

Clase

Descripción

Alert

Pantalla que muestra un mensaje al usuario y espera un cierto periodo de tiempo antes de pasar a la siguiente pantalla.

AlertType

Indica la naturaleza de las alertas (exclamación, error, etc.).

Canvas

Es la base para la escritura de aplicaciones que utilicen eventos de bajo nivel y para dibujar objetos gráficos en la pantalla.

ChoiceGroup

Un grupo de elementos seleccionables, colocados dentro de una forma (Form).

Command

Una estructura que encapsula la información semántica de una acción (p. ej. "Salir").

DateField

Componente modificable para presentar en pantalla la información de hora y fecha.

Display

Representa el manejador de pantalla y dispositivos de entrada (teclas) del sistema.

Displayable

Característica de un objeto que tiene la capacidad de ser mostrado en la pantalla.

Font

Representa las propiedades de la fuente (letra).

Form

Una pantalla que contiene una mezcla arbitraria de elementos (imágenes, cajas de texto, etc.)

Gauge

Una barra que puede ser utilizada como indicador de avance en un proceso.

Graphics

Provee la capacidad de presentar gráficos 2D simples.

Image

Muestra una imagen.

ImageItem

Proporciona el control de trazado (colocación) de una imagen en una forma o alerta

Item

Superclase para elementos que van a ser adheridos a una forma o alerta.

List

Muestra una lista de opciones.

Screen

La superclase de todas las clases de interfaz de usuario de alto nivel.

StringItem

Un elemento que puede contener una cadena de caracteres.

TextBox

Pantalla que permite al usuario insertar y modificar texto.

TextField

Un componente de texto modificable que puede ser colocado en una forma.

Ticker

Un texto que cruza continuamente la pantalla, puede ser agregado en todos los tipos de pantalla a excepción de canvas.

En los siguientes apartados se verá como utilizar algunas de las clases listadas en la tabla anterior, esto mediante la explicación de programas sencillos que, aunque pudiesen carecer de utilidad, ilustran de forma clara la forma de implementar una clase determinada.

5.5.1.¡Hola mundo!

Se iniciará esta serie de programas de ejemplo con el clásico código fuente de una aplicación que lo único que hace es mostrar un mensaje en la pantalla, en este caso el mensaje es "¡Hola mundo!".

El código fuente es el siguiente:

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

Se comienza por importar los paquetes que son obligatorios para cualquier MIDlet. Esto puede variar dependiendo de la finalidad de la clase a crear, pero para una clase que será la principal de su paquete, es forzoso el importar las clases del paquete javax.microedition.midlet y lcdui se requiere para las operaciones de entrada y salida de información.

public class Holamundo extends MIDlet implements CommandListener {

Se inicia el código de la clase, la cual extiende (o hereda) la clase MIDlet, necesaria, como ya se dijo, para la creación de clases ejecutables, además se implementa la interfaz CommandListener, esta interfaz define una estructura de clase en la que se deben declarar unos objetos llamados comandos, los cuales responderán a alguna acción del usuario.

private Form Forma1;

Se ha instanciado un objeto de la clase Form, que, como ya se vio, pertenece al paquete lcdui. Un objeto Form define una pantalla donde se agregarán objetos de entrada y salida de datos por teclado y pantalla, respectivamente.

public Holamundo() {

Forma1 = new Form("¡Hola mundo!");

Forma1.append(new StringItem(null, "¡Hola mundo!"));

Forma1.addCommand(new Command("Salir", Command.EXIT, 1));

Forma1.setCommandListener(this);

}

En la sección de arriba se describe el constructor de la clase, el cual debe llevar el mismo nombre que la clase, sin especificar tipo y de acceso público. En un constructor de clase se establecen los valores que han de tomar las variables, se crean las instancias de las clases, en fin, se define como habrá de presentarse, al arrancar, la aplicación al usuario. Al iniciar el constructor se instancia un objeto Form con título "¡Hola mundo!" y de nombre Forma1, enseguida, a esa misma forma se le agrega un elemento SringItem sin etiqueta (título o descripción) y con un contenido igual a "¡Hola mundo!", se agrega también, un comando, los comandos son las opciones que, en un teléfono celular, aparecen en la parte inferior de la pantalla y que el usuario puede seleccionar presionando las teclas que se encuentran debajo del texto; ese comando tiene por texto o etiqueta la palabra "Salir", es del tipo EXIT y de prioridad 0. En un comando, la prioridad indica la importancia de ese comando con respecto a otros en la pantalla, dicha prioridad puede ir de 1 a 10, siendo 1 el valor de prioridad más alto.

public void startApp() {

Display.getDisplay(this).setCurrent(Forma1);

}

El método startApp es el que se ejecuta después del constructor, en el se encuentran las instrucciones que serán ejecutadas por la aplicación (es como el procedimiento main de las aplicaciones en C o Java). En el ejemplo, se utiliza un objeto Display que se encarga del control de la pantalla, un método getDisplay(this), el cual arroja como resultado la pantalla del dispositivo (como salida de datos para la MIDlet this, la actual) y otro método setCurrent(Forma1), que indica que lo que se ha de mostrar en la pantalla será lo contenido en Forma1.

public void pauseApp() {}

public void destroyApp(boolean unconditional) {}

public void commandAction(Command c, Displayable s) {

notifyDestroyed();

}

}

Las funciones pauseApp y destroyApp, también son obligatorias de cualquier clase MIDP (sea la principal del proyecto o no), en pauseApp se pueden definir las acciones a tomar cuando la aplicación sea pausada por el usuario, por la misma aplicación o por otra; destroyApp indica lo que se realizará antes de cerrar la aplicación. El método commandAction define lo que se hará con los comandos de la MIDlet, como en el ejemplo sólo se tiene un comando basta con notificar la destrucción de la aplicación,

5.5.2.TextBox

La clase TextBox, genera objetos de pantalla completa, como Form,la diferencia es que TextBox únicamente permite la introducción de texto y el manejo de comandos. A continuación se presenta un ejemplo sencillo:

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

public class TextBoxDemo extends MIDlet

implements CommandListener {

private Command CmdSalir;

private Display display;

private TextBox t = null;

De esta primera parte sólo hay que resaltar la creación de un objeto TextBox de nombre t y valor nulo.

public TextBoxDemo() {

display = Display.getDisplay(this);

CmdSalir = new Command("Salir", Command.EXIT, 2);

t = new TextBox("Hola", "Esto es una prueba", 256, 0);

t.addCommand(CmdSalir);

t.setCommandListener(this);

}

En el constructor de la MIDlet se observa la designación del contenido de la pantalla (esta MIDlet), la creación de un comando de salida de prioridad 2, la instanciación de t con título "Hola", texto inicial "Esto es una prueba", longitud máxima de texto de 256 caracteres y tipo 0, los tipos son valores constantes que la clase TextBox interpreta para permitir la entrada de algunos caracteres e impedir la de otros, en el ejemplo el tipo 0 es la constante Textfield.ANY, que indica que se puede introducir cualquier carácter (también existen Textfield.NUMERIC, TextField.DECIMAL y TextField.PHONENUMBER, entre otras). Después de creado el objeto t, se le agrega el comando CmdSalir.

public void startApp() {

display.setCurrent(t);

}

En el método startApp se indica que el elemento en pantalla será t.

public void pauseApp() {

}

public void destroyApp(boolean unconditional) {

}

public void commandAction(Command c, Displayable s) {

if (c == CmdSalir) {

destroyApp(false);

notifyDestroyed();

}

}

}

Cuando una MIDlet tiene más de un comando (aunque no es el caso de esta) se puede realizar una decisión con el parámetro c para definir las acciones a tomar en cada comando.

5.5.3.TextField

El elemento Textfield trabaja sobre una forma (Form), por lo que ésta debe ser declarada e instanciada antes de utilizar el Textfield.

private Form mainForm;

mainForm = new Form("Text Field");

private TextField txt1;

txt1=newTextField("Cualquier carácter", "", 15, TextField.ANY)

Una vez instanciada la forma, se utiliza el método append para crear en ella los campos de texto que consideremos necesarios:

mainForm.append(txt1);

mainForm.append(new TextField("E-Mail", "", 15, TextField.EMAILADDR));

mainForm.append(new TextField("Entero", "", 15, TextField.NUMERIC));

mainForm.append(new TextField("Decimal", "10.5", 15, TextField.DECIMAL));

mainForm.append(new TextField("Teléfono", "", 15, TextField.PHONENUMBER));

mainForm.append(new TextField("Password", "", 15, TextField.PASSWORD));

mainForm.append(new TextField("URL", "", 15, TextField.URL));

Como se puede observar, el constructor de la clase Textfield lleva cuatro parámetros, el primero de ellos indica la etiqueta que habrá de llevar el campo de texto, en el segundo se debe especificar el valor inicial, el siguiente es la longitud (en caracteres) que habrá de tolerar el campo y el último indica el filtro a utilizar para dicho campo, es decir, que caracteres admitirá.

Quizá el lector observe que, el utilizar la palabra clave new dentro de los paréntesis del método append podría limitar el control que se tenga sobre los objetos de la forma, por lo tanto es recomendable declarar e instanciar antes los objetos y sólo nombrarlos en append, como se hizo con txt1.

Hay varios filtros además de los mostrados en el ejemplo, se recomienda al lector interesado revisar la especificación de la clase Textfield.

5.5.4.Datefield

Hasta ahora no se ha descrito, en las clases TextField y TextBox, un método relativamente fácil para introducir una fecha, los signos "/" en un teléfono son un poco difíciles de localizar, sin contar con que los números son la última o una de las últimas opciones en el orden de las teclas de la mayoría de los equipos, estos problemas no lo son tanto si se utiliza la clase DateField. Enseguida se explica cómo.

public class DateFieldDemo extends MIDlet implements CommandListener{

private final static Command CmdSalir = new Command("Salir", Command.EXIT,1);

private boolean primera;

private Form mainForm;

public DateFieldDemo() {

Primera = true;

Forma = new Form("Ejemplo de fecha");

}

En esta clase de nombre DateFieldDemo, se utilizan por primera vez los cambios de pantalla, implícitos en la clase DateField, es por esto que se crea una variable lógica Primera que servirá para no instanciar los objetos dos veces (al iniciar la MIDlet y al volver del cambio de pantalla).

protected void startApp() {

if(Primera) {

Forma.append(new DateField("Fecha", DateField.DATE));

Forma.append(new DateField("Hora", DateField.TIME));

Forma.append(new DateField("Fecha y hora",

DateField.DATE_TIME));

Forma.addCommand(CmdSalir);

Forma.setCommandListener(this);

Primera = false;

}

Display.getDisplay(this).setCurrent(mainForm);

}

Además de los ya conocido, en startApp se agregan a la forma tres campos de fecha, el primero pedirá, según la forma que tenga dispositivo de hacerlo, la fecha; el segundo pedirá la hora y el tercero ambos datos.

protected void destroyApp(boolean unconditional) { }

protected void pauseApp() { }

public void commandAction(Command c, Displayable d) {

if (c == CmdSalir) {

destroyApp(false);

notifyDestroyed();

}

}

}

5.5.5.StringItem

Cuando lo que se desea no es pedir al usuario un dato, sino mostrarle información, seguramente no es recomendable utilizar clases cuyo contenido pueda ser alterado. Para esto se utiliza la clase StringItem.

public class StringItemDemo extends MIDlet implements CommandListener,

ItemCommandListener {

private Display display;

private Form mainForm;

private final static Command IR = new Command("Ir", Command.ITEM, 1);

private final static Command PRES = new Command("Pres",

Command.ITEM, 1);

private final static Command Salir = new Command("Salir",

Command.EXIT, 1);

En esta primera parte del código de la clase, se puede ver que se ha implementado una nueva interfaz, ItemCommmandListener, la cual se utiliza para agregar comandos, no sólo a los objetos de pantalla completa (como TextBox o Form), sino a los agrupados en estos objetos. Ahora podemos utilizar los comandos de tipo ITEM.

protected void startApp() {

display = Display.getDisplay(this);

mainForm = new Form("String Item Demo");

mainForm.append("Esto es sólo una etiqueta");

StringItem item = new StringItem("Etiqueta de String Item: ",

"Texto de String Item");

mainForm.append(item);

item = new StringItem("Etiqueta: ", "texto");

mainForm.append(item);

item = new StringItem("Hipervínculo ", "Ir a", Item.HYPERLINK);

item.setDefaultCommand(IR);

item.setItemCommandListener(this);

mainForm.append(item);

item = new StringItem("Botón ", "Presionar", Item.BUTTON);

item.setDefaultCommand(PRES);

item.setItemCommandListener(this);

mainForm.append(item);

mainForm.addCommand(Salir);

mainForm.setCommandListener(this);

display.setCurrent(mainForm);

}

En startApp sólo se muestran las posibilidades que se tienen para escribir un texto que el usuario no pueda modificar y que además pueda ejecutar alguna acción. Desde simplemente escribir "Esto es sólo una etiqueta" hasta un botón que, al ser presionado, puede realizar una tarea. En el ejemplo, se distinguen dos tipos de constructores de StringItem, el primero, que tiene como parámetros dos cadenas de texto (etiqueta o título y contenido) y el segundo, que además permite la definición de un tipo de texto (hipervínculo o botón).

public void commandAction(Command c, Item item) {

if (c == IR) {

String text = "Ir a la URL...";

Alert a = new Alert("URL", text, null, AlertType.INFO);

display.setCurrent(a);

} else if (c == PRES) {

String text = "Do an action...";

Alert a = new Alert("Action", text, null, AlertType.INFO);

display.setCurrent(a);

}

}

public void commandAction(Command c, Displayable d) {

destroyApp(false);

notifyDestroyed();

}

Tal vez llame la atención el hecho de tener dos funciones con el mismo nombre (CommandAction), pero hay que observar los parámetros que toman al activarse, ambas capturan un evento en el teclado, pero la primera captura los eventos ocasionados en el componente de la forma que esté seleccionado, mientras el otro se ocupa de los eventos generales y funcionan solamente sobre los eventos

protected void destroyApp(boolean unconditional) { }

protected void pauseApp() { }

}

5.5.6.ChoiceGroup

Los grupos de selección o ChoiceGroup, por su nombre en inglés, son listados de elementos en los que se puede seleccionar uno o varios de ellos y permiten realizar operaciones (principalmente comparaciones lógicas) con dicha selección.

import javax.microedition.lcdui.*;

import javax.microedition.midlet.MIDlet;

public class Choice1 extends MIDlet implements CommandListener {

private final static Command CMD_Salir = new Command("Salir",

Command.EXIT,1);

private Display display;

private boolean primera;

private Form Forma;

public ChoiceGroupDemo() {

primera = true;

}

Hasta este punto todo se ve como en los ejemplos anteriores, se importan las clases, se define la clase con extensiones e implementaciones, se crea un comando que se utilizará para salir de la MIDlet, se declaran los objetos y variables a utilizar y se determina lo que ha de hacer el constructor.

protected void startApp() {

if(primera) {

display = Display.getDisplay(this);

Forma = new Form("Choice Group");

Forma.append("Choice Group");

Image[] ArrImg = null;

try {

Image Imag = Image.createImage("/midp/uidemo/icono.png");

ArrImg = new Image[] { Imag, Imag, Imag, Imag };

} catch (java.io.IOException err) {

}

String[] arrString = {

"Opcion A", "Opcion B", "Opcion C", "Opcion D"

};

ChoiceGroup[] grupos = {

new ChoiceGroup("Exclusivo", ChoiceGroup.EXCLUSIVE,

arrString,ArrImg),

new ChoiceGroup("Multiple", ChoiceGroup.MULTIPLE,

arrString,ArrImg),

new ChoiceGroup("Pop-Up", ChoiceGroup.POPUP,

arrString,ArrImg)

};

for (int iter = 0; iter <>

Forma.append(grupos[iter]);

}

Forma.addCommand(CMD_Salir);

Forma.setCommandListener(this);

primera = false;

}

display.setCurrent(Forma);

}

startApp crea tres grupos de selección, exclusivo, múltiple y pup-up. Todos estos grupos contienen cuatro opciones (A, B, C y D) y cuatro iconos, correspondientes, cada uno, a una opción, contenidos en arrString y arrImg, respectivamente.

El grupo exclusivo es aquel que permite que uno y sólo uno de sus elementos esté seleccionado. El grupo múltiple permite la selección de uno o varios elementos. El modo pop-up permite escoger una sola opción, pero, a diferencia del exclusivo, las muestra en un menú desplegable.

public void commandAction(Command c, Displayable d) {

if (c == CMD_Salir) {

destroyApp(false);

notifyDestroyed();

}

}

protected void destroyApp(boolean unconditional) {

}

protected void pauseApp() {

}

}

5.5.7.List

Una lista de elementos, a diferencia de lenguajes como HTML WML, en J2ME es una lista de la que se puede seleccionar un elemento, es decir, es como un grupo de selección (ChoiceGroup). A continuación se muestra un código de ejemplo para la utilización de listas:

public class Lista extends MIDlet implements CommandListener {

private final static Command SALIR = new Command("Salir",

Command.EXIT, 1);

private final static Command ATRAS = new Command("Atrás",

Command.BACK, 1);

private Display display;

private List Lista1;

private List ListaEx;

private List ListaIm;

private List ListaMul;

private boolean primera;

En esta primera parte del código únicamente se han declarado las variables y los objetos que se utilizarán, notese que entre esos objetos se encuentran cuatro listas u objetos List.

public Lista() {

display = Display.getDisplay(this);

String[] Opciones = {"Opción A", "Opción B", "Opción C", "Opción D"

};

Image[] imagenes = null;

ListaEx = new List("Exclusiva", Choice.EXCLUSIVE, Opciones,

imagenes);

ListaEx.addCommand(ATRAS);

ListaEx.addCommand(SALIR);

ListaEx.setCommandListener(this);

ListaIm = new List("Implícita", Choice.IMPLICIT, Opciones,

imagenes);

ListaIm.addCommand(ATRAS);

ListaIm.addCommand(SALIR);

ListaIm.setCommandListener(this);

ListaMul = new List("Múltiple", Choice.MULTIPLE, Opciones,

imagenes);

ListaMul.addCommand(ATRAS);

ListaMul.addCommand(SALIR);

ListaMul.setCommandListener(this);

primera = true;

}

El constructor de la clase principal crea un arreglo Opciones que contiene los elementos de la lista, otro arreglo imagenes de valor nulo que definirá las imágenes a utilizar como iconos a mostrar al lado de los elementos; finalmente se instancian las listas según el tipo al que pertenecerán y se les agrega un comando ATRAS y otro SALIR.

Entradas relacionadas:

0 comentarios

Publicar un comentario