resumen.pdf

27
Análisis de tecnologías para aplicaciones en dispositivos móviles. 1.- Introducción. ¿Qué es un dispositivo móvil? Se trata de un aparato de pequeño tamaño y de poco peso, con pantalla y teclado, con pequeñas capacidades de procesamiento, memoria limitada y conexión (permanente o no) a una red. 1.1.- Clasificación de los dispositivos móviles. SmartPhones o "teléfonos inteligentes". PDA (Personal Digital Assistant - asistentes digitales personales) o PocketPC (PC de bolsillo). Handheld, o PCs de mano. Internet tables, que se encontrarían entre las PDA y los PC Ultramóviles (pequeños tablet PC). Según las fuentes que consultes puedes encontrar diversas clasificaciones donde se incluyan unos u otros tipos de dispositivos, como por ejemplo: Pagers (o buscapersonas), hoy día ya en desuso. Navegadores GPS. E-Readers (lectores de libros digitales). Pequeñas videoconsolas de mano. Cámaras digitales. Calculadoras programables. 2.- Limitaciones de las tecnologías móviles. Suministro de energía limitado. Procesadores con capacidad de cómputo reducida. Suelen tener una baja frecuencia de reloj por la necesidad de ahorrar energía. En algunos casos, por ejemplo, podrían no disponer de la capacidad de cálculos en punto flotante. Poca memoria principal (RAM). Almacenamiento de datos persistente reducido (pequeña memoria flash interna, tarjetas SD, etc.). Conexión a algún tipo de red intermitente y con ancho de banda limitado. Pantallas de reducidas dimensiones. Teclados con funcionalidad muy básica y muy pequeños. 3.- Tecnologías disponibles. Symbian OS, Android, iOS, Blackberry OS y Windows Phone. 3.1.- Hardware. 3.1.1.- Smartphones. Funcionamiento en multitarea. Acceso a Internet. Conectividad Wi-Fi, Bluetooth, etc. Posibilidad de conexión con un ordenador para cargar y descargar información. Normalmente con conexión USB o bien una conexión inalámbrica. Posibilidad de ampliación de memoria mediante tarjetas externas de memoria (por ejemplo SD). Pequeñas pantallas pero de alta resolución y/o con millones de colores. Posibilidad de pantallas táctiles o incluso multitáctiles (multitouch). Sensores (de orientación, de temperatura, de presión, acelerómetros, magnetómetros, etc.). Cámaras digitales integradas. Capacidades fotográficas. Grabación de audio y vídeo. Receptor GPS. Receptor de radio FM. Emisor de radio FM. Posibilidad de instalar y ejecutar aplicaciones sofisticadas. La principal arquitectura de microprocesadores utilizada para telefonía móvil es la diseñada por la empresa ARM ("Advanced RISC Machines", hoy día ARM Holdings. 3.1.3.- PDA. Una PDA (Personal Digital Assistant o asistente digital personal) u ordenador de bolsillo o Pocket PC o Palmtop Computer es un dispositivo móvil cuya funcionalidad original era la de gestión de datos personales. 3.2.- Sistemas operativos. Symbian OS. La mayoría de teléfonos móviles con Symbian son del fabricante Nokia (entre ellos la mayoría de los de la serie N). Android. Desarrollado inicialmente por Google y basado en el núcleo de Linux. El primer fabricante de móviles que lo incorporó fue HTC. iOS. Desarrollado por Apple para el iPhone y usado más tarde también para el iPod Touch y el iPad. Windows Phone (anteriormente llamado Windows Mobile). Desarrollado por Microsoft tanto para smartPhones como para otros dispositivos móviles (por ejemplo PDA). Algunos fabricantes de teléfonos móviles que incorporan este sistema operativo son Samsung, LG o HTC. Blackberry OS. Desarrollado por Research in Motion (RIM) para sus dispositivos Blackberry. HP webOS, desarrollado por Palm, adquirido por HP (Palm era la desarrolladora del más antiguo Palm OS). Está basado en un kernel de Linux. Palm OS. Desarrollado por PalmSource para PDA, aunque las últimas versiones también funcionan para smartPhones. Maemo OS. Desarrollado por Nokia para smartPhones, PDA e Internet tables. Bada. Desarrollado por Samsung. 3.2.1.- Symbian OS. Para el desarrollo de aplicaciones sobre Symbian se utilizó inicialmente una versión específica de C++, aunque hoy día se emplea C++ estándar con el framework Qt. Los entornos de desarrollo más habituales para programar sobre Symbian son Carbide.C++ (basado en Eclipse), o bien QtCreator. También se pueden desarrollar aplicaciones sobre Symbian utilizando Python (Python para S60), Adobe Flash o Java ME. 3.2.2.- Android. Para desarrollar aplicaciones sobre Android se necesita el kit de desarrollo de software para Android (Android SDK), proporcionado gratuitamente por Google. El lenguaje de programación que se utiliza es Java (y por tanto es necesario el JDK de Oracle para poder compilar programas Java). El IDE oficial es Eclipse (a partir de la versión 3.2) junto con el plugin ADT (Android Development Tools - herramientas de desarrollo para Android. 3.2.3.- Windows Phone. Para desarrollar aplicaciones sobre Windows Phone pueden utilizarse las tecnologías Silverlight y XNA de Microsoft, así como el entorno de desarrollo Visual Studio. 3.2.4.- iOS. Para desarrollar aplicaciones sobre iOS, las aplicaciones deben ser compiladas específicamente para este sistema operativo basado en la arquitectura ARM. Para ello puede utilizarse el kit de desarrollo iPhone SDK. El lenguaje de programación principal para este conjunto de herramientas es el Objective-C. Para poder utilizar este kit de desarrollo es necesario un ordenador MAC con un sistema operativo MAC OS X Leopard o superior. 3.3.- Plataformas de desarrollo y lenguajes de programación. Windows Phone. Para desarrollar aplicaciones sobre Windows Phone pueden utilizarse las tecnologías Silverlight, XNA y .NET Compact Framework de Microsoft. Las herramientas Visual Studio 2010 Express y Expression. El lenguaje más habitual para el desarrollo ha sido C#.Android . Google proporciona el Android SDK para programar aplicaciones en Java sobre su sistema operativo. El IDE más utilizado es Eclipse con el plugin ADT (Android Development Tools). También es posible programar en otros lenguajes como C o C++ gracias al uso del Android NDK (Native Development Kit) que permite generar código nativo (native code), frente al código gestionado (managed code), que se ejecuta sobre una máquina virtual, como es el caso de Java o C#. iOS. El lenguaje de programación en este caso es Objective-C. Java ME : no se trata de una serie de herramientas (bibliotecas, compiladores, IDEs, etc.) asociadas a un sistema operativo, sino de un subconjunto de la plataforma Java orientada para el desarrollo sobre dispositivos móviles. Se programaría en lenguaje Java y sería necesario que hubiera instalada una máquina virtual en el sistema operativo del dispositivo sobre el que se deseara ejecutar la aplicación desarrollada como sucede por ejemplo en Symbian (que se puede programar en modo nativo o bien con Java ME). 3.5.- La plataforma Java ME. La plataforma Java Micro Edition (Java ME), consiste en una especificación de un subconjunto de la plataforma Java orientada para proporcionar una colección de API de desarrollo de software para dispositivos con recursos restringidos (teléfonos móviles, PDA, electrodomésticos inteligentes, etc.). Se utiliza para ello una pequeña máquina virtual de Java conocida como KVM. 4.- El entorno de ejecución. Paquetes opcionales.Perfil.Configuración.Máquina virtual Java. 4.1.- Máquinas Virtuales. Las dos máquinas virtuales disponibles en Java ME son la KVM (K Virtual Machine, se le ha dado ese nombre porque sólo ocuparía unos pocos Kilobytes de memoria) y la CVM (Compact Virtual Machine), algo más pesada. 4.2.- Configuraciones. Una configuración define una plataforma Java para un amplio rango de dispositivos, estando directamente relacionada con una máquina virtual. Configuración CLDC (Connected Limited Device Configuration), enfocada a dispositivos con restricciones de procesamiento y memoria. Requerirá el uso de la máquina virtual KVM. Configuración CDC (Connected Device Configuration), enfocada a dispositivos sin tantas limitaciones. Utiliza la máquina virtual CVM. 4.3.- Perfiles. Los perfiles consisten en un conjunto de APIs de alto nivel que combinados con una configuración concreta permitirán ofrecer un entorno de ejecución completo y específico para cada categoría de dispositivo. Mientras que una configuración (CDC o CLDC) definía las características de una familia de dispositivos, el perfil se encarga de las APIs que definen las características de un dispositivo (o un conjunto muy reducido). Para la configuración CDC existen los siguientes perfiles: Foundation Profile (FP). Proporciona un conjunto de APIs sobre la configuración CDC con capacidades de acceso a red orientada a dispositivos que carecen de interfaz gráfica como por ejemplo los descodificadores de TDT.

Upload: toniwells1

Post on 01-Dec-2015

21 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: resumen.pdf

Análisis de tecnologías para aplicaciones en dispos itivos móviles. 1.- Introducción. ¿Qué es un dispositivo móvil? Se trata de un aparato de pequeño tamaño y de poco peso, con pantalla y teclado, con pequeñas capacidades de procesamiento, memoria limitada y conexión (permanente o no) a una red.

1.1.- Clasificación de los dispositivos móviles. SmartPhones o "teléfonos inteligentes". PDA (Personal Digital Assistant - asistentes digitales personales) o PocketPC (PC de bolsillo). Handheld, o PCs de mano. Internet tables, que se encontrarían entre las PDA y los PC Ultramóviles (pequeños tablet PC). Según las fuentes que consultes puedes encontrar diversas clasificaciones donde se incluyan unos u otros tipos de dispositivos, como por ejemplo: Pagers (o buscapersonas), hoy día ya en desuso. Navegadores GPS. E-Readers (lectores de libros digitales). Pequeñas videoconsolas de mano. Cámaras digitales. Calculadoras programables.

2.- Limitaciones de las tecnologías móviles. Suministro de energía limitado. Procesadores con capacidad de cómputo reducida. Suelen tener una baja frecuencia de reloj por la necesidad de ahorrar energía. En algunos casos, por ejemplo, podrían no disponer de la capacidad de cálculos en punto flotante. Poca memoria principal (RAM). Almacenamiento de datos persistente reducido (pequeña memoria flash interna, tarjetas SD, etc.). Conexión a algún tipo de red intermitente y con ancho de banda limitado. Pantallas de reducidas dimensiones. Teclados con funcionalidad muy básica y muy pequeños.

3.- Tecnologías disponibles. Symbian OS, Android, iOS, Blackberry OS y Windows Phone.

3.1.- Hardware. 3.1.1.- Smartphones. Funcionamiento en multitarea. Acceso a Internet. Conectividad Wi-Fi, Bluetooth, etc. Posibilidad de conexión con un ordenador para cargar y descargar información. Normalmente con conexión USB o bien una conexión inalámbrica. Posibilidad de ampliación de memoria mediante tarjetas externas de memoria (por ejemplo SD). Pequeñas pantallas pero de alta resolución y/o con millones de colores. Posibilidad de pantallas táctiles o incluso multitáctiles (multitouch). Sensores (de orientación, de temperatura, de presión, acelerómetros, magnetómetros, etc.). Cámaras digitales integradas. Capacidades fotográficas. Grabación de audio y vídeo. Receptor GPS. Receptor de radio FM. Emisor de radio FM. Posibilidad de instalar y ejecutar aplicaciones sofisticadas. La principal arquitectura de microprocesadores utilizada para telefonía móvil es la diseñada por la empresa ARM ("Advanced RISC Machines", hoy día ARM Holdings.

3.1.3.- PDA. Una PDA (Personal Digital Assistant o asistente digital personal) u ordenador de bolsillo o Pocket PC o Palmtop Computer es un dispositivo móvil cuya funcionalidad original era la de gestión de datos personales.

3.2.- Sistemas operativos. Symbian OS. La mayoría de teléfonos móviles con Symbian son del fabricante Nokia (entre ellos la mayoría de los de la serie N). Android. Desarrollado inicialmente por Google y basado en el núcleo de Linux. El primer fabricante de móviles que lo incorporó fue HTC. iOS. Desarrollado por Apple para el iPhone y usado más tarde también para el iPod Touch y el iPad. Windows Phone (anteriormente llamado Windows Mobile). Desarrollado por Microsoft tanto para smartPhones como para otros dispositivos móviles (por ejemplo PDA). Algunos fabricantes de teléfonos móviles que incorporan este sistema operativo son Samsung, LG o HTC. Blackberry OS. Desarrollado por Research in Motion (RIM) para sus dispositivos Blackberry. HP webOS, desarrollado por Palm, adquirido por HP (Palm era la desarrolladora del más antiguo Palm OS). Está basado en un kernel de Linux. Palm OS. Desarrollado por PalmSource para PDA, aunque las últimas versiones también funcionan para smartPhones. Maemo OS. Desarrollado por Nokia para smartPhones, PDA e Internet tables. Bada. Desarrollado por Samsung.

3.2.1.- Symbian OS. Para el desarrollo de aplicaciones sobre Symbian se utilizó inicialmente una versión específica de C++, aunque hoy día se emplea C++ estándar con el framework Qt. Los entornos de desarrollo más habituales para programar sobre Symbian son Carbide.C++ (basado en Eclipse), o bien QtCreator. También se pueden desarrollar aplicaciones sobre Symbian utilizando Python (Python para S60), Adobe Flash o Java ME.

3.2.2.- Android. Para desarrollar aplicaciones sobre Android se necesita el kit de desarrollo de software para Android (Android SDK), proporcionado gratuitamente por Google. El lenguaje de programación que se utiliza es Java (y por tanto es necesario el JDK de Oracle para poder compilar programas Java). El IDE oficial es Eclipse (a partir de la versión 3.2) junto con el plugin ADT (Android Development Tools - herramientas de desarrollo para Android.

3.2.3.- Windows Phone. Para desarrollar aplicaciones sobre Windows Phone pueden utilizarse las tecnologías Silverlight y XNA de Microsoft, así como el entorno de desarrollo Visual Studio. 3.2.4.- iOS. Para desarrollar aplicaciones sobre iOS, las aplicaciones deben ser compiladas específicamente para este sistema operativo basado en la arquitectura ARM. Para ello puede utilizarse el kit de desarrollo iPhone SDK. El lenguaje de programación principal para este conjunto de herramientas es el Objective-C. Para poder utilizar este kit de desarrollo es necesario un ordenador MAC con un sistema operativo MAC OS X Leopard o superior.

3.3.- Plataformas de desarrollo y lenguajes de prog ramación. Windows Phone. Para desarrollar aplicaciones sobre Windows Phone pueden utilizarse las tecnologías Silverlight, XNA y .NET Compact Framework de Microsoft. Las herramientas Visual Studio 2010 Express y Expression. El lenguaje más habitual para el desarrollo ha sido C#.Android. Google proporciona el Android SDK para programar aplicaciones en Java sobre su sistema operativo. El IDE más utilizado es Eclipse con el plugin ADT (Android Development Tools). También es posible programar en otros lenguajes como C o C++ gracias al uso del Android NDK (Native Development Kit) que permite generar código nativo (native code), frente al código gestionado (managed code), que se ejecuta sobre una máquina virtual, como es el caso de Java o C#. iOS. El lenguaje de programación en este caso es Objective-C. Java ME: no se trata de una serie de herramientas (bibliotecas, compiladores, IDEs, etc.) asociadas a un sistema operativo, sino de un subconjunto de la plataforma Java orientada para el desarrollo sobre dispositivos móviles. Se programaría en lenguaje Java y sería necesario que hubiera instalada una máquina virtual en el sistema operativo del dispositivo sobre el que se deseara ejecutar la aplicación desarrollada como sucede por ejemplo en Symbian (que se puede programar en modo nativo o bien con Java ME).

3.5.- La plataforma Java ME. La plataforma Java Micro Edition (Java ME), consiste en una especificación de un subconjunto de la plataforma Java orientada para proporcionar una colección de API de desarrollo de software para dispositivos con recursos restringidos (teléfonos móviles, PDA, electrodomésticos inteligentes, etc.). Se utiliza para ello una pequeña máquina virtual de Java conocida como KVM. 4.- El entorno de ejecución. Paquetes opcionales.Perfil.Configuración.Máquina virtual Java.

4.1.- Máquinas Virtuales. Las dos máquinas virtuales disponibles en Java ME son la KVM (K Virtual Machine, se le ha dado ese nombre porque sólo ocuparía unos pocos Kilobytes de memoria) y la CVM (Compact Virtual Machine), algo más pesada.

4.2.- Configuraciones. Una configuración define una plataforma Java para un amplio rango de dispositivos, estando directamente relacionada con una máquina virtual. Configuración CLDC (Connected Limited Device Configuration), enfocada a dispositivos con restricciones de procesamiento y memoria. Requerirá el uso de la máquina virtual KVM. Configuración CDC (Connected Device Configuration), enfocada a dispositivos sin tantas limitaciones. Utiliza la máquina virtual CVM.

4.3.- Perfiles. Los perfiles consisten en un conjunto de APIs de alto nivel que combinados con una configuración concreta permitirán ofrecer un entorno de ejecución completo y específico para cada categoría de dispositivo. Mientras que una configuración (CDC o CLDC) definía las características de una familia de dispositivos, el perfil se encarga de las APIs que definen las características de un dispositivo (o un conjunto muy reducido). Para la configuración CDC existen los siguientes pe rfiles: Foundation Profile (FP). Proporciona un conjunto de APIs sobre la configuración CDC con capacidades de acceso a red orientada a dispositivos que carecen de interfaz gráfica como por ejemplo los descodificadores de TDT.

Page 2: resumen.pdf

Personal Profile (PP). Para dispositivos con un interfaz gráfico completo AWT, capacidades web y soporte de Applets Java. RMI Profile. Se construye sobre el Foundation Profile. Soporta un subconjunto de las APIs Java SE v1.3 RMI. Para la configuración CLDC disponemos de estos otro s perfiles: PDA Profile. Diseñado para PDA de gama baja, tipo Palm, con una pantalla y algún tipo de puntero. Mobile Information Device Profile (MIDP). Diseñado para smartPhones y PDAs, incluye la interfaz de usuario, conectividad de red, almacenamiento local de datos y gestión de aplicaciones. Combinado con CLDC, MIDP aporta un entorno de ejecución para Java que minimiza los consumos de memoria y de procesador. Este perfil será el que utilizaremos para desarrollar aplicaciones móviles en este módulo.

5.- Jerarquía de clases de perfil. Las aplicaciones que realices utilizando el perfil MIDP son conocidas con Midlets (por hacer algo así como un paralelismo con los Applets). Por tanto un midlet es una aplicación Java construida con el perfil MIDP sobre la configuración CLDC. 5.1.- Clases CLDC heredadas de Java SE.

5.2.- Clases específicas de la configuración CLDC. CLDC dispone de un conjunto de clases genérico para comunicaciones conocido como "Generic Connection Framework " o GCF. Consisten en un conjunto de clases e interfaces diseñado para facilitar el acceso a sistemas de almacenamiento y conexión, sin necesidad de especificar ningún requisito software o hardware. Estas clases e interfaces (la mayoría son interfaces) se encuentran en el paquete javax.microedition.io

5.3.- Paquetes del perfil MIDP. El perfil MIDP incorpora a un conjunto de bibliotecas y clases para interfaces gráficas, almacenamiento, persistencia y otros aspectos más avanzados específicos del perfil de dispositivo. Al estar construido sobre la configuración CLDC este perfil también incluye los paquetes que hemos visto antes para el funcionamiento normal de un programa (clases base, tipos, datos, E/S, utilidades, etc.).

8.2.- Escritura de código. import javax.microedition.midlet.*; public class HolaMidlet extends MIDlet implements javax.microedition.lcdui.CommandListener { private void initialize() { javax.microedition.lcdui.Display.getDisplay(this).setCurrent(get_helloTextBox()); } public void commandAction(javax.microedition.lcdui.Command command, javax.microedition.lcdui.Displayable displayable) { if (displayable == helloTextBox) { if (command == exitCommand) { javax.microedition.lcdui.Display.getDisplay(this).setCurrent(null); destroyApp(true); notifyDestroyed(); } } } private javax.microedition.lcdui.TextBox get_helloTextBox() { if (helloTextBox == null) { helloTextBox = new javax.microedition.lcdui.TextBox(null, "Hola Mundo!", 120, 0x0); helloTextBox.addCommand(get_exitCommand()); helloTextBox.setCommandListener(this); }

Page 3: resumen.pdf

return helloTextBox; } private javax.microedition.lcdui.Command get_exitCommand() { if (exitCommand == null) { exitCommand = new javax.microedition.lcdui.Command("Salir", javax.microedition.lcdui.Command.EXIT, 1); } return exitCommand; } javax.microedition.lcdui.TextBox helloTextBox; javax.microedition.lcdui.Command exitCommand; public void startApp() { initialize(); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } }

9.- Gestión del entorno de ejecución. En estos dispositivos lo que existe es un software conocido como Gestor de Aplicaciones o Administrador de Aplicaciones (AMS – Application Management System) que se encarga de ejecutar los Midlets y de gestionar los recursos que consumen. El AMS lleva a cabo esencialmente dos funciones: 1.La gestión del ciclo de vida de los Midlets en el dispositivo. 2.El control de los estados por los que pasa midlet mientras resida en la memoria del dispositivo, es decir, mientras esté en ejecución.

9.2.- Ciclo de vida de una aplicación. El Gestor de Aplicaciones (AMS) es quien se encarga de gestionar esas fases: 1.Descubrimiento (o localización). Consiste en el proceso por el cual un usuario localiza un midlet a través de su dispositivo. 2.Instalación. Una vez que la aplicación ha sido descargada en el dispositivo, ésta puede ser instalada. 3.Ejecución. El AMS es también el que permite poner en ejecución el midlet. 4.Actualización. Una vez que un midlet ha sido descargado, el AMS debe de ser capaz de detectar si se trata de una actualización de un midlet ya presente en el dispositivo. 5.Borrado. Si el usuario así lo desea, el AMS se encargará de borrar el midlet del dispositivo.

9.3.- Modelo de estados de una aplicación. Activo. El midlet está en ese momento ejecutándose. Pausa. El midlet no se encuentra ejecutándose en ese momento. En ese estado no se debe utilizar ningún recurso compartido. Para volver a ejecutar instrucciones de su código, el midlet debe de pasar a estado activo. Destruido. El midlet no está ya en ejecución ni podrá pasar a otro estado. Se liberan todos los recursos ocupados. Un midlet puede cambiar de estado mediante una llamada a algunos de los métodos: midlet.StartApp ( ). midlet.pauseApp ( ). midlet.destroyApp ( ).

1.- Herramientas y fases de construcción. 1.1.- Desarrollo del código. 1.1.1.- Creación de un proyecto Java ME. Un proyecto representa una midlet suite, es decir, un conjunto de midlets (aplicaciones) y no necesariamente sólo una. src, que contiene los archivos fuente (Java). dist, que contiene el archivo final JAR y el archivo JAD, así como otras bibliotecas externas en formato JAR o ZIP. De aquí podrías sacar el archivo final para copiarlo a un dispositivo e instalarlo. nbproject, que contiene información de configuración del proyecto para NetBeans. build, que contiene el archivo de manifiesto, así como los archivos de clases Java procesadas.

1.1.2.- El esqueleto de un midlet. Todo midlet necesita tener una clase principal que hereda de la clase abstracta midlet. Esta clase se encuentra en el paquete javax.microedition.midlet. Recuerda que no es posible instanciar directamente un objeto de una clase abstracta sino que es necesario crear una clase que herede de ella y que implemente todos sus métodos abstractos. Esa nueva clase sí será instanciable. Por tanto, cuando crees una aplicación de tipo midlet, su clase principal deberá heredar de la clase midlet: public class midletEjemplo extends midlet

Además de los tres métodos anteriores, que son de obligada implementación, un midlet suele incorporar también un constructor en el que se definen los elementos gráficos y se inicializan las variables de estado de la aplicación.

1.1.3.- Funcionamiento de un midlet. Un midlet comienza en estado en pausa. Cuando se carga en memoria, se ejecuta su constructor y, si no se produce ningún problema, se pasa al estado activo ejecutándose el método startApp. La aplicación continuará en ese estado hasta que pase a un estado en pausa o destruido. el gestor de aplicaciones puede hacer pasar al midlet a estado en pausa, dando los recursos del dispositivo (pantalla, teclado, CPU, etc.) a otra aplicación y ejecutándose el método pauseApp.

import javax.microedition.midlet.*;

public class MidletEjemplo extends MIDlet {

public void startApp() {

}

public void pauseApp() {

}

public void destroyApp(boolean

unconditional) {

Métodos abstractos de la clase midlet

Método Descripción

protected abstract void startApp () Método que se ejecuta cuando se pasa de estado en pausa a estado activo .

protected abstract void destroyApp (boolean unconditional)

Método que se ejecuta cuando se destruye el midlet.

protected abstract void pauseApp () Método que se ejecuta cuando se pasa de estado act ivo a estado en pausa.

Page 4: resumen.pdf

1.1.4.- Ejemplo de un midlet básico. 1.2.- Compilación y preverificación. Los procesos de verificación durante la generación de código se encargan de realizar revisiones de seguridad, integridad y cumplimiento de los estándares. Debido a las importantes restricciones existentes en los dispositivos móviles, la verificación de las clases tiene dos etapas: Preverificación, que se realiza como un paso más de la generación de los binarios.Verificación, llevada a cabo por la máquina virtual durante la ejecución.

1.3.- Empaquetamiento. Esta fase es la que se encarga de empaquetar la aplicación con todas las clases y recursos que vaya a necesitar, dejándola lista para ser descargada en un dispositivo que la instale. Esta fase implica la creación de los siguientes archivos: El archivo JAR (Java Archive), que es el paquete que contendrá todos los archivos que conforman la aplicación (clases; recursos como imágenes y sonidos; archivo de manifiesto; etc.).El archvo de manifiesto, que consiste en una descripción del contenido del archivo JAR. Es un archivo opcional. Archivo JAD.

1.3.1.- El archivo de manifiesto. (manifest.mf). Este archivo describe el contenido del JAR y consiste un archivo de texto con una estructura de una línea por atributo, donde los valores de los atributos son especificados de la forma "atributo: valor". 1.3.2.- Archivos JAD. El archivo JAD (Java Application Descriptor) sirve para proporcionar información adicional sobre el juego de midlets contenido en un JAR. Su estructura es similar a la del archivo de manifiesto (pares atributo: valor). 1.4.- Instalación en un dispositivo real. 1.5.- Ejecución. La ejecución de un midlet puede realizarse bien en un emulador (basta con ejecutar el midlet en NetBeans para que éste sea ejecutado en el emulador que tengamos configurado en el proyecto) bien en un dispositivo real. 1.6.- Depuración. Para depurar una aplicación de tipo midlet lo ideal es disponer de un IDE adecuado que proporcione todas las posibilidades típicas de un depurador: Ejecución paso a paso y sus variantes (saltando funciones, entrando en ellas, etc.).Observar el contenido de las variables (y, si es posible, modificarlo).Establecer puntos de parada o breakpoints.Control de los threads.

2.- Interfaces de usuario. Interfaz de usuario de alto nivel. En este caso es el dispositivo quien se encarga de la colocación adecuada de los elementos , de la forma de navegación y de características visuales como el color o los tipos de letra. La ventaja de utilizar estas APIs de alto nivel es el alto grado de portabilidad de la aplicación para diferentes dispositivos. Interfaces de usuario de bajo nivel. En este caso el programador tendrá un control total de todo lo que va a aparecer en la pantalla. A partir de ahora, la mayoría de tus clases Java dentro de proyectos midlet incluirán la sentencia import javax.microedition.lcdui.*.

2.1.- Gestión de la pantalla y los dispositivos de entrada. La clase Display. Sólo existe una instancia (un objeto) de la clase Display por midlet.

Page 5: resumen.pdf

2.2.- Pantallas en un midlet. La clase Displayable. Una pantalla (o displayable en terminología MIDP) normalmente consistirá en un conjunto de objetos de interfaz gráfico de usuario (tanto de alto como de bajo nivel) organizados de algún modo. Todos ellos formarán parte de un objeto de la clase Displayable.

2.3.- Tipos de pantallas. Especializaciones de la c lase Displayable. Existen dos grandes categorías de displayables o pantallas, o dicho de otro modo, la clase Displayable tiene dos subclases:

• La clase Screen (también clase abstracta), que implementa la API de alto nivel. Dentro de esta categoría podríamos hablar también de dos subcategorías:

o Pantallas con estructura predefinida, que encapsulan componentes de interfaz específicos y que las aplicaciones no pueden enriquecer con nuevos componentes. Hay tres tipos: Alert. Alertas. List. Listas. TextBox. Cuadros o pantallas de texto.

o Formularios. Pantallas genéricas donde el programador de la aplicación puede insertar etiquetas, campos de texto, imágenes,

barras de progreso y otros componentes de interfaz de usuario para dar lugar al tipo de pantalla que la aplicación necesite. Se trata de la clase Form.

• La clase Canvas (nuevamente también abstracta), que implementa la API a bajo nivel. En este caso las aplicaciones tienen un control

total sobre los componentes en la pantalla y pueden acceder a eventos de bajo nivel.

2.4.- Gestión de eventos. tres tipos de eventos disponen a su vez de su correspondiente interfaz de listener asociado:

• CommandListener. • ItemStateListener. • ItemCommandListener

2.5.- Comandos. La clase Command. Los objetos de clase Command mantienen información sobre un evento. Contienen tres valores importantes:

Page 6: resumen.pdf

• Etiqueta (Label). Cadena de texto (String) que representa la acción de ese Command. • Tipo (Type). Número entero que indica el tipo de Command (qué función puede realizar). Existen ocho tipos definidos de Command:

BACK, CANCEL, HELP, EXIT, ITEM, OK, SCREEN, y STOP. • Prioridad (Priority). Número entero que especifica la importancia o prioridad del Command. Cuanto menor sea el número, mayor

prioridad tendrá.

Si, por ejemplo, se desea crear un objeto Command de tipo BACK, con la etiqueta "Atrás" y prioridad 0 se podría escribir el siguiente código de llamada al constructor: c1= new Command (“Atras”, Command.BACK, 0) Una vez creado el Command habrá que asignarlo a alguna pantalla (Displayable) para que forme parte de ella y activar el oyente de ese Displayable (normalmente el propio midlet). Por ejemplo:

pantalla1.addCommand (c1); pantalla1.setCommandListener (this); // Establecem os como oyente al propio midlet

2.6.- Oyentes. La interfaz CommandListener y el mét odo commandAction. Recuerda que para implementar una interfaz en Java es necesario utilizar la palabra reservada implements: public class Ejemplomidlet extends midlet implements javax.microedition.lcdui.CommandL istener La interfaz CommandListener contiene sólo un método: commandAction (Command c, Displayable d). Dentro de ese método es donde se incluirá el código que debe ejecutarse cuando se produzca el evento Command c que se encuentra en el objeto Displayable d. // Método para la recepción y tratamiento de los ev entos producidos // (Necesario al implementar CommandListener) public void commandAction (Command c, Displayable d) { //Miramos si se ha pulsado nuestro Command c1 if (c == c1) { destroyApp(true); notifyDestroyed(); } else System.out.println("Otro comando pulsado"); }

3.- La interfaz de usuario de alto nivel: pantallas básicas. 3.1.- Pantallas de la interfaz de usuario de alto n ivel. La clase Screen. Como ya vimos, hay cuatro tipos de pantallas o displayables en esta interfaz. Es decir, cuatro clases que heredan directamente de la clase Screen: TextBox. List. Alert. Form. Los principales métodos de la clase Screen, heredados en todas sus subclases son: String getTitle ().

Page 7: resumen.pdf

setTitle (String titulo).

3.2.- Cuadros de texto. La clase TextBox.

import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class MidletEjemploTextBox extends MIDlet im plements CommandListener { private Display display; private TextBox smsTextBox; private Command cmdSalir; private Command cmdEnviar; public MidletEjemploTextBox () { // Obtenemos el Display display= Display.getDisplay (this); // Creamos el TextBox (el unico dis playable/pantalla que va a tener la aplicación) smsTextBox= new TextBox ("Introduzca su men saje", "Texto...", 160, TextField.ANY); cmdSalir= new Command ("Salir", Command.EX IT, 0); cmdEnviar= new Command ("Enviar", Command.C ANCEL, 0);

TextBox smsTextBox;

String mensaje;

smsTextBox= new TextBox (“Introduzca su mensaje”,

“Texto…”, 160, TextField.ANY);

mensaje= smsTextBox.getString();

public void commandAction (Command c,

Displayable d) {

//Miramos si se ha pulsado nuestro

Command c1

if (c == cmdSalir) {

destroyApp (true);

notifyDestroyed ();

} else

System.out.println("Pulsado Command

Enviar...");

}

}

Page 8: resumen.pdf

smsTextBox.addCommand(cmdSalir); smsTextBox.addCommand(cmdEnviar); smsTextBox.setCommandListener(this); } public void startApp() { // Establecemos como pantalla ("displayable ") activa el TextBox smsTextBox display.setCurrent(smsTextBox); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } // Método para la recepción y tratamiento de lo s eventos producidos // (Necesario al implementar CommandListener)

3.3.- Alertas. La clase Alert.

Se dispone de varios tipos de alertas predefinidos. Cada uno de ellos tiene asociado un sonido: ALARM. Indica la llegada de una petición a notificar. CONFIRMATION. Indica la finalización de un evento o acción. ERROR. Indica que se ha producido un error. INFO. Indica información general. WARNING. Indica una situación o problema potencial.

Page 9: resumen.pdf

3.4.- Listas. La clase List.

List listaExclusiva= new List (“Lista exclusiva”, L ist.EXCLUSIVE); List listaMultiple= new List (“Lista multiple”, Li st.MULTIPLE); List listaImplicita= new List (“Lista implícita”, List.IMPLICIT); Además de este constructor, también puedes utilizar un segundo constructor que permite proporcionar una lista con un conjunto inicial de opciones y de imágenes asociadas. List(String titulo, int listType, String[] elemento s, Image[] imagenes)

3.4.1.- Listas implícitas. menu= new List (“Menu”, List.IMPLICIT); menu.insert (0, “Opcion 1”, null); menu.insert (1, “Opcion 2”, null); menu.append (“Opcion 3”, null); ... Cuando se seleccione un elemento de la lista se generará un evento de tipo List.SELECT_COMMAND que tendrá que ser gestionado desde el gestor de eventos commandAction (como si se hubiera seleccionado un Command): public void commandAction (Command c, Displayable d) { if ( c == List.SELECT_COMMAND ) { ... } else { // Gestión de otros posibles Commands de la aplicación } El elemento de la lista seleccionado se puede obte ner mediante el método getSelectedIndex: if ( c == List.SELECT_COMMAND ) { switch (menu.getSelectedIndex()) {

tres tipos diferentes de listas:

Exclusivas (List.EXCLUSIVE), donde

sólo se permite una selección en cada

momento.

Múltiples (List.MULTIPLE), donde se

permiten cero o más selecciones al

mismo tiempo.

Implícitas (List.IMPLICIT), donde la

selección de un elemento genera un

evento.

Page 10: resumen.pdf

case 0: // Acción a reali zar si se ha seleccionado el primer elemento. … case 1: // Acción a reali zar si se ha seleccionado el segundo elemento. … case 2: // Acción a realizar si se ha seleccionad o el tercer elemento. … }

3.4.2.- Listas exclusivas. En este caso, la selección de un item de la lista no da lugar a la generación de ningún evento como sucedía con las listas implícitas, de manera que será necesario utilizar un Command para consultar el estado de las opciones de la lista, lista= new List (“Lista”, List. EXCLUSIVE); Para obtener la opción elegida usamos también el método getSelectedIndex: public void commandAction (Command c, Displayable d ) { if ( c == cmdSeleccionar ) { int indice= lista.getSelectedIndex() switch (indice) { // Realizar la opción oportuna en funció n de la opción elegida case 0: // Acción a reali zar si se ha seleccionado el primer elemento. … case 1: // Acción a reali zar si se ha seleccionado el segundo elemento. … case 2: // Acción a realizar si se ha seleccionad o el tercer elemento. … }

3.4.3.- Listas múltiples. lista= new List (“Lista”, List. MULTIPLE); Para la obtención de las opciones elegidas, tendrás que usar el método getSelectedFlags, que rellena un array de bolean indicando para cada elemento si está seleccionado (true) o no (false): public void commandAction (Command c, Displayable d ) { boolean elementos[]= new boolean [lista.size() ]; lista.getSelectedFlags (elementos); for (int i=0; i<lista.size(); i++) { if (elementos[i]) {

Page 11: resumen.pdf

// Acciones a realizar si el el emento i ha sido seleccionado. } else { // Acciones a realizar si el elemento i no ha sido seleccionado. } }}

4.- La interfaz de usuario de alto nivel: formulari os. 4.1.- Formularios. La clase Form. ¡Un mismo Item no puede estar en dos formularios a la vez! Si intentas insertar un ítem en un formulario cuando ese ítem ya está siendo utilizado en otro formulario se producirá una excepción de tipo IllegalStateException.

4.2.- Elementos en un formulario. La clase Item. La clase Item es una clase abstracta y no puede ser instanciada. Los componentes que se pueden incrustar en un formulario serán objetos de clases que derivan de Item. En concreto dispones de los siguientes: Etiquetas de texto. Clase StringItem. Imágenes. Clase ImageItem. Campos de texto. Clase TextField . Campos de fecha y hora. Clase DateField. Grupos de selección. Clase ChoiceGroup. Barras de progreso. Clase Gauge.

4.3.- Etiquetas de texto. La clase StringItem.

import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class MidletEjemploStringItem extends MIDlet implements CommandListener { Display display; Form formulario; Command cmdTerminar; StringItem strItem1, strItem2, strItem3; public MidletEjemploStringItem () { // Display display= Display.getDisplay(this); // Formulario formulario= new Form ("Formulario con Strin gItem"); // StringItems strItem1= new StringItem ("StringItem1: ", "Apariencia PLAIN", Item.PLAIN); strItem2= new StringItem ("StringItem2: ", "Apariencia HYPERLINK", Item.HYPERLINK); strItem3= new StringItem ("StringItem3: ", "Apariencia BUTTON", Item.BUTTON); formulario.append(strItem1);

import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class MidletEjemploFormVacio extends MIDlet implements CommandListener { Display display; Form formulario; Command cmdTerminar; public MidletEjemploFormVacio () { // Display display= Display.getDisplay(this); // Formulario formulario= new Form ("Formulario vacio"); // Commands cmdTerminar= new Command ("Terminar", Command.EXIT, 0); formulario.addCommand (cmdTerminar); // Establecemos el oyente formulario.setCommandListener(this); } public void startApp() { display.setCurrent(formulario); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction (Command c, Displayable d) { if (c == cmdTerminar) { destroyApp (false); notifyDestroyed (); } } }

Las posibles apariencias del texto de un objeto

StringItem son:

Item.PLAIN. Aspecto normal. Utilizado normalmente

para mostrar información textual no interactiva.

Item.HYPERLINK. Aspecto de tipo hiperenlace.

Item.BUTTON. Aspecto de tipo "botón". Utilizado para

simular botones en el formulario (lo veremos más

adelante).

formulario.append(strItem2);

formulario.append(strItem3);

// Commands

cmdTerminar= new Command

("Terminar", Command.EXIT, 0);

formulario.addCommand (cmdTerminar);

// Establecemos el oyente

formulario.setCommandListener(this);

}

public void startApp() {

display.setCurrent(formulario);

}

public void pauseApp() {

}

public void destroyApp(boolean

unconditional) {

}

public void commandAction (Command c,

Displayable d) {

if (c == cmdTerminar) {

destroyApp (false);

notifyDestroyed ();

} }}

Page 12: resumen.pdf

4.4.- Imágenes. La clase Image. Las imágenes (objetos de la clase Image) pueden ser: Inmutables. Imágenes que una vez que son creadas no es posible modificarlas. Una imagen inmutable suele ser creada a partir de un recurso (archivo, array de bytes, etc.). Mutables. Cuando se crea una imagen mutable en realidad se está reservando un bloque de memoria para crear en él la imagen más adelante (y modificarla si así se decide). Para que una imagen mutable se haga visible es necesario que se indique explícitamente (por ejemplo mediante el método paint de la clase Canvas). Las imágenes inmutables pueden aparecer en: Formularios (Form), incrustado como un ítem más. Los elementos de una lista (List) o de un ChoiceGroup (como un adorno que acompaña a cada elemento). Alertas (Alert), como imagen que acompaña al texto de la alerta.

Image imagen; imagen= Image.createImage (“/resources/europa_occi dental.png”);

4.5.- Imágenes. La clase ImageItem. Para insertar imágenes (objetos de tipo Image) en un formulario es necesario utilizar un marco (un componente o ítem de formulario) en el que poder incrustarlas: la clase ImageItem.

El parámetro textoAlt del constructor consiste en el texto alternativo a la imagen que se mostrará en caso de que ésta no pueda ser dibujada en la pantalla (normalmente porque no quepa). El parámetro layout indica la posición de la imagen (layout o disposición) en la pantalla (LAYOUT_LEFT, LAYOUT_CENTER, LAYOUT_RIGHT, LAYOUT_NEWLINE_AFTER, LAYOUT_NEWLINE_BEFORE.). El parámetro apariencia tiene los mismos posibles valores que en el caso de StringItem (PLAIN, HYPERLINK, BUTTON ). Image imagen= Image.createImage (“/resources/europa _occidental.png”); ImageItem elemento= new ImageItem (“Europa occiden tal”, imagen, ImageItem.LAYOUT_DEFAULT, “Cargando… ”);

4.6.- Campos de texto. La clase TextField.

Form formulario= new Form ("Formulario con campos d e texto"); TextField nombre= new TextField (“Nombre: ”, null, 100, TextField.ANY); TextField password= new TextField ("Clave: ", "", 50, TextField.PASSWORD); TextField telefono= new TextField ("Telefono: ", " +34", 15, TextField.PHONENUMBER); TextField email= new TextField ("E-mail: ", "", 50 , TextField.EMAILADDR); TextField web= new TextField ("Pagina web: ", "", 50, TextField.URL); formulario.append (nombre); formulario.append (password); import javax.microedition.midlet.*; import javax.microedition.lcdui.*;

formulario.append (telefono);

formulario.append (email);

formulario.append (web);

Page 13: resumen.pdf

public class MidletEjemploTextField extends MIDlet implements CommandListener { Display display; Form formulario; Command cmdTerminar; StringItem etiqueta1; TextField nombre, telefono, email, web, passwor d; public MidletEjemploTextField () { // Display display= Display.getDisplay(this); // Formulario formulario= new Form ("Formulario con campo s de texto"); // StringItems etiqueta1= new StringItem ("", "Ejemplos de TextField", Item.PLAIN); password= new TextField ("Clave: ", "", 50, TextField.PASSWORD); nombre= new TextField ("Nombre: ", null, 10 0, TextField.ANY); telefono= new TextField ("Telefono: ", "+34 ", 15, TextField.PHONENUMBER); email= new TextField ("E-mail: ", "", 50, T extField.EMAILADDR); web= new TextField ("Pagina web: ", "", 50, TextField.URL);

4.7.- Campos de fecha y hora. La clase DateField.

Esta clase hace uso de la clase java.util.Date para manipular fechas y horas. El modo de entrada del contenido de un objeto DateField puede establecerse para manipular fechas (DATE), horas (TIME) o ambas (DATE_TIME). Date ahora= new Date (); DateField fechaAhora= new DateField (“Instante act ual: “, DateField.DATE_TIME); DateField fechaCita= new DateField (“Fecha de la c ita: “, DateField.DATE); DateField horaCita= new DateField (“Hora de la cit a: “, DateField.TIME); -------------------------------------------------------------------------------------------------- import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import java.util.Date; public class MidletEjemploDateField extends MIDlet implements CommandListener { Display display; Form formulario; Command cmdTerminar; StringItem etiqueta; DateField fechaAhora, fechaCita, horaCita; Date ahora; public MidletEjemploDateField () { // Display display= Display.getDisplay(this); // Formulario formulario= new Form ("Formulario con campo s de fecha"); public void destroyApp(boolean unconditional) { } public void commandAction (Command c, Displayab le d) { if (c == cmdTerminar) { destroyApp (false); notifyDestroyed (); } } }

4.8.- Grupos de selección. La clase ChoiceGroup. Los eventos de un componente de tipo ChoiceGroup se pueden gestionar de dos formas diferentes: Mediante el método commandAction (interfaz CommandListener), del mismo modo que cuando se trabajaba con listas (exclusivas o múltiples). Es decir, incluyendo en el formulario un Command que cuando sea activado realice una consulta de las opciones elegidas en el ChoiceGroup. Mediante el método itemStateChanged (interfaz ItemStateListener), que será llamado cada vez que se seleccione (o deseleccione) una opción

formulario.append(etiqueta1);

formulario.append(nombre);

formulario.append(password);

formulario.append(telefono);

formulario.append(email);

formulario.append(web);

// Commands

cmdTerminar= new Command ("Terminar",

Command.EXIT, 0);

formulario.addCommand (cmdTerminar);

// Establecemos el oyente

formulario.setCommandListener(this);

}

public void startApp() {

display.setCurrent(formulario);

}

public void pauseApp() {

}

// Elementos etiqueta= new StringItem ("", "Ejemplos de DateField", Item.PLAIN); ahora= new Date (); fechaAhora= new DateField ("Instante actual : ", DateField.DATE_TIME); fechaAhora.setDate(ahora); fechaCita= new DateField ("Fecha de la cita : ", DateField.DATE); horaCita= new DateField ("Hora de la cita: ", DateField.TIME); formulario.append(etiqueta); formulario.append(fechaAhora); formulario.append(fechaCita); formulario.append(horaCita); // Commands cmdTerminar= new Command ("Terminar", Command.EXIT, 0); formulario.addCommand (cmdTerminar); // Establecemos el oyente formulario.setCommandListener(this); } public void startApp() { display.setCurrent(formulario); } public void pauseApp() { }

Page 14: resumen.pdf

import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class MidletEjemploChoiceGroup extends MIDle t implements CommandListener { Display display; Form formulario; Command cmdTerminar; StringItem etiqueta; ChoiceGroup grupo; public MidletEjemploChoiceGroup () { // Display display= Display.getDisplay(this); // Formulario formulario= new Form ("Formulario con grupo s de seleccion"); // Elementos etiqueta= new StringItem ("", "Ejemplos de ChoiceGroup", Item.PLAIN); grupo= new ChoiceGroup ("Posibles destinos: ", Choice.MULTIPLE); grupo.append("Kenia", null); grupo.append("Tanzania", null); grupo.append("Uganda", null); grupo.append("Ruanda", null); grupo.append("Burundi", null); formulario.append(etiqueta); formulario.append(grupo);

4.9.- Barras de progreso. La clase Gauge. Una barra de progreso se considera interactiva cuando puede ser cambiada por el usuario al realizar éste alguna acción, por ejemplo, al pulsar un botón. Se considera no interactiva cuando su valor cambia por la lógica interna de la aplicación, por ejemplo, la barra de progreso de un contador de tiempo, o de una descarga, o de la instalación de un programa.

// Commands cmdTerminar= new Command ("Terminar", Command.EXIT, 0); formulario.addCommand (cmdTerminar); // Establecemos el oyente formulario.setCommandListener(this); } public void startApp() { display.setCurrent(formulario); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction (Command c, Displayable d) { if (c == cmdTerminar) { destroyApp (false); notifyDestroyed (); } } }

Page 15: resumen.pdf

import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class MidletEjemploGauge extends MIDlet impl ements CommandListener { Display display; Form formulario; Command cmdTerminar; StringItem etiqueta; Gauge barra1, barra2, barra3; public MidletEjemploGauge () { // Display display= Display.getDisplay(this); // Formulario formulario= new Form ("Formulario con barra s de desplazamiento"); // Elementos etiqueta= new StringItem ("", "Ejemplos de Gauge", Item.PLAIN); barra1= new Gauge ("Volumen", true, 100, 20 ); barra2= new Gauge ("Tono", true, 100, 50); barra3= new Gauge ("Resonancia", false, 100 , 70); formulario.append(etiqueta); formulario.append(barra1); formulario.append(barra2); formulario.append(barra3);

4.10.- Organizando los elementos en un formulario. El de los orden de inserción elementos en el formulario es importante (método append), pues se irán mostrando en ese orden. También puedes decidir insertar un elemento en una posición determinada (entre dos elementos) con el método insert. El atributo de disposición (layout) de un ítem puede permitirte situarlo en una determinada zona de la pantalla dentro de la fila en la que se esté colocando el componente (Item.LAYOUT_LEFT, Item.LAYOUT_RIGHT, etc.), pero además puedes decidir si quieres que ese elemento comience en una nueva fila obligatoriamente (Item.LAYOUT_NEWLINE_BEFORE) o que no haya más ítems en esa fila después de él (Item.LAYOUT_NEWLINE_AFTER). También existen otras opciones posibles como utilizar todo el espacio disponible (Item.LAYOUT_EXPAND) o lo contrario (Item.LAYOUT_SHRINK). El ítem Spacer (también subclase de Item) permite definir ítems "invisibles" pero de un determinado tamaño, de manera que puedes colocar separadores (espacios en blanco) entre elementos que estén en una misma fila.

4.11.- Gestión de eventos en un formulario. En este caso se trata de la interfaz ItemStateListener y de su método abstracto

itemStateChanged. Otra forma de gestionar eventos sobre los elementos de un formulario es mediante la interfaz ItemCommandListener, que dispone también de un único método y que nuevamente se llama commandAction. Para ello, tendremos que asociar un Command a un Item de manera que cuando se accione ese Command se ejecutará el método commandAction.

4.11.1.- Gestión de los cambios en un Item. La inte rfaz ItemStateListener. Debes tener en cuenta que si es la propia aplicación la que modifica el valor de un Item, el listener listener no será activado y por tanto no se llamará al método itemStateChanged. Para llevar a cabo esta gestión será necesario lo siguiente:

Crear y asignar a un formulario los Items cuya modificación se desea controlar. Asignar un oyente para los elementos del formulario (método setItemStateListener). Escribir el código apropiado para gestionar el evento (implementar método itemStateChanged de la interfaz ItemStateListener).

public class midlet extends midlet implements Comma ndListener, ItemStateListener Form formulario; ... public void itemStateChanged (Item item) { if (item == item1) { // Acción si se ha modificado el it em1 } else if (item == item2) { // Acción si se ha modificado el it em1 } else if (item == fecha) { // Acción si se ha modificado el it em1 …

// Commands cmdTerminar= new Command ("Terminar", Command.EXIT, 0); formulario.addCommand (cmdTerminar); // Establecemos el oyente formulario.setCommandListener(this); } public void startApp() { display.setCurrent(formulario); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction (Command c, Displayable d) { if (c == cmdTerminar) { destroyApp (false); notifyDestroyed (); } }}

Page 16: resumen.pdf

import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class MidletEjemploItemStateListener extends MIDlet implements CommandListener, ItemStateListen er { Display display; Form formulario; Command cmdTerminar; StringItem etiqueta; TextField nombre; Gauge edad; DateField fecha; Alert alerta; public MidletEjemploItemStateListener () { // Display display= Display.getDisplay(this); // Formulario formulario= new Form ("Formulario con event os"); // StringItems etiqueta= new StringItem (null, "Elementos del formulario:", Item.PLAIN); nombre= new TextField ("Nombre: ", null, 15 , TextField.ANY); edad= new Gauge ("Edad", true, 100, 20); fecha= new DateField ("Fecha: ", DateField. DATE); formulario.append(etiqueta); formulario.append(nombre); formulario.append(edad); formulario.append(fecha); // Alerta alerta= new Alert ("Mensaje", "Pulsado...", null, AlertType.INFO); alerta.setTimeout (Alert.FOREVER); // Commands cmdTerminar= new Command ("Terminar", Comma nd.EXIT, 0); formulario.addCommand (cmdTerminar); // Establecemos los oyentes formulario.setCommandListener(this); formulario.setItemStateListener (this); }

4.11.2.- Gestión de Commands asociados a un Item. L a interfaz ItemCommandListener. Es posible asociar Commands a un Item mediante el método addCommand o setDefaultCommand. void CommandAction (Command c, Item item) Para llevar a cabo esta gestión será necesario lo siguiente: Crear el Item al que se le desea asociar un comando. Crear el Command que se le desea asociar. Asignar el Command al Item (método addCommand o setDefaultCommand). Asignar un oyente para el Item (método setItemCommandListener). Escribir el código apropiado para gestionar el evento (implementar el método CommandAction de la interfaz ItemCommandListener).

public void startApp() { display.setCurrent(formulario); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction (Command c, Displayable d) { if (c == cmdTerminar) { destroyApp (false); notifyDestroyed (); } } public void itemStateChanged (Item item) { String mensaje; if (item == nombre) { mensaje= "Detectado cambio en TextField "; } else if (item == edad) { mensaje= "Detectado cambio en Gauge"; } else if (item == fecha) { mensaje= "Detectado cambio en DateField "; } else { mensaje= "Detectado cambio en objeto no identificado"; } alerta.setString(mensaje); display.setCurrent(alerta, formulario); } }

Page 17: resumen.pdf

import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class MidletEjemploItemCommandListener exten ds MIDlet implements CommandListener, ItemCommandLi stener { Display display; Form formulario; Command cmdTerminar, cmdEtiqueta; StringItem etiqueta; Alert alerta; public MidletEjemploItemCommandListener () { // Display display= Display.getDisplay(this); // Formulario formulario= new Form ("Formulario con event os"); // Items etiqueta= new StringItem ("", "Etiqueta", I tem.PLAIN); formulario.append(etiqueta); // Alerta alerta= new Alert ("Etiqueta", "Pulsada la etiqueta.", null, AlertType.INFO); alerta.setTimeout (Alert.FOREVER); // Commands cmdTerminar= new Command ("Terminar", Comma nd.EXIT, 0); cmdEtiqueta= new Command ("OK", Command.OK, 1); formulario.addCommand (cmdTerminar); etiqueta.addCommand(cmdEtiqueta); // Establecemos los oyentes formulario.setCommandListener(this); etiqueta.setItemCommandListener (this); }

public void startApp() { display.setCurrent(formulario); } public void pauseApp() { } public void destroyApp(boolean unconditiona l) { } public void commandAction (Command c, Displayab le d) { if (c == cmdTerminar) { destroyApp (false); notifyDestroyed (); } } public void commandAction (Command c, Item item ) { if (item == etiqueta) { if (c == cmdEtiqueta) { display.setCurrent(alerta, formular io); } } }}

Page 18: resumen.pdf

4.11.3.- Ejemplo de Commands asociados a Items. Sim ulación de botones.

Para simular un botón basta con que sigamos los pasos vistos en el apartado anterior: Crear un Item (StringItem o ImageItem) al que se le asocia un Command. En este caso es mejor utilizar el método setDefaultCommand. Establecer el oyente de ese Item. Implementar el método commandAction con las acciones que se deban tomar cuando se active el Command sobre ese Item. En estos casos se suele utilizar el valor Item.BUTTON para la apariencia del Item (normalmente un StringItem o un ImageItem) y de ese modo en la pantalla aparecerá de manera que tenga un aspecto "pulsable", aunque eso siempre dependerá de la implementación de la máquina virtual en el dispositivo (podría darse el caso en que no haya diferencia de presentación entre las apariencias PLAIN, BUTTON o HYPERLINK). Se recomienda utilizar el método setDefaultCommand (establecer comando por defecto) para asociar un Command a un Item a la hora de simular un botón porque así cuando se pulse en el dispositivo la tecla con la que habitualmente se seleccionan opciones (normalmente el botón central de los cursores o del joystick) se activará ese Command (el establecido por defecto). De ese modo la simulación del botón quedará muy elegante import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class MidletEjemploBotones extends MIDlet im plements CommandListener, ItemCommandListener { Display display; Form formulario; Command cmdTerminar, cmdBoton1, cmdBoton2, cmdB oton3; StringItem boton1, boton2, boton3; Alert alerta; public MidletEjemploBotones () { // Display display= Display.getDisplay(this); // Formulario formulario= new Form ("Formulario con boton es"); // Items boton1= new StringItem ("", "Boton 1", Item .BUTTON); boton2= new StringItem ("", "Boton 2", Item .BUTTON); boton3= new StringItem ("", "Boton 3", Item .BUTTON); formulario.append(boton1); formulario.append(boton2); formulario.append(boton3); // Alerta alerta= new Alert ("Atencion:", "Pulsado un boton.", null, AlertType.INFO); alerta.setTimeout (Alert.FOREVER); // Commands cmdTerminar= new Command ("Terminar", Comma nd.EXIT, 0); cmdBoton1= new Command ("OK", Command.OK, 1 ); cmdBoton2= new Command ("OK", Command.OK, 1 ); cmdBoton3= new Command ("OK", Command.OK, 1 ); formulario.addCommand (cmdTerminar); boton1.setDefaultCommand(cmdBoton1); boton2.setDefaultCommand(cmdBoton2); boton3.setDefaultCommand(cmdBoton3); // Establecemos los oyentes formulario.setCommandListener(this); boton1.setItemCommandListener (this); boton2.setItemCommandListener (this); boton3.setItemCommandListener (this); }

4.12.- Uniéndolo todo También es recomendable que tus aplicaciones incluyan siempre algunas pautas que ayuden al usuario a manejar el programa con facilidad: Una pantalla inicial de presentación de la aplicación. Una pantalla de ayuda con algunas instrucciones mínimas sobre la aplicación. Comandos con etiquetas claras y concisas. Formularios sin recargar excesivamente.

5.- Creación de interfaces gráficos de usuario util izando asistentes y herramientas del entorno integrado. En este apartado vamos a echar un vistazo al asistente de diseño de aplicaciones móviles de NetBeans: Visual Mobile Designer Cuando un midlet es desarrollado con el VMD (Visual Mobile Designer) dispondrás de cuatro posibles vistas para trabajar con él:

• Vista Flow. Es la vista que te permite crear y modificar el flujo de pantallas de la aplicación, indicando cómo se puede ir de una pantalla a otra y a través de qué comando.

• Vista Screen Design. A través de esta vista puedes realizar el diseño de las pantallas, observando el aspecto final que tendrán cuando la aplicación sea ejecutada.

• Vista Source. Ésta la vista que has estado utilizando hasta ahora. Es la vista del código fuente de las clases de la aplicación. • Vista Analyzer. Esta vista es útil para comprobar la compatibilidad de la aplicación con versiones anteriores de la configuración CLDC.

public v oid startApp() { display.setCurrent(formulario); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction (Command c, Displayable d) { if (c == cmdTerminar) { destroyApp (false); notifyDestroyed (); } } public void commandAction (Command c, Item item ) { String mensaje= "Evento no identificado"; if (item == boton1) { if (c == cmdBoton1) { mensaje= "Pulsado boton 1"; } } else if (item == boton2) { if (c == cmdBoton2) { mensaje= "Pulsado boton 2"; } } else if (item == boton3) { if (c == cmdBoton3) { mensaje= "Pulsado boton 3"; } } alerta.setString(mensaje); display.setCurrent(alerta, formulario); }}

Page 19: resumen.pdf

CÓMO INSERTAR IMÁGENES EN UN MENÚ DE TIPO LISTA (Cl ase List) Tenéis que tener en cuenta que la carpeta raíz considera que es la carpeta SRC de nuestro PROYECTO. El formato ideal es PNG, aunque también entiende JPG. Un buen tamaño es 25x25 píxeles.

a) Un objeto Image para guardar en él la imagen: private Image img1, img2, img3; b) Un objeto de tipo array de imágenes (Image []) que será donde guardemos todas las imágenes

Image[] todasImagenes = {img1, img2, img3}; Creamos las imágenes mediante el método “createImagen(“ruta”);”

Cargamos el ARRAY con todos los objetos IMAGE: Image[] todasImagenes={img1,img2,img3}; Creamos la lista usando el constructor: List(String title, int listType, String[] stringEle ments, Image[] imageElements) menu=new List("MENU PRINCIPAL", List.IMPLICIT, Item sMenu, todasImagenes); También se podría haber hecho así: Image[] todasImagenes=new Image[6]; bucle { imagenes[i]=Image.createImage(“ruta del archive.png ”); fin bucle}

6.- La interfaz de usuario de bajo nivel. Todas las pantallas que utilicen la API de bajo nivel heredan de la clase Canvas.

6.1.- El lienzo donde dibujar. La clase Canvas. La clase Canvas posee un método abstracto llamado paint() que se encarga de dibujar en la pantalla del dispositivo. Ese método tendrá que ser implementado en cada clase que sea subclase de Canvas. El código para crear una clase en java es bien simple, así: Public class HelloCanvas extends Canvas implements CommandListener { //código de la clase } “implements CommandListener”. Esa instrucción permite que el móvil detecte los comandos como exitCommand, o los okCommand u otros. 1º) Constructor de la Clase HelloCanvas: public HelloCanvas() { try { // Set up this canvas to listen to command events setCommandListener(this); Con la instrucción: setCommandListener deja listo al Canvas para “escuchar” los comandos // Add the Exit command Agrega un exitCommand al Canvas addCommand(new Command("Exit", Command.EXIT, 1)); } catch(Exception e) { e.printStackTrace(); } } 2º) El método paint: se usa para dibujar en el Canvas y mostrarse en la pantalla del móvil public void paint(Graphics g) { Esa sentencia crea un objeto de la clase Graphics, el objeto se llama g. g.drawString("Sample Text",0,0,Graphics.TOP|Graphic s.LEFT); } La clase Graphics. La clase Graphics posee todos los métodos necesarios para dibujar en pantalla, mostrar gráficos y mostrar textos. drawString y sirve para dibujar una cadena de caracteres dentro del Canvas,

3º) Métodos para detectar eventos relacionados con las pulsaciones de una tecla protected void keyPressed(int keyCode) { Se ejecuta cuando se presiona una tecla } protected void keyReleased(int keyCode) { Se ejecuta cuando se suelta una tecla } protected void keyRepeated(int keyCode) { Se ejecuta cuando se deja presionada una tecla } 4º) Métodos para detectar eventos relacionados con punteros protected void pointerDragged(int x, int y) { } protected void pointerPressed(int x, int y) { } protected void pointerReleased(int x, int y) { } 5º) Métodos para procesar comandos (el commandActio n) public void commandAction(Command command, Displaya ble displayable) { }

Page 20: resumen.pdf

Enlazar la clase HelloCanvas con nuestro Midlet La solución es sencilla y quizá muchos ya lo saben, recuerde las clases son plantillas para crear objetos, HelloCanvas es una clase, entonces es posible crear un objeto de la clase HelloCanvas y usarlo en la clase MIDlet Para crear un objeto, primero hay que declararlo: HelloCanvas miCanvas; Lo anterior es la declaración, para realmente para crearlo se usa el comando new así: miCanvas = new HelloCanvas(); Solo falta un detalle, recordad que para mostrar cu alquier cosa en la pantalla del móvil se usa la cla se Display. Esta clase, representa el hardware, la pantalla del móvil, para acceder a esta pantalla se usa el método getdisplay(this) (se usa el this, para indicar que el MIDlet actual es el que se envía como parámetro), finalmente el método setCurrent(pantalla) es usado para indicar que la pantalla actual será la definida por el objeto pantalla. Display.getDisplay(this).setCurrent(miCanvas); Por tanto, el código del MIDlet debe quedaros así: public class Midlet extends MIDlet { HelloCanvas miCanvas; public void startApp() { miCanvas = new HelloCanvas(); Display.getDisplay(this).setCurrent(miCanvas); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } } el comando EXIT se agrega (como ya dije) en la clase HelloCanvas, ¿cómo podría entonces mandar llamar el método destroyApp(), si este método está en la clase MIDlet? Ahora si se ve el problema ¿verdad?. La solución es la siguiente, es posible enviar información entre clases, esto sólo se logra por medio del constructor. se tiene que enviar un objeto de la clase MIDlet, para que con el objeto se pueda mandar llamar el método destroyApp(). entonces la sentencia para crear el objeto es así: miCanvas = new HelloCanvas(this); Por tanto, el código final de nuestro MIDlet será: public class Midlet extends MIDlet { HelloCanvas mi Canvas; public void startApp() { miCanvas = new HelloCanvas (this); Display.getDisplay(this).setCurrent(miCanvas); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } } Cambios a realizar en la clase HelloCanvas 1º) Cambiaremos el CONSTRUCTOR: public HelloCanvas(Midlet m ) { // código del constructor } IMPORTANTÍSIMO: El nombre que debéis poner donde yo puse “Midlet” debe ser el nombre que hayáis dado a vuestra clase MIDlet cuando la creasteis y que coincide con el nombre de l archivo .java que contiene vuestro MIDlet. Podría ser: “EjMidlet”, “PrimerMidlet”,… Declaro un objeto de la clase Midlet (en mi ejemplo es Midlet, en el vuestro……., ver el comentario que os puse en IMPORTANTÍSIMO): private Midlet mid; Ahora, a ese objeto privado le asigno el valor de “ m” que se recibe como parámetro: mid = m; O también podemos poner (más correcto, aunque hace lo mismo): this.mid = m; De momento, el código parcial de la clase HelloCanv as queda así: public class HelloCanvas extends Canvas implements CommandListener { private Midlet mid; /** * constructor */ public HelloCanvas(Midlet m ) { this.mid = m; // código del constructor } 2º) Añadiremos el código para el botón EXIT: public void commandAction(Command command, Displaya ble displayable) { mid.destroyApp(true); mid.notifyDestroyed(); } Como sólo es un comando el que se tiene en la clase HelloCanvas es posible hacer lo anterior, cuando hay más de un comando se debe usar un if para identificar cuál comando se presionó pero en este ejemplo sólo se tiene el comando de EXIT. Si al ejecutarlo, ves la pantalla negra y no sale el texto, es porque tu emulador de teléfono usa como color inicial el NEGRO y por tanto, TEXTO NEGRO sobre FONDO NEGRO no se ve. En este caso, añade esta línea (justo antes de escribir el texto “Hola Mundo”) a tu método “paint()” de la clase HelloCanvas: g.setColor(255, 255, 255); Con esta línea estás eligiendo el color BLANCO y como el fondo es negro, ya verás el texto. Por si tienes dudas, tú método paint() debe quedar así: public void paint(Graphics g) { g.setColor(255, 255, 255); g.drawString("Hola Mundo, en modo gráfico", 20, 100 , Graphics.TOP | Graphics.LEFT); }

Page 21: resumen.pdf

6.2.- Eventos de bajo nivel. Se dispone de dos medios de interacción con un objeto Canvas:

• Mediante los Commands, como has hecho en la API de alto nivel. • Mediante eventos de bajo nivel.

Los eventos de bajo nivel son: • Eventos de teclado. • Eventos de puntero.

/*-ejemp lo creación tablero nxm casillas protected void paint(Graphics g) { int ancho= getWidth (); int alto= getHeight (); int i,j; // Fondo g.setColor (0xFFFFFF); // Color blanco g.fillRect(0, 0, ancho, alto); // Tablero g.setColor (0x000000); // Color negro for (i=0; i<filas; i++) { for (j=0; j<columnas; j++) { g.drawRect(j*ancho/columnas, i*alto /filas, ancho/columnas, alto/filas); } } }

Page 22: resumen.pdf

Si por ejemplo queremos mostrar en pantalla cuál es la tecla que se va pulsando en cada momento podríamos escribir el siguiente código en el método keyPressed: protected void keyPressed (int keyCode) { texto = "Key code: " + String.valueOf(keyCo de) + " - Key name: " + getKeyName(keyCode) ; repaint(); }

6.2.2.- Acciones de juego. Las acciones de juego no son más que códigos estándar para las funciones típicas de juegos (direcciones, disparo, etc.). El perfil MIDP define las siguientes acciones de juego: UP, DOWN, LEFT, RIGHT, FIRE, GAME A, GAME B, GAME C y GAME D.

La implementación del método keyPressed podría quedar entonces así: Protected void keyPressed (int keyCode) { int gameAction= getGameAction (keyCode); switch (gameAction) { case UP: // Acciones si se pulsa te cla “arriba” case DOWN: // Acciones si se pulsa tecla “a bajo” case LEFT: // Acciones si se pulsa tecla “izquierda” case RIGHT: // Acciones si se pulsa tecla “d erecha” case FIRE: // Acciones si se pulsa tecla “disparo” … } repaint (); }

6.3.- Dibujar elementos en la pantalla. El método p aint. Para ello Canvas dispone del método abstracto paint que se encarga de dibujar el contenido de la pantalla. Dado que el método paint es abstracto, para cada subclase de Canvas que definas deberás implementar ese método. Un ejemplo trivial de implementación de paint podría ser: protected void paint (Graphics g) { g.drawRect (5,5,10,10); }

Page 23: resumen.pdf

Cuando el administrador de aplicaciones hace visible un Canvas en la pantalla, llama al método showNotify y cuando lo elimina de la pantalla hace una llamada a hideNotify. Estos métodos están vacíos en la clase Canvas. Su implementación puede resultar muy útil para: Almacenar el estado de la aplicación (disposición de la pantalla, variables, etc.) cuando el AMS por alguna razón (por ejemplo por una llamada telefónica entrante o por la llegada de un mensaje corto) quita un objeto Canvas de la pantalla del dispositivo (antes llamará a hideNotify). Restaurar posteriormente la aplicación (al llamar a showNotify) con la información que previamente había sido almacenada.

6.4.- Herramientas de dibujo. La clase Graphics. Hay dos formas de obtener un objeto de la clase Graphics:

• Como parámetro del método paint: protected void paint (Graphics g). Ese objeto es el que podrás utilizar para dibujar elementos en la pantalla.

• A través de una imagen mutable (una imagen que se creó reservando un bloque de memoria y sobre la que luego se puede obtener un objeto Graphics para poder escribir sobre ella).

6.5.- Sistema de coordenadas. El sistema de coordenadas representa posiciones entre píxeles, no los propios píxeles. Por tanto el primer píxel en la esquina superior izquierda de la pantalla sería el cuadrado definido por las coordenadas (0,0), (1,0), (0,1) y (1,1). Mediante los métodos getWidth y getHeight de la clase Canvas se puede obtener el alto y el ancho de la pantalla. /*-------------------------------------------------- * Método paint * Dibujamos los ejes de coordenadas *-------------------------------------------------*/ protected void paint (Graphics g) { // Borramos la pantalla g.setColor(0xFFFFFF); g.fillRect(0, 0, getWidth(), getHeight()); // Origen de coordenadas g.setColor(0x000000); //Negro g.drawString("(0,0)",0,0,Graphics.TOP|Graph ics.LEFT); // Eje vertical g.drawLine(0, 0, 0, getHeight()); g.fillTriangle(-getHeight()/20, (19*getHeig ht())/20, getHeight()/20, (19*getHeight())/20, 0, g etHeight()); // Eje horizontal g.drawLine(0, 0, getWidth(), 0); g.fillTriangle((19*getWidth())/20, -getWidt h()/20, getWidth(), 0, (19*getWidth())/20, getWidth ()/20); } El origen de coordenadas puede ser modificado mediante el método translate de la clase Graphics, provocando un desplazamiento de todos los objetos en la pantalla.

6.6.- Manejo de los colores. La clase Graphics proporciona un modelo de coloreado de 24 bits de tipo RGB con 8 bits para cada componente de color (rojo, verde, azul).

Graphics g; g.setColor (0, 0, 0); // Color n egro g.setColor (255, 255, 255); // Color blanco g.setColor (0, 0, 255); // Color azul g.setColor (0x00FF00); // Color verde Una vez seleccionado un color determinado para el "pincel", cualquier cosa que se dibuje en la pantalla será con ese color hasta que se establezca otro color. Por ejemplo: g.setColor (255, 0, 0); g.fillRect (0, 0, getWidth(), getHeight()); // pintaría toda la pantalla de color rojo

Page 24: resumen.pdf

6.7.- Escritura de texto. Para dibujar texto en la pantalla la clase Graphics proporciona una serie de herramientas (entre ellas el método drawString). El aspecto que tendrá el texto al mostrarse en la pantalla podrá ser configurado a través de la clase Font , permitiendo jugar con la combinación de tres tipos de atributos: aspecto, estilo y tamaño.

Para obtener una fuente podemos utilizar el método estático getFont de la clase Font que devuelve un objeto de tipo Font. Para ello se debe indicar una especificación del tipo de fuente que se desea (atributos face, style y size; o aspecto, estilo y tamaño), por ejemplo: Font fuente= Font.getFont (FACE_SYSTEM, STYLE_BOLD, SIZE_LARGE); Una vez que se disponga de un objeto de la clase Font, habrá que asociarlo al objeto Graphics que será quien ejecutará alguno de sus métodos (por ejemplo drawString) para dibujar el texto. Esa asociación se puede llevar a cabo mediante el método setFont de la clase Graphics. Por ejemplo: g.setFont (fuente); g.drawString (“Ejemplo de texto en Canvas”, getWidt h()/2, getHeight()/2, BASELINE | HCENTER); La definición de un punto de anclaje consiste en la combinación de una constante horizontal (LEFT, HCENTER, RIGHT) con una constante vertical (TOP, BASELINE, BOTTOM) mediante el operador lógico OR.

6.8.- Dibujo de figuras geométricas.

6.9.- Dibujo de imágenes. Uso del contexto gráfico. Para imágenes inmutables: -Se crea la imagen (por ejemplo a partir de un archivo gráfico): Image imagen= Image.createImage (“/resources/europa _occidental”); -Se muestra la imagen en un Canvas (usando el método drawImage de la clase Graphics dentro del método paint del Canvas): protected void paint (Graphics g) { ... g.drawImage (imagen, g.getWidth(), g.getHeight (), Graphics.HCENTER | Graphics.VCENTER); ...} Para imágenes mutables: -Se crea la imagen mutable (reserva de espacio únicamente): Image imagen= Image.createImage (60, 40); -Se crea y manipula el contenido de la imagen (mediante el uso de las herramientas proporcionadas por la clase Graphics: rectángulos, triángulos, líneas, arcos, textos, etc.). Para ello hay que obtener el contexto gráfico de la imagen (un objeto de tipo Graphics).

Page 25: resumen.pdf

Graphics contexto= imagen.getGraphics (); // Ob tención del contexto gráfico de la imagen // Dibujo sobre la imagen contexto.setColor (255, 255, 0); contexto.fillRect (0, 0, imagen.getWidth(), imagen. getHeight()); … Se muestra la imagen en un Canvas (usando el método drawImage de la clase Graphics dentro del método p aint del Canvas): protected void paint (Graphics g) { ... g.drawImage (imagen, g.getWidth(), g.getHeight (), Graphics.HCENTER | Graphics.VCENTER); ... }

6.10.- Recorte de regiones. Cada vez que se realiza una llamada al método paint, el dispositivo tiene que redibujar toda la pantalla. Si pudieras dibujar únicamente una parte de la pantalla (la que va a ser modificada) podría obtenerse un importante ahorro en tiempo.

6.11.- Desplazamiento del origen de coordenadas.

7.- Una interfaz de usuario para juegos. Es importante recordar que las clases especializadas para el desarrollo de juegos fueron incorporadas a partir de la versión 2.0 del perfil MIDP, así que aquellos móviles que sólo soporten la versión 1.0 no podrán ejecutarlas.

7.1.- Utilización de la API de juegos. Además de los métodos de Canvas, esta clase proporciona algunas funcionalidades adicionales para el desarrollo de juegos como: Creación de animaciones rápidas y sin parpadeo mediante una sincronización apropiada de los gráficos en la pantalla. Posibilidad de examinar el estado de las teclas del dispositivo. A partir de los objetos de esta clase y todos los demás componentes del paquete Game (capas, sprites, escenarios, etc.) podrás comenzar a diseñar pequeños juegos de prueba. Se crea primero una clase que derive o herede de la clase GameCanvas (igual que hacíamos con Canvas), en código es así: public class EjemploGameCanvas extends GameCanvas { // Código de la clase } Pero eso no es todo, está clase porque así está diseñada, se debe ejecutar en su propio “subproceso”, para implementar esto en Java se usa la interfaz Runnable, para hacerlo se escribe en la definición de la clase el “implements Runnable” así: import javax.microedition.lcdui.game.*; public class EjemploGameCanvas extends GameCanvas i mplements Runnable { // Código de la clase } El constructor de la clase que hereda de GameCanvas, según la documentación, requiere un parámetro que es de tipo booleano (verdadero o falso), si es verdadero se suprimen los mecanismos para los eventos de las teclas, si es falso se activan los mecanismos y se pueden detectar fácilmente las teclas que se han presionado. public class EjemploGameCanvas extends GameCanvas i mplements Runnable { public EjemploGameCanvas () {

Page 26: resumen.pdf

super(true); // código del constructor } } toda clase que lleve en su definición el “implements Runnable” debe obligatoriamente implementar el método run() este método es la clave de los subprocesos, public class EjemploGameCanvas extends GameCanvas i mplements Runnable { public EjemploGameCanvas () { super(true); // código del constructor } public void run() { //Código del subproceso } } El Método getGraphics() Por otro lado, la clase GameCanvas contiene varios métodos, uno de ellos es getGraphics(), este método es el primer paso para iniciar a dibujar en el GameCanvas, el método regresa un objeto tipo grafico con el que posteriormente se dibuja, la instrucción para usarlo es así: g = getGraphics(); queda entonces la clase así: public class EjemploGameCanvas extends GameCanvas i mplements Runnable { Graphics g; public EjemploGameCanvas () { super(true); // código del constructor g = getGraphics(); } public void run() { //Código para el subproceso } } Creación del Subproceso Otra vez regresamos a los subprocesos, no basta con escribir el “implements Runnable” y el método “run” se debe en verdad crear el subproceso, esto se hace creando un objeto de la clase Thread, como se crea el objeto, ya lo vimos, primero se declara y se crea usando la palabra new, esto incluso se puede escribir en una sola línea así: Thread subproceso = new Thread(this); Ya está creado el subproceso con la línea anterior pero mientras no se inicie jamás se va a ejecutar el método run, así que para iniciarlo basta con mandar llamar su método start así: subproceso.start(); queda entonces la clase así: public class EjemploGameCanvas extends GameCanvas i mplements Runnable { Graphics g; public EjemploGameCanvas () { super(true); // código del constructor g = getGraphics(); Thread subproceso = new Thread(this); subproceso.start(); } public void run() { //Código } Ahora si a Dibujar Listo tenemos todos los elementos para empezar a dibujar lo que queramos en la pantalla del móvil, usando de por medio el objeto “g” tal y como se hizo con la clase Canvas, esto ya se vio por lo que no entraré en detalles, el código siguiente coloca la pantalla del móvil en negro y escribe “hola Mundo usando GameCanvas”, en otro color: // pantalla en negro g.setColor(0x000000); g.fillRect(0, 0, getWidth(), getHeight()); // dibujo de las letras “hola mundo… g.setColor(0xff00FF); g.drawString("Hola mundo, con GameCanvas", 0, 60, G raphics.LEFT | Graphics.TOP); ¿Dónde va el código? En el método run() después de todo es el que se ejecuta al iniciar el subproceso, antes de ver donde, veamos otro método de la clase GameCanvas. El método flushGraphics(); Este método, también de la clase GameCanvas es usado para colocar realmente en la pantalla del móvil lo dibujado por el objeto “g”, el código anterior que pinta la pantalla de negro y dibuja el letrero está en la memoria o “buffer” y no se puede ver, hasta que se invoque el método flushGraphics(), al hacerlo se ve ahora si lo dibujado, este código va al final, despueés del método drawString, también va en el método run, queda finalmente el código así: sora: Mª Alejandra Tomás Fernández 5 de 5 public class EjemploGameCanvas extends GameCanvas i mplements Runnable { Graphics g; public EjemploGameCanvas () { super(true); // código del constructor g = getGraphics(); Thread subproceso = new Thread(this); subproceso.start(); } public void run() { // pantalla en negro g.setColor(0x000000); g.fillRect(0, 0, getWidth(), getHeight()); // dibujo de las letras “hola mundo… g.setColor(0xff00FF); g.drawString("Hola mundo, con GameCanvas", 0, 60, G raphics.LEFT | Graphics.TOP); flushGraphics(); } }

Ya sólo faltaría crear el MIDlet que llame a esta clase GameCanvas que se hace como siempre con el código:

………. EjemploGameCanvas canvas=new EjemploGameCanvas(); display.setCurrent(canvas); ……………………..

Page 27: resumen.pdf