Home UC3M
Home IT

Desarrollando UI con el API de bajo nivel

 OBJETIVOS


En la clase de hoy vamos a ver cómo se utiliza el API a bajo nivel que nos proporciona MIDP para realizar interfaces de usuario. Este API es el favorito de los desarrolladores de juegos porque permite tener control total sobre lo que dibujas en la pantalla, a nivel de pixel, y además puedes definir tus propios eventos de entrada. Lo que se gana en flexibilidad, se pierde en portabilidad ya que el resultado final dependerá del teléfono concreto en el que se implemente.
En una misma aplicación podrás utilizar los API de alto nivel y de bajo nivel (vistos en la clase pasada), pero no ambos simultaneamente.
El objetivo de la clase de hoy es que os familiariceis con este API, para realizar el tablero de juego de la práctica final.

 Canvas

La clase Canvas es una subclase de Displayable.

Cuando trabajamos a bajo nivel es importante saber las dimensiones del display, ya que éstas varían de dispositivo a dispositivo y por lo tanto, nuestras apliaciones no deben de asumir un determinado tamaño por defecto. La clase Canvas proporciona los métodos getHeight() y getWidth() para obtener el tamaño del display.

La clase Canvas proporciona un método paint(Graphics g) y varios métodos para la gestión de eventos a bajo nivel que las aplicaciones pueden sobreescribir. La clase Canvas es abstracta y por lo tanto una aplicación debe obligatoriamente extender la clase Canvas para poder utilizarla. La clase que extiende la clase Canvas debe de proporcionar obligatoriamente una implementación del método paint()

A continuación se muestra el código de un MIDlet que extiende la clase Canvas (EjemploCanvas.java):

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


public class EjemploCanvas extends MIDlet {

    private Display  display;
    private MyCanvas canvas;
   
    public EjemploCanvas(){
        display = Display.getDisplay( this );
        canvas  = new MyCanvas();
    }
   
    protected void startApp(){
        display.setCurrent(canvas);
    }
   
    protected void pauseApp(){
    }
  
    protected void destroyApp( boolean unconditional ){
    }
   
    public void exit(){
        destroyApp( true );
        notifyDestroyed();
    }

    // extiende la clase Canvas
    public class MyCanvas extends Canvas {
    
       public MyCanvas(){
       } 
 
       protected void paint(Graphics g){
         g.setColor( 255, 255, 255 );
         g.fillRect( 0, 0, getWidth(), getHeight() );
         g.setColor( 0, 0, 0 );
         g.drawString( "¡Hola!", getWidth()/2, 0, g.TOP | g.HCENTER );
       }
    }
}


El MIDlet anterior funciona, pero si os fijais para finalizar su ejecución no espera ninguna interacción del usuario. Para ello, vamos a ver ahora como se gestionan los eventos con el API de bajo nivel.

La clase Canvas proporciona algunos métodos para gestionar eventos, que las aplicaciones pueden sobreescribir, estos métodos son:


Por ejemplo, si sobreescribimos el método keyPressed, en MyCanvas:
protected void keyPressed( int keyCode ){
  exit();
}


El resultado será que cuando se presione cualquier tecla, finalizará la aplicación.

Del mismo modo que en el API a alto nivel, se puede definir Commands, que se pueden asociar a un objeto de un clase que extiende la clase Canvas, utilizando el método addCommand.

 Graphics



La clase Graphics es similar a la clase java.awt.Graphics de J2SE, y proporciona métodos para geometría en dos dimensiones. Se definen métodos para dibujar texto, imágenes y líneas, y para dibujar y rellenar rectángulos y arcos, enumero a continuación alguno de ellos:


Si os fijais en los ejemplos anteriores, el método paint de la clase Canvas, acepta como único parámetro un objeto de la clase Graphics.

La clase Graphics también nos da soporte para colores a través de varios métodos:



A continuación, se incluye un MIDlet que dibuja dos líneas (LineTest.java)


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

public class LineTest extends MIDlet {
    private Display display;

    public LineTest() {
        display=Display.getDisplay(this);
    }

    public void startApp() throws MIDletStateChangeException {
        display.setCurrent(new LineTestCanvas());
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }

    class LineTestCanvas extends Canvas {
        public void paint(Graphics g) {
            // Tamaño del área de dibujo
            int width=this.getWidth();
            int height=this.getHeight();

            // Fondo de la pantalla blanco
            g.setColor(0xFFFFFF);
            g.fillRect(0,0,width,height);

            // Líneas en negro
            g.setColor(0x000000);
            // Dibujamos dos líneas (ejes)
            g.drawLine(0,height,0,0);
            g.drawLine(0,height-1,width,height-1);
        }
    }
}


Como ejercicio y tomando como base el código de los ejemplos anteriores, realizad el tablero del juego de los barcos.

RETO: ¿Os atreveis a que el tablero sea mejor, por ejemplo, que los barcos, las bombas y el agua sean imágenes?

 ENLACES


API de MIDP/CLDC




inicio | tablón| contacta