Sesión 13

 

1. Vamos a realizar un ejercicio que nos permita practicar cómo dibujar en Java, y posteriormente realizar animaciones con esos dibujos.

  1. Antes de comenzar, lee la introducción al apartado 3.4 (Gráficos y animación), y los subapartados 3.4.1 (Gráficos en AWT), y 3.4.2 (Contexto gráfico: Graphics) entero, incluyendo sus subapartados, del tema 3 de teoría.
  2. Echa un vistazo a la clase Ej1.java que se proporciona en la plantilla de la sesión. Verás que es un subtipo de JFrame, de 300 de ancho por 300 de alto, y que tiene un GridLayout de 2 filas y 1 columna.

    Verás también que dentro de ese GridLayout coloca dos componentes. Uno de tipo MiPanel (una clase interna definida dentro de Ej1), y otro de tipo MiCanvas (también otra clase interna de Ej1). Observa que el primero es un subtipo de JPanel, y el segundo un subtipo de Canvas.
  3. Compila y ejecuta la clase para comprobar que, de momento, no hay errores. Aparecerá una ventana de 300 x 300 donde no se ve nada (están añadidos el canvas y el panel, pero al estar vacíos no se ve nada).
  4. Vamos a hacer que tanto en MiCanvas como en MiPanel se dibujen un rectángulo azul y un círculo verde. Para ello, vamos a cada clase y definimos dentro un método paint propio, que será el encargado de dibujar estos elementos:
    ...
    class MiPanel extends JPanel
    {
    	...
    	
    	public void paint(Graphics g)
    	{
    		g.setColor(Color.blue);
    		g.fillRect(5, 0, 100, 25);
    		g.setColor(Color.green);
    		g.fillOval(125, 0, 100, 50);
    	}
    }
    
    class MiCanvas extends Canvas
    {
    	...
    	public void paint(Graphics g)
    	{
    		g.setColor(Color.blue);
    		g.fillRect(5, 0, 100, 25);
    		g.setColor(Color.green);
    		g.fillOval(125, 0, 100, 50);
    	}
    }
    Observa que los dos (panel y canvas) dibujan las figuras en sus mismas coordenadas (relativas a cada uno), de forma que la apariencia en los dos es la misma.
  5. Compila y ejecuta ahora la aplicación. Quedaría algo como esto:

    Figura 1. Apariencia de la aplicación de dibujar. El panel superior es MiPanel, y el inferior es MiCanvas

  6. Vamos a introducir ahora algunas animaciones sobre estas figuras. Antes de seguir, lee entero el apartado 3.4 (Animaciones) del tema 3 de teoría.
  7. Vamos a mover todas las figuras desde una coordenada y = 0 hasta otra y = 100.
    1. Lo primero, definimos una variable global en la clase Ej1, que guarde dicha coordenada y:
      public class Ej1 extends JFrame
      {
      	MiPanel mp = new MiPanel();
      	MiCanvas mc = new MiCanvas();
      	int yObj = 0;
      	...
    2. Para hacer las animaciones, como se explica en el apartado de teoría, es importante hacerlas desde un hilo aparte, para no bloquear el programa principal. Así que definimos un hilo en nuestra clase principal, y hacemos que ésta implemente la interfaz Runnable:
      public class Ej1 extends JFrame implements Runnable
      {
      	MiPanel mp = new MiPanel();
      	MiCanvas mc = new MiCanvas();
      	int yObj = 0;
      	Thread t = new Thread(this);
      	...

      Al final del constructor, iniciamos el hilo:

      public Ej1()
      {
      	...
      	t.start();
      }

      Finalmente, definimos un método run en la clase Ej1, que haga las animaciones. Lo que va a hacer es incrementar la yObj de uno en uno, hasta 100, y repintar el panel y el canvas en cada iteración. Dormirá 100 ms entre cada iteración para permitir que el proceso principal (la ventana) siga su curso.

      public void run()
      {	
      	while (yObj < 100)
      	{
      		yObj++;
      		mp.repaint();
      		mc.repaint();
      		try
      		{
      			Thread.currentThread().sleep(100);
      		} catch (Exception ex) {}
      	}
      }

      Finalmente, nos queda modificar un poco los métodos paint de MiCanvas y MiPanel, para hacer que la coordenada Y donde se dibujan las figuras no sea fija, sino que sea la variable yObj:

      ...
      class MiPanel extends JPanel
      {
      	...
      	
      	public void paint(Graphics g)
      	{
      		g.setColor(Color.blue);
      		g.fillRect(5, yObj, 100, 25);
      		g.setColor(Color.green);
      		g.fillOval(125, yObj, 100, 50);
      	}
      }
      
      class MiCanvas extends Canvas
      {
      	...
      	public void paint(Graphics g)
      	{
      		g.setColor(Color.blue);
      		g.fillRect(5, yObj, 100, 25);
      		g.setColor(Color.green);
      		g.fillOval(125, yObj, 100, 50);
      	}
      }
    3. Prueba a compilar y ejecutar la clase... ¿Qué efecto no deseable observas en el panel superior (MiPanel)? ¿Y en el inferior (MiCanvas)?
  8. Vamos a corregir los dos efectos no deseables que ocurrían en el paso anterior.
  9. Compila y ejecuta la aplicación, para ver que funciona ya correctamente. ¿Por qué en el caso de MiPanel no ha sido necesario hacer el doble buffer, y sí lo hemos tenido que hacer en MiCanvas?

PARA ENTREGAR