Mostrando las entradas con la etiqueta curso java.. Mostrar todas las entradas
Mostrando las entradas con la etiqueta curso java.. Mostrar todas las entradas

martes, 30 de diciembre de 2014

TEMA #14: LECTURA DE DOCUMENTOS DE TEXTO (.TXT)

Este tema será corto y sólo comentaremos el código que permite leer un documento de texto (.txt), que son los documentos del bloc de notas de Windows. Este proceso lo hacemos utilizando tres estructuras de control: do/while, for, if/else. Veamos todo lo que debemos importar y el código que utilizaremos:

Imports
private InputStream is = getClass.getResourceAsStream(“dirección el documento”);
private InputStreamReader isr = newInputStreamReader(is, “UTF-8”);
private char[] buffer = new char[10];
private int nchars;
private StringBuffer sb = new StringBuffer();

Código De Lectura
Form form = new Form(“Texto”);

do{
      nchars = isr.read(buffer);
      for(int i=0; i<nchars; i++){
            if(buffer[i] == ´\n´){
                  sb.append(buffer[i]);
            }else{
                  sb.append(buffer[i]);
            }
      }
} while (nchars == buffer.lenght);

form.append(sb.toString());

Algo importante que debemos destacar es que al definir el InputStreamReader le debemos proporcionar el InputStream y el tipo de codificación del documento. El bloc de notas permite guardar texto en diferentes codificaciones: ANSI, Unicode, Unicode big endian y UTF-8; esto se elige cuando entremos en el menú archivo del bloc de notas y le demos a guardar como. Saldrá un cuadro de diálogo donde podemos elegir el nombre del archivo y la codificación.
 
El código que hemos visto nos va a permitir leer un documento de texto (.txt) y poder añadirlo a la pantalla, en este caso una Form. Este elemento de la Interfaz de Alto Nivel es la manera más sencilla de mostrar el texto en la pantalla. La Form se encarga de crear una barra lateral para el “scrolling” y se encarga de agregar saltos de línea cuando una palabra no entre en una línea.


Descarga la aplicación de ejemplo. Descargar App.
Descargar el código y los recursos utilizados en la aplicación. Descargar.

Ahora, existe otra forma de mostrar el texto en la pantalla y es a través de un lienzo de dibujo (Interfaz de Bajo Nivel). Lo que diferencia esta manera de mostrar el texto en pantalla es que nos debemos encargar de los saltos de línea y del “scrolling” del texto agregado, lo que hace más difícil el proceso. Con respecto a esta manera de mostrar el texto en pantalla, les dejo una aplicación de ejemplo y un código donde se muestra cómo hacerlo.


La ventaja que resulta de utilizar un lienzo de dibujo en lugar de una Form es que en el lienzo de dibujo podremos utilizar toda la pantalla para visualizar el texto, en cambio, si utilizamos una Form, el espacio se ve limitado por el título de la Form y la barra de comandos de la Form.
Si no quieres complicarte las cosas, puedes agregar el texto a una Form, pero cuando crees la Form, en lugar de colocarle un título le agregas la palabra null para que no se muestre la barra de título de la Form: Form form = new Form(null);. Veamos cómo se ve:


 
Esto es todo en este tema. Nos vemos en el próximo tema.

TEMA #13: THREAD

En este tema veremos la clase Thread y cómo usarla. La palabra Thread significa hilo; en el contexto de este curso (y de programación en general) lo vamos a definir como una tarea que puede realizarse simultáneamente con otra, y que nos va a permitir realizar procesos de manera simultánea. Podemos utilizar sólo un Thread dentro de nuestra aplicación/juego, o podemos utilizar varios simultáneamente.

¿Cómo Definir Un Thread?
Cuando trabajamos con una aplicación/juego podemos decidir si colocar un Thread “aislado” o crear una clase que implemente la interfaz Runnable. En este caso vamos a ver cómo usar un Thread “aislado”. El paquete que debemos importar a la hora de usar un Thread es java.lang.Thread;. Un Thread se define de la siguiente forma:

Definición
Notas
Thread th = new Thread(){
     public void run(){
           …
           try{
                 Thread.sleep(long milisecs);
           }catch(InterruptedException ie){}
     }
};
th.start();
Vemos la estructura del Thread... Dentro del método public void run(){...} debemos colocar las acciones que realizará el hilo.
Vemos que dentro debemos colocar también una línea de código que determinará cada cuanto tiempo trabajará el Thread y vemos que lanza un error el cual debemos capturar.
Por último iniciamos el Thread a través del método .start();.

Ejemplo: si tenemos un lienzo de dibujo y queremos que cada 5 segundos cambie de color, esto lo hacemos con Thread. Si queremos que una imagen se mueva de un lugar a otro continuamente, lo hacemos con Thread.

Como te habrás dado cuenta, en todas las aplicaciones de ejemplo la pantalla de presentación consiste en muchos círculos y un fondo que van cambiando poco a poco de color. Este efecto de cambio de color de poco a poco lo hacemos con Thread.


Redundancia de Thread
En mi experiencia con el uso de los Threads tuve un problema que me enseñó dos métodos de cómo evitar lo que yo llamo “redundancia de Thread”. Miremos el siguiente ejemplo gráfico con el cual explicaremos la redundancia de Thread:


Supongamos que estamos haciendo una aplicación que funcione como cronómetro y necesitamos que cada segundo se le sume 1 a la cuenta de los segundos y que se empiece a contar cuando se presione la tecla 1 del teclado de nuestro celular. Veamos el código de la imagen de acá arriba: el Thread que definimos se va a encargar de aumentar el valor de la cuenta (cuenta+=1;) y más abajo está cada cuánto tiempo se realizará la acción (Thread.sleep(1000);), que debe ser colocado en milisegundos. En este caso, cada 1 segundo (1000 milisegundos) se aumentará el valor de la variable cuenta en 1. Las últimas líneas determinan cuándo se iniciará el Thread, en este caso, cuando dentro de un lienzo de dibujo pulsemos la tecla 1 del teclado de nuestro celular.

Pero, ¿dónde está el problema?, ¿dónde ocurre la redundancia de Thread? Pues bien, dijimos que cuando pulsamos la tecla 1 del teclado de nuestro celular se inicia el Thread, ahora, si pulsamos nuevamente la tecla 1 cuando el Thread se está ejecutando se recibirá nuevamente la orden de iniciar el Thread. El efecto que causa la redundancia de Thread es que la velocidad del Thread se aumentará, deshaciendo así la coordinación del Thread. Esto no resulta útil porque en lugar de que se aumente el valor de la variable cuenta en 1 cada 1 segundo, se aumentará en 1 pero el tiempo será acortado (cada 0.5 segundos).

Descarga la aplicación de ejemplo donde se muestran los efectos de la redundancia de Thread. Descargar App.
Descarga el código y los recursos utilizados en esta aplicación. Descargar.



Métodos Para Evitar La Redundancia De Thread
Para evitar la redundancia de Thread me he dado cuenta de dos formas para evitarla, las llamaremos “Método de la llave” y “Método de confirmación”.

Método de la llave
Este método consiste en colocar una variable de tipo numérico (llave) que es la que va a determinar cuándo se inicia el Thread, y cuando se inicie el Thread, éste se encargará de cambiar el valor de la llave para que no se active nuevamente el Thread. Veamos el siguiente ejemplo gráfico:

En este ejemplo si pulsamos la tecla 1 del teclado de nuestro celular activará una llave que se encargará de activar el Thread. Una vez que el Thread se activa, el mismo Thread se encarga de desechar la llave para que cuando de pulse la tecla 1 nuevamente no ocurra la redundancia de Thread.

Ahora, ¿cómo creamos la llave y cómo la desechamos? Mencionamos anteriormente que la llave va a ser una variable de tipo int. Cuando creamos esta variable “creamos la llave”, cuando esta variable tenga un valor específico se activará el Thread (usamos la llave) y cuando el Thread se active se encargará de cambiar el valor de la variable (desechamos la llave).

Descarga un código donde se corrige el error de la aplicación del principio, utilizando este método. Descargar.
Descarga la aplicación. Descargar.

Método de confirmación
Este método consiste en utilizar la estructura de control if/else para confirmar si el Thread se encuentra ejecutándose o no, lo que nos permitirá activar el Thread, si no está activo, y en el caso de que esté activo, no hacer nada, evitando la redundancia de Thread. Veamos el siguiente ejemplo gráfico:

Vemos que para que se realice la acción primero se pasa por un filtro para confirmar que el Thread no se encuentre activo. Si no se encuentra activo se inicia (thr.start();), pero si ya se encuentra activo no se realiza ninguna acción.

Nota: para utilizar este método es indispensable que los Threads que utilicemos los coloquemos al principio y los definamos como un Thread vacío:

private Thread thr = new Thread();

Si no se hace esto no funcionará el método de confirmación.

Descarga un código donde se corrige el error de la aplicación del principio, utilizando este método. Descargar.
Descarga la aplicación. Descargar.

Por último te dejo la porción de código que corresponde a la pantalla inicial de las aplicaciones de ejemplo a lo largo del curso. Descargar.

TEMA #12: SONIDOS

En este tema veremos cómo agregar sonido a una aplicación/juego. Aprenderemos a cómo reproducir sonidos, a pausarlos y otras cosas. Observemos esta primera imagen:
A través de esta imagen lo que quiero explicar es que Manager es la clase principal en este tema y es la que va a permitir crear un Player, el cual va a permitir reproducir audio y video. La clase control, como vemos, es la que está dentro de Manager y Player, y va a permitir controlar los Players que creemos. El import que debemos hacer es: javax.microedition.media.*;


Tipos de Audio y Video
Los archivos de audio y de video tienen diferentes formatos y dependiendo del formato nuestro celular será capaz o no de reproducirlo. No nos detendremos en cada uno de estos formatos, sólo los mencionaremos.

Formatos De Audio
Clave
Formatos De Video
Clave
Wave audio files
“audio/x-wav”
3GP video files
“video/3gp”
AU audio files
“audio/basic”
MPEG4 video files
“video/mp4”
MP3 audio files
“audio/mpeg”
-
-
MIDI audio files
“audio/midi”
-
-
Tone Sequences
“audio/x-tone-seq”
-
-

Existen otros formatos de audio y de video, pero, en J2ME, estos son los importantes.
Es importante saber qué tipo de formato soporta tu celular para que evites usar un formato inadecuado a la hora de hacer aplicaciones/juegos para tu celular. Descarga esta aplicación que te dirá qué formatos de audio y video soporta tu celular. Descargar App.

Si alguna vez tienes problemas con el formato de un archivo de audio y quieres cambiarle el formato, te recomiendo el siguiente programa. Descargar.

Si tienes problemas con el formato de un archivo de video, te recomiendo el siguiente programa para cambiarle el formato. Descargar.


Fuente Del Sonido
El  archivo de sonido que se reproducirá en la aplicación/juego puede obtenerse de una dirección web o de la misma aplicación/juego. En lo particular, no he utilizado la primera opción. En este tema sólo vamos a trabajar con la segunda opción, para lo cual debemos conocer la clase InputStream que nos va a permitir comunicar la aplicación/juego con el archivo de audio (o video) guardado en la misma. Se define de manera sencilla:

InputStream inStream = getClass().getResourceAsStream(“ubicación del archivo”);

Vemos que esta vez no utilizamos la palabra “new”, y esto es una particularidad de esta clase cuando la usamos para localizar archivos guardados en la propia aplicación/juego. El único parámetro que debemos proporcionar es la ubicación del archivo y esto es similar a como lo hicimos al ubicar una imagen (ver tema correspondiente). También debemos recordar que el archivo debe ser copiado a la carpeta “src” del proyecto que estamos creando, para que la aplicación/juego pueda ubicarlo.


Player
El Player es el que se va a encargar de reproducir los archivos de audio o video. Es necesario mencionar que el Player puede estar en 5 estados: UNREALIZED, REALIZED, PREFETCHED, STARTED y CLOSED. Cuando creamos un Player está en el estado UNREALIZED. Cuando lo pasamos al estado REALIZED el reproductor realiza la comunicación necesaria para localizar los elementos que necesita para funcionar (tal como un archivo). Cuando de detiene el reproductor el Player pasa de un estado STARTED a un estado PREFETCHED.


Player de Audio
A través de la clase Manager podemos reproducir sonidos, desde sonidos sencillos hasta archivos de sonidos, por lo tanto hay tres formas de crear un sonido:

Sonido
Notas
Manager.playTone(...);
Reproduce un solo sonido.
Player p = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR)
Reproduce una secuencia de sonidos que determinemos.
Player p = Manager.createPlayer(InputStream iStream, String clave);
Reproduce un archivo de audio. Ya hablamos de InputStream. El parámetro clave depende del tipo de archivo (ver la primera tabla de este tema).

Nos concentraremos en la última de estas tres formas, que es la más importante.
Para crear un Player debemos definir primero el InputStream que utilizará y luego podemos definir el Player. Veamos un ejemplo:

InputStream inStream = getClass().getResourceAsStream(“/música.mp3”);

Player pl = Manager.createPlayer(inStream, “audio/mpeg”);
pl.start();

Luego que creemos el Player, para reproducirlo usamos el método .start();, como muestra el ejemplo.

Nota: al crear un Player ocurren dos errores que debemos atrapar, IOException y MediaException. Si queremos atrapar dos errores lo que debemos hacer es agregar otro catch para atrapar el segundo error, así:

InputStream inStream = getClass().getResourceAsStream(“/música.mp3”);

try{
    Player pl = Manager.createPlayer(inStream, “audio/mpeg”);
    pl.start();
}catch(IOException io){
}catch(MediaException me){}


Player de Video
Manager nos permite reproducir videos en nuestro celular, siempre y cuando lo soporte. Podemos definir este tipo de Player de la siguiente manera:

Player pl = Manager.createPlayer(InputStream iStream, String clave);

Pero esto no es todo lo que debemos hacer, sino que debemos tomar el control del video y colocarlo dentro de un elemento de tipo Form (no he probado colocarlo en un lienzo de dibujo...). Veamos un ejemplo completo:

try{
InputStream in = getClass.getResourceAsStream(“/mivideo.3gp”);
Player pl = Manager.createPlayer(in, “video/3gp”);

pl.realize();
GUIControl gc = (GUIControl)pl.getControl(“GUIControl”);
if(gc != null){
    Form form = new Form(“Mi Video”);
    form.append((Item)gc.initDisplayMode(GUIControl.USE_GUI_PRIMITIVE, null));
    display.setCurrent(form);
}

pl.start();

}catch(MediaException me){
}catch(IOException io){}

Un método importantes es .setDisplayFullscreen(boolean valor); que pertenece a VideoControl o GUIControl que permite expandir el tamaño del video hasta que llegue al tope del ancho o alto de la pantalla (true). Se hace de la siguiente forma:

GUIControl gc = (GUIControl)player.getControl(“GUIControl”);
gc.setDisplayFullscreen(true);

Descarga la aplicación de ejemplo de este tema. Descargar App.

Descarga el código y los recursos utilizados en la aplicación. Descargar.

TEMA #11: LA INTERFAZ DE BAJO NIVEL (GAMECANVAS) II: MANEJO DE TECLADO Y PANTALLA

Ya vimos en el tema anterior cómo dibujar en el lienzo (GameCanvas), a través del método public void paint(Graphics g){...}, ahora vamos a ver otros métodos que podemos utilizar en el lienzo de dibujo pero que no tienen que ver directamente con el dibujado en pantalla, sino que estos métodos nos van a permitir realizar acciones a través del teclado de nuestro celular o pantalla (celulares táctiles). 

Los métodos de los que hablaremos los podemos clasificar en 2 grupos:


Antes de continuar, descarga esta aplicación que te indicará qué métodos soporta tu celular. DescargarApp. Es importante debido a que algunos celulares no soportan keyRepeated, por mencionar un ejemplo.


TECLADO
Antes de comenzar con los métodos de teclado vamos a ver qué teclas podemos utilizar. El teclado está compuesto por botones alfanuméticos y además tiene botones direccionales y botones extras. Veamos un ejemplo gráfico donde se muestran los botones que podemos utilizar:



keyPressed
Se utiliza para realizar una acción al pulsar un botón del teclado de nuestro celular, cuando estamos trabajando dentro de un lienzo de dibujo (GameCanvas). Las acciones que coloquemos dentro de este método se van a llevar a cabo justo cuando se pulse un botón determinado.


keyReleased
Se utiliza para realizar una acción al soltar un botón que ha sido previamente pulsado, cuando estamos trabajando dentro de un lienzo de dibujo (GameCanvas). Las acciones que coloquemos dentro de este método se van a llevar a cabo justo cuando se suelte un botón determinado.


keyRepeated
Se utiliza para realizar una acción al mantener presionado un botón, cuando estamos trabajando dentro de un lienzo de dibujo (GameCanvas), y siempre que el celular soporte este método. Las acciones que coloquemos dentro de este método se van a llevar a cabo cuando se mantenga presionado un botón determinado.


¿Cómo Usarlos?
Para usar los métodos de teclado debemos colocarle nombre a la variable de tipo int, no necesariamente se tiene que llamar keycode, yo en lo particular siempre la llamo “k”.
Código
Notas
public void keyPressed(int k){
         if(k == KEY_NUM0){
              //Acciones a realizar
         }
         if(k == KEY_NUM1){
              //Acciones a realizar
         }
}
En este caso utilizamos keyPressed pero puede ser keyReleased o keyRepeated, es la misma estructura. Podemos ver que es similar a como definíamos una función particular para cada comando dentro de una Form. Las teclas que podemos utilizar son: KEY_NUM0,..., KEY_NUM9, KEY_STAR, KEY_POUND. Y las teclas de acción que podemos utilizar son: FIRE, GAME_A, GAME_B, GAME_C, GAME_D.

Descarga el código y los recursos de la aplicación para saber con más detalle cómo se usan los métodos de teclado. Descargar.
Descarga una aplicación de ejemplo en la que se utilizan los métodos de teclado. DescargarApp.


PANTALLA
En el caso de los celulares táctiles, cualquier punto dentro de la pantalla es válido, es por eso que los métodos para controlar la pantalla solicitan dos parámetros: una coordenada en el eje horizontal (x) y una coordenada en el eje vertical (y). La determinación de este punto en la pantalla es similar a como lo hicimos con el punto de referencia, un valor x y uno y.

pointerPressed
Se utiliza para realizar una acción al pulsar un punto determinado de la pantalla, cuando estamos trabajando dentro de un lienzo de dibujo (GameCanvas). Las acciones que coloquemos dentro de este método se van a llevar a cabo justo cuando se pulse un punto que determinemos de la pantalla del celular.


pointerReleased
Se utiliza para realizar una acción al dejar de pulsar un punto determinado de la pantalla, cuando estamos trabajando dentro de un lienzo de dibujo (GameCanvas). Las acciones que coloquemos dentro de este método se van a llevar a cabo justo cuando se deje de pulsar un punto que determinemos de la pantalla del celular.


pointerDragged
Se utiliza para realizar una acción al desplazar nuestro dedo desde un punto a otro de la pantalla, cuando estamos trabajando dentro de un lienzo de dibujo (GameCanvas). Las acciones que coloquemos dentro de este método se van a llevar a cabo cuando nuestro dedo se desplace desde el punto inicial que determinemos hasta el punto final que determinemos, en la pantalla.


¿Cómo Usarlos?
Para usar los métodos de pantalla debemos colocar nombre a las dos variables tipo int, yo particularmente las llamo igual “x” y “y”.
Código
Notas
public void pointerPressed(int x, int y){
         if(x == 5 && y == 5){
              //Acciones a realizar
         }
         if(x == 20 && y == 50){
              //Acciones a realizar
         }
}
En este caso utilizamos pointerPressed pero puede ser pointerReleased o pointerDragged, es la misma estructura. Debemos utilizar el operador “&&” para relacionar el valor del eje vertical (x) con el valor del eje vertical (y). Si no se coloca un valor de x y uno de y no funcionará.

Descarga el código y los recursos de la aplicación para saber con más detalle cómo se usan los métodos de pantalla. Descargar.
Descarga una aplicación de ejemplo en la que se utilizan los métodos de pantalla. DescargarApp.