applet03+ (1)

58
Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets Capitulo 3 ( Applets ) Las versiones de Java proporcionan una serie de facilidades para generar figuras gráficas. Java2 tiene una gran riqueza en clases gráficas, cuyo poder de realizar operaciones de dibujado o pintado, así como la generación de una variedad de figuras geométricas con un amplio rango de paleta de colores, incorporando texto, imágenes, video y sonido, es decir, Java permite incorporar multimedios en general. Ahora veremos una selección de estas herramientas. No olvide que lo que se verá son solamente pequeños ejemplos de las capacidades gráficas de Java2, de Ud. depende, poder incrementar sus experiencias en el tema Applets. Además considerar que este mismo tema puede ser abordado a través de aplicaciones, pues los Applets tienen limitaciones, como se muestrará en Capítulo 7. En general, existen 2 maneras de ejecutar programas de Java: como applets, y como aplicaciones. Todos los programas como aplicaciones, son ejecutados por el sistema de Java (SDK), y ellos se ejecutan bajo el mando de un método principal. Un applet en cambio es ejecutado por un browser o visualizadores tales como Netscape u otros, el que es incrustado en una página HTML. Nosotros nos dedicaremos en este segmento a trabajar cono los Applets, las aplicaciones las dejaremos para los próximos capítulos. Si una aplicación va a generar gráficos, tendrá que usar una ventana en donde pueda desplegar imágenes de alta resolución. Una ventana DOS es inadecuada para esto, por tal motivo se verá cómo crear una ventana conveniente para desplegar gráficos. 3.1 Applets Area de Computación , Universidad de La Serena 1

Upload: joseph-heras

Post on 25-Oct-2015

9 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Capitulo 3 ( Applets )

Las versiones de Java proporcionan una serie de facilidades para generar figuras gráficas. Java2 tiene una gran riqueza en clases gráficas, cuyo poder de realizar operaciones de dibujado o pintado, así como la generación de una variedad de figuras geométricas con un amplio rango de paleta de colores, incorporando texto, imágenes, video y sonido, es decir, Java permite incorporar multimedios en general. Ahora veremos una selección de estas herramientas. No olvide que lo que se verá son solamente pequeños ejemplos de las capacidades gráficas de Java2, de Ud. depende, poder incrementar sus experiencias en el tema Applets. Además considerar que este mismo tema puede ser abordado a través de aplicaciones, pues los Applets tienen limitaciones, como se muestrará en Capítulo 7.

En general, existen 2 maneras de ejecutar programas de Java: como applets, y como aplicaciones.

Todos los programas como aplicaciones, son ejecutados por el sistema de Java (SDK), y ellos se ejecutan bajo el mando de un método principal. Un applet en cambio es ejecutado por un browser o visualizadores tales como Netscape u otros, el que es incrustado en una página HTML. Nosotros nos dedicaremos en este segmento a trabajar cono los Applets, las aplicaciones las dejaremos para los próximos capítulos. Si una aplicación va a generar gráficos, tendrá que usar una ventana en donde pueda desplegar imágenes de alta resolución. Una ventana DOS es inadecuada para esto, por tal motivo se verá cómo crear una ventana conveniente para desplegar gráficos. 3.1 Applets Esta sección examina programas de Java applets, junto a los cuales se analizan: Extensión de la clase Applet, Objetos Graphics, compilar y ejecutar los Applets, Páginas Web y HTML, los métodos drawString(), setBackground(), setColor(), drawOval(), drawRect(), drawLine() y Colores.

Un applet puede desplegar gráficos, sin grandes dificultades. Cuando un browser pone una página Web en su pantalla, y esa página Web contiene un enlace a un applet, entonces los browser pondrán un área de despliegue a disposición de la página Web de manera que los applet puedan usarse para desplegar cualquier tipo de información. Para Java esto no es una dificultad pues contiene su propio intérprete de Java , llamada Java Máquina Virtual(JVM).Los primeros pasos que nosotros tenemos que hacer para desplegar gráficos son: 1. escribir un applet que despliega los gráficos, y compílarlo.2. escribir una página Web que contiene un enlace al applet compilado.3. tener Netscape o Internet Explorador de versiones apropiadas (4.0 y 4.1 resp.) que

incluyen un intérprete de Java, y así puedan desplegar la página.

Area de Computación , Universidad de La Serena1

Page 2: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Desgraciadamente no siempre la versión del Browser será apropiada para ejecutar los applets, ¡los browsers de hoy pueden ejecutar versiones antiguas de Java, por ejemplo JDK1.1!, pero existen soluciones a este problema.

Solución 1. Conseguir un ' plug-in ' para el browser que le permita ejecutar Java 2. Estos ‘plug-in’ existen y Sun Microsystems pone uno a disposición. TextPad es uno de ellos ! Solución 2. Usar appletviewer que es un programa que es parte de la distribución SDK, el cuál aceptará una página Web y ejecutará cualquier applets que contenga. El appletviewer se proporciona para ayudar a los programadores a testear los applets, pero también da una manera simple para ver programas gráficos que son justamente lo que nosotros queremos hacer. La forma de trabajar será, cuando queramos crear algunos gráficos escribiremos un applet que dibuja o pinta en el área de despliegue, y además escribiremos una página Web que simplemente consiste en un enlace con el applet compilado. Entonces usaremos appletviewer para procesar la página Web. Pero en TextPad bien sabe que no es así pues lo genera en forma automática. El único inconveniente a solución 2 es que, usando appletviewer no podemos ver nada de la página Web aparte del applets que Ud. genero. No cubriremos la etapa de cómo escribir páginas Web en este curso, pero si Ud. está interesado, seguramente podrá encontrar en la red mucho material sobre el particular. Todo lo que usted necesita saber de HTML para este curso es que una página Web consiste en un archivo de texto que usa notación de HTML. La única página Web que debería por ahora manejar es:

<APPLET CODE = "Programa.class" WIDTH=300 HEIGHT=300> </APPLET>

Este ejemplo contiene un enlace a un archivo llamado Programa.class. Este archivo contendrá un applet de Java compilado. Este ejemplo también contiene el tamaño del área del despliegue que mantendrá el applet para desplegarse. En este caso la anchura y la altura del área son ambos 300 pixeles.

3.2 Ciclo de Vida de un Applet

Al ejecutar un applet varios eventos ocurren automáticamente cuando se inicia y luego para cuando el usuario decide terminar el programa o navegar hacia otra página. Estos eventos son controlados mediante métodos especiales dentro del applet, estos son los efectos en resumen.

El browser lee la página HTML y encuentra cualquier <APPLET> tags.El browser analiza el <APPLET> tag para encontrar el CODE y posibles atributos CODEBASE.

Area de Computación , Universidad de La Serena2

Page 3: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

El browser downloads el archivo .class para el applet desde el URL encontrado en la última etapa.El browser convierte los bytes downloaded en clases Java, que son objetos de java.lang.Class.El browser instancia el applet class para formar un objeto applet. Esto requiere que el applet tenga un constructor sin argumentos.El browser llama al método applet's init().El browser llama al método applet's start().Mientras el applet esta ejecutandose, el browser pasa los eventos al applet, ya sea pulsar el mouse, presionar una tecla, etc., el método applet's handleEvent(). Actualiza los eventos usados para llamar al applet si necesita repintarse asi mismo.El browser llama al método applet's stop().El browser llama al método applet's destroy().

Con algún detalle, se puede insistir en que cuando se entra por primera vez a la página web que contiene el applet, Java llama al método opcional init (inicialización) del applet, dentro del cual éste realiza sus operaciones de inicialización que se ejecutan una sola vez y que pueden incluir la creación e inicialización de objetos, la transportación de valores de parámetros del archivo de HTML, así como otras operaciones que el applet debe realizar solamente una vez.

Después de llamar al método init, Java llama al método start (arranque). (En realidad, Java llama al método start cada vez que el usuario regresa a la página del applet después de visitar otra.) La diferencia clave entre el método init y el método start es que Java llama a init sólo una vez durante la vida del applet; en cambio, puede llamar al método start varias veces, según el usuario navegue dentro y fuera de la página.

Desde luego, si hay un método start debe haber un método stop (parada). Cada vez que el usuario sale de la página del applet, Java llama al método stop. Dentro del método stop, por ejemplo, es posible detener la música que estaba reproduciéndose de fondo mientras se ejecutaba el applet. De esta forma, la música no sonará mientras el usuario navega por otros sitios.

Mientras se ejecuta el applet pueden ocurrir muchas interacciones con el usuario y eventos relacionados. Por ejemplo, el usuario puede redimensionar, mover o cubrir la ventana con otra. Se verá más adelante, que es necesario escribir métodos que respondan a los eventos generados por el usuario, tales como redimensionar ventanas, clics del ratón y selecciones de menús. En este punto de su ciclo de vida, el applet está en plena ejecución.Finalmente, cuando el usuario decide terminar el applet, Java llama al método destroy (destruir) para liberar recursos o limpiar los elementos que el applet haya asignado durante su acción. Conforme examine los applets de este libro, notará que se usan intensamente estos métodos.

Area de Computación , Universidad de La Serena3

Page 4: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

En Java, el applet que imprime “Hola DAA!”, en un navegador de Internet es bastante sencillo, pero al describirlo en términos de sus clases podrá ver que se tornan un tanto confuso, como podrá apreciarlo luego. En efecto,

Ejemplo 1

import java.awt.Graphics;public class HolaDAA extends java.applet.Applet { public void paint (Graphics g) { g.drawString(“Hola DAA!”, 10, 10 ); }}

Comentarios:

import java.awt.Graphics;hace que la clase Graphics esté disponible directamente para el código que sigue, el prefijo java.awt especifica el paquete Java en el cual se encuentra la clase Graphics.

public class HolaDAA extends java.applet.Applet {introduce una nueva clase llamada HolaDAA y especifica que es una subclase Applet, la cual se encuentra en el paquete java.applet.

public void paint (Graphics g) { g.drawString(“Hola DAA!”, 10, 10 );}declara una operación llamada paint, cuya implementación invoca a otra operación llamadadrawString, responsable de imprimir la cadena de caracteres “Hola DAA!”, en las coordenadas indicadas dentro del applet. Al estilo habitual orientado a objetos, drawString es una operación sobre un parámetrop g, cuyo tipo es la clase Graphics.

3.3 Jerarquía de Clases

Convengamos que esta forma de descripción captura los aspectos básicos de la aplicación “Hola DAA!”, pero deja afuera varias cosas. Por ejemplo, las clases Applet y Graphics intervienen y cada una se utiliza en forma diferente.

En primer término, la clase Applet se utiliza como padre de HolaDAA, y la clase Graphics se usa en la signatura e implementación de una de sus operaciones, paint.Sin embargo lo más importante radica en el marco bajo el cual se construyo HolaDAA.

Ahora si se estudian las bibliotecas de Java para Applet y Graphics, se descubrirá que ambas clases son parte de una jerarquía mayor, siguiendo solamente la pista de las clases que Applet extiende e implementa, se puede generar otro diagrama de clases, tal como lo muestra el siguiente diagrama.

Area de Computación , Universidad de La Serena4

Page 5: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

ImageObserver

La figura deja claro que HolaDAA es sólo una clase hoja(no tiene subclases) de una jerarquía mayor de clases. HolaDAA es hija de Applet; Applet es hija de Panel; Panel es hija de Container; Container es hija de Component y Component es hija de Object, la cual es la clase padre de todas las clases en Java. La relación entre ImageObserver y Component es un poco diferente, y el diagrama de clases refleja esta diferencia.

En la biblioteca Java, ImageObserver es una interface, lo cual entre otras cosas, significa que no tierne implementación y que requiere que otras clases la implementen. Como puede ver Hola DAA colabora directamente solamente con dos clases (Applet y Graphics), y estas dos clases no son sino una pequeña parte de una biblioteca mayor de clases Java predefinidas.

Para gestionar esta gran colección, Java organiza sus interfaces y clases en diferentes paquetes. El paquete raíz en el entorno Java se llama, como era de esperar, java. Dentro de él se encuentran varios paquetes que contienen otros paquetes, interfaces y clases. Object se encuentra en el paquete lang y por ello su nombre completo, java.lang.Object. Análogamente para Panel, Container, y Component que están en awt; la clase Applet se encuentra en applet. La interfaz ImageObserver esta en el paquete image, la que se encuentra en awt, de allí que su nombre completo sea java.awt.image.ImageObserver.

Lo más dificil para dominar una biblioteca tan rica como la de Java es aprender cómo colaboran sus partes. Por ejemplo, ¿Cómo llega a invocarse la operación o método paint de HolaDAA?, ¿Qué operaciones hay que utilizar si se desea cambiar el comportamiento de este applet, para conseguir por ejemplo, que imprima la cadena de caracteres en otro color, o con algún determinado color de fondo?. Esta y otras situaciones serán abordadas, sin embargo no piense que con un semestre de Java podrá entenderlo todo, pero si le aseguro que cursando el segundo curso de java podrá tener la dinámica de saber donde están o como se usan las clases o que métodos implemetan tal o cual interface.

Area de Computación , Universidad de La Serena5

HolaDAA

Applet

Panel

Container

Component

Object

Page 6: Applet03+ (1)

java.lang.Object

<<interface>>java.awt.image.ImageObserver

«interface»java.awt.Accessible

{abstract}java.awt.Component

java.awt.Checkbox java.awt.Button java.awt.Container

java.awt.Panel java.awt.Windows java.awt.MenuContainer

java.applet.Applet java.awt.Dialog java.awt.Frame

java.awt.FileDialog

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

A través de la siguiente figura podrá visualizar en que contexto se encuentra dentro del mapa de clases, en particular de java.awt.

Panel: simple clase Container. Ella pone lugar a disposición para disponer componentes arbitrarios.

Container: Container generico de Abstract Window Toolkit (AWT).

Component : Objeto que sobre una representación gráfica se pone a disposición, la que puede ser mostrada en pantalla y ofrece la posibilidad de interactuar con el usuario. Ejemplo: Button, Check Boxen y Scrollbars, entre otros.

3.4 Ambito de Aplicación de los Applet

Area de Computación , Universidad de La Serena6

<<interface>>java.awt.Accessible

Page 7: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

StringCuando Ud. define un applet, esta definiendo un object que será usado por otro programa, el web browser. Los objetos applet en web proporcionan servicios (métodos) al browser cuando el browser los ejecuta. Un objeto applet tiene muchas variables y métodos. Muchos de ellos vienen en forma automática con la distribución en Applet desde JDK. Las herramientas están en java.applet.Applet. Otro camino es importar java.awt.*. Este contiene muchas clases que son usualmente utilizads para windows y graphics. Aquí está el código para un applet pequeño, el nombre de la clase es Hola.

Ejemplo 2

import java.applet.Applet;import java.awt.*;

public class Hola extends Applet{ public void paint ( Graphics gr ) { /*que sentido tiene gr ? ...El parametro gr es una referencia a un objeto de tipo Graphics*/ setBackground( Color.pink );/* setear el background del area de la antalla que será pintada de pink. (Algunos browser no cambian el color dependiendo de la versión, y de la tarjeta de video que Ud. tenga.) */ gr.drawString("Hola amigos de los Applet", 25, 30); gr.drawString("Es un placer,", 25, 50); gr.drawString("continuar con Applets", 25, 70 ); gr.drawString("en Java2." ,25, 90); gr.drawString("--- E. Jeltsch" ,50, 130); }}

Area de Computación , Universidad de La Serena7

Page 8: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

La definición de Applet que el programa importa proporciona un “framework” para construir sus applet, a lo cual deberá extender la clase Applet:

Cuando Ud. extiende una clase, estará haciendo una nueva clase sobre una clase. En este ejemplo, estamos definiendo una nueva clase llamada Hola. La nueva clase tendrá todo lo que la clase Applet tiene (herencia.) La clase Applet tiene un método paint, pero este hace lo mínimo. El web browser llama al método paint cuando este necesita “pintar” alguna sección de la pantalla devuelta por el applet. El applets que Ud. escribe tendrá su propio método paint.

El color background del applet es el color del área dibujada. Esto es seteado a través de un color predefinido. Para ordenar a conectar su applet al area particular de la pantalla que sera “painted”, el web browser debe pasar su método paint por referencia a un objeto Graphics . El objeto Graphics es a menudo llamado programa “pintador”, entonces la declaración:

gr.drawString("Hola amigos de los applets", 25, 30);

llama al método drawString del objeto Graphics referenciado por la variable gr, imprimiendo un String en la localidad dada por los últimos dos parámetros. En general, los parámetros son

drawString( String str, int x, int y)str ---el String para pintar sobre paerte del applet de windows. x --- la distancia horizontal en pixeles desde la esquina superior izquierda.y --- la distancia vertical en pixeles desde la esquina superior izquierda.

Los parametros x e y indican en donde posicionar el String en el area del applet, considerando que (0,0) es la esquina superior izquierda del applet y no sobre la pantalla completa, incrementando los valores de y se mueve el área hacia abajo. La distancia es medida en pixeles. Un pixel es uno de los puntos más pequeños en el contexto de la imagen digital. El tamaño actual del pixel depende de el tamaño del monitor y el seteo de la tarjeta de video. Por ejemplo, lo siguiente dice que el String parte del 25 pixel hacia abajo desde el tope, y 30 pixeles desde la izquierda.

gr.drawString("Hola amigos de los applet",25,30);

El propio applet es una clase de Java, comportándose de la misma manera a las clases y conceptos de la POO vista antes. Es así como esta compuesto de campos, métodos y constructores. Difiere de las clases que hemos visto previamente en un aspecto importante. Contiene un método que maneja la ventana en el sentido que mantiene las ventanas en la pantalla y asegura que ellas se abran propiamente cuando el usuario las quiera, y desaparezcan para cuando el usuario cierra o las minimiza. Uno de los métodos applet que manejan la ventana se llama paint(). El window manager como se le llama, llamará a este método para que el área de despliegue aparezca en la pantalla la primera vez. También, usará el método para refrescar el área de despliegue del applet, llamado repaint().

Area de Computación , Universidad de La Serena8

Page 9: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

La tarea del método paint() es dar los volúmenes del área de despliegue (es decir dibuje líneas, o áreas de la pintura, o escriba texto). Vamos a escribir un método de la pintura que dará una forma simple, un triángulo. Para hacer esto, hacemos uso de un objeto Graphics2D. Esto es parecido al objeto System.out para cuando enviábamos cadenas de caracteres a la pantalla de la consola. Pero el objeto Graphics2D que usaremos se conecta al área de despliegue de alta resolución del applet, no a una consola DOS, y es mucho más versátil.

Por ejemplo, ya hemos visto drawString() que puede usarse para desplegar texto, otro método llamado draw dibujará una forma como un rectángulo o un círculo, y otro método llamado drawImage() para desplegar imágenes completas como fotografías. También, un objeto Graphics2D tiene métodos para pintar las formas y textos. Suponga que g2 es un objeto Graphics2D conectado a nuestra área desplegada por el applet, y suponga linea1 es una línea. Entonces la siguiente declaración despliega la línea sobre la pantalla.

g2.draw(linea1);

despliegará linea1 en el área dispuesta para esto.Existen varios tipos de figuras geométricas que pueden ser dibujadas y pintadas usando objeto Graphics2D. Usaremos en principio 3 tipos:

Líneas, Rectángulos y Elipses (incluyendo círculos). Cada uno es un objeto Java, por ejemplo, una línea es un objeto de tipo Line2D.Double. La palabra Double indica que los datos de la línea están almacenados usando número 64-bits floating-point. (pudiendo usar otro tipo de declaración por ejemplo, Line2D.Float en vez de la anterior.) Para crear una línea Ud. debe especificar las coordenadas. Posición en el área de despliegue son las coordenadas x e y. Se visualizan así

(0,0) x

yArea Display

Area de Computación , Universidad de La Serena9

Page 10: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Las coordenadas son medidas en pixeles. Así por ejemplo, un área 300300 se extenderá por un tercio de la pantalla aproximadamente. Para crear un objeto línea usamos el constructor Line2D.Double que tiene las coordenadas del punto final de la línea como parámetros,

Line2D.Double(x0,y0,x1,y1)

Crea un objeto que representa la línea desde (x0,y0) a (x1,y1). (Los valores x0, yo, x1 e y1 son valores double. Si Ud. proporciona coordenadas integer, Java las convertirá a double.)

Por ejemplo, supongamos que queremos al objeto g2 de Graphics2D dibujar el siguiente triángulo sobre la pantalla.

(150,100)

(100,210) (200,210)

Entonces podemos usar la siguiente declaración. Primeramente el objeto que representa el lado derecho del triángulo es asignado y creado en line1, y luego dibujamos usando el método draw. El mismo proceso se realiza para las otras 2 líneas.

Line2D.Double line1 = new Line2D.Double(150,100,200,210);g2.draw(line1);

Line2D.Double line2 = new Line2D.Double(200,210,100,210);g2.draw(line2);

Line2D.Double line3 = new Line2D.Double(100,210,150,100);g2.draw(line3);

Suponga que queremos escribir un applet que dibuje solamente este triángulo en la pantalla. Entonces podemos escribir un método para pintar que contenga estas seis declaraciones. ¿Pero cómo creamos nosotros el objeto g2 de Graphics2D para conectarlo al área de despliegue del applet? La respuesta es que nosotros no lo hacemos, sino que la ventana lo creará, pasándolo al método paint() como un parámetro. Applets han estado usando métodos paint() de sus inicios, mucho antes que Java 2 introdujese los objetos Graphics2D. En el pasado, un método paint() tenía un parámetro que era un

Area de Computación , Universidad de La Serena10

Page 11: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

objeto Graphics, hoy es similar Java todavía espera que el método paint() de un applet tenga un objeto Graphics como un parámetro, y ése es lo que nosotros debemos especificar siempre que nosotros escribamos el título de un método paint(). Por ejemplo,

public void paint(Graphics g)

En todo caso el compilador estará bastante contento si encuentra que un objeto Graphics2D va a ser pasado como el parámetro cuando el windows manager llame al método. Esto es porque reconocerá un objeto Graphics2D como un caso especial de un objeto Graphics. Sin embargo, el compilador no debería estar contento si nosotros empezamos tratando g como un objeto Graphics2D, a menos que le digamos que éste es definitivamente el caso. Usted puede hacer esto por medio de la declaración

Graphics2D g2 = (Graphics2D) g;

Esto dice: crea una variable g2, de tipo Graphics2D y asigna el objeto g el cual es un objeto de Graphics2D a la variable g2. El cast (Graphics2D) le asegura al compilador que el parámetro es realmente un objeto Graphics2D. En el resto de los métodos el objeto puede ser referido a g2, y tratado como objeto Graphics2D. En resumen a través de esta declaración el objeto g2 fue producido de una conversión por “cast”, en definitiva todas las operaciones gráficas de Java2D deben ser llamadas en un objeto Graphics2D, que es parte del paquete java.awt.Aquí esta el programa completo que dibujará el triángulo, notar que hay sólo una clase requerida. Las clases heredan las clases de applet. Las primeras tres líneas le dicen al compilador a que secciones de la biblioteca de Java debe remitirse.

Ejemplo 3

import java.applet.*;import java.awt.*;import java.awt.geom.*;

/* Applet que despliega un triángulo. */public class Triangulo extends Applet

{ public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; Line2D.Double line1 = new Line2D.Double(150,100,200,210); g2.draw(line1);

Line2D.Double line2 = new Line2D.Double(200,210,100,210); g2.draw(line2); Line2D.Double line3 = new Line2D.Double(100,210,150,100); g2.draw(line3);

Area de Computación , Universidad de La Serena11

Page 12: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

}}

Notar que un conjunto más reducido de declaraciones se generan si evitamos introducir las variables line1, etc. En vez de eso podemos escribir

Line2D.Double line1 = new Line2D.Double(150,100,200,210);g2.draw(line1); porg2.draw(new Line2D.Double(150,100,200,210));

ambas versiones son correctas.

Para ejecutar este programa, se debe considerar el siguiente archivo de texto (que usa notación HTML). Conteniendo vitales enlaces al archivo que contiene el archivo compilado llamado Triangulo.class.

<APPLET CODE="Triangulo.class" WIDTH=300 HEIGHT=300></APPLET>

Suponga que si al archivo le llamo Triangulo.html , luego cuando ejecute el comando >appletviewer Triangulo.html obtendrá la figura que se muestra a continuación.

Recuerde que el triángulo aparece porque el windows manager llama al método paint.

Area de Computación , Universidad de La Serena12

Page 13: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

La librería Java consiste de un número de packages. Ud. pudo ver en el programa anterior la línea, import java.applet.*;llama a compilar los “package” en java.applet. La llama al compilador a esperar cualquier clase del paquete. En este caso solo usamos la clase Applet. Si no quisiéramos importar la clase java.applet, deberíamos haber usado el nombre completo java.applet.Applet en vez de Applet. El paquete java.awt contiene muchas clases gráficas, en este ejemplo mostramos las clases Graphics y Graphics2D.El paquete java.awt.geom proporciona figuras geométricas tal como el objeto Line2D.Double.

Rectángulos y ElipsesLas nuevas librerías de Java incluyen varias otras formas geométricas. Una de estas es el rectángulo, dado por la clase Rectangle2D.Double. Un rectángulo puede ser construido usando el constructor.

Rectangle2D.Double(x,y,w,h)

Crea un objeto que representa un rectángulo con lados horizontal y vertical. La esquina esta situada en la parte superior izquierda y tiene coordenadas (x,y), ancho w, altura h.

(x,y)

h

w

Una figura similar es la elipse, dada por la clase Ellipse2D.Double. Puede ser creada por el constructor

Ellipse2D.Double(x,y,w,h),

La posición y forma de la elipse esta descrita por los parámetros x, y, w y h. Especificando el rectángulo que contiene la elipse. Los parámetros son los mismos.

(x,y)

h

w

Area de Computación , Universidad de La Serena13

Page 14: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

No existe el objeto Circulo, sin embargo puede ser hecho creando una elipse cuyo ancho sea igual a la altura. Si el centro de un circulo es (xc,yc) y radio r, entonces su equivalente a la elipse contenida en el rectángulo cuya esquina superior izquierda es (xcr, ycr), y ancho 2r y altura 2r.

(xcr, ycr)

r

2r (xc,yc)

2rEn los ejemplos que vienen usaremos líneas, rectángulos y elipses para construir un dibujo didáctico que nos mostrara las distintas aplicaciones. Asumiremos que el área de despliegue es 300300.

(0,0)

(50,100) 120 (170,130)

80 8020 50

(90,180) (210,180)

Area de Computación , Universidad de La Serena14

Page 15: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

En el applet que genera este dibujo, se han considerado 2 rectángulos, 2 círculos para las ruedas y la línea para el piso que soporta al autoEjemplo 4

import java.applet.*;import java.awt.*;import java.awt.geom.*;public class DrawCarro extends Applet{ public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; Rectangle2D.Double tras = new Rectangle2D.Double(50,100,120,80); g2.draw(tras); Rectangle2D.Double delan = new Rectangle2D.Double(170,130,80,50); g2.draw(delan); Ellipse2D.Double ruedaTras = new Ellipse2D.Double(70,160,40,40); g2.draw(ruedaTras); Ellipse2D.Double ruedaDel = new Ellipse2D.Double(190,160,40,40); g2.draw(ruedaDel); Line2D.Double baseLine = new Line2D.Double(0,200,300,200); g2.draw(baseLine); }}

Esta es la imagen que se genera para DrawCarro.

Area de Computación , Universidad de La Serena15

Page 16: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Introduciendo ColorComo vemos los objetos Graphics2D dibujan en blanco, pero Ud. puede cambiar el color a su gusto. Un Graphics2D tiene métodos setColor() que pueden ser usados para cambiar el color a través de parámetros específicos. Colores en Java están representados por objetos de tipo Color. La clase Color contiene constantes que representan colores estandares. Por ejemplo, la constante Color.red representa el color rojo. Así si Ud. quiere que el objeto g2 de Graphics2D parta pintando en rojo deberá setearlo, es decir insertar la declaración,

g2.setColor(Color.red);

Los objetos Color pueden representar más colores que los usuales, pues existe la posibilidad de combinar los 3 colores básicos y obtener los matices que Ud. desee. Java hace considerable uso del sistema red-green-blue (RGB) para definir colores. La clase Color tiene un constructor que crea colores, este es

Color(r, g, b)

Crea los colores combinado r de red, g de green y b de blue. El valor r,g,b son valoresfloating point en el rango de 0 a 1. Ellos son de tipo float, y si Ud. escribe, por ejemplo 0.5, elcompilador lo considera como double , y entregara un error debido que para especificar unvalor de tipo float, se escribe 0.5f. Un ejemplo.

Color c = new Color(1.0f, 1.0f, 0.0f);

(No escribe Color(1, 1, 0). Normalmente Ud. puede usar enteros donde los valores flotantes son requeridos, pero NO aquí!. La razón es que la clase Color tiene otro constructor el que tiene parámetros como integers en el rango 0 a 255.

Un listado de los colores estandares,

Color.black 0.0f 0.0f 0.0fColor.blue 0.0f 0.0f 1.0fColor.cyan 0.0f 1.0f 1.0fColor.gray 0.5f 0.5f 0.5fColor.darkGray 0.25f 0.25f 0.25fColor.lightGray 0.75f 0.75f 0.75fColor.green 0.0f 1.0f 0.0fColor.magenta 1.0f 0.0f 1.0fColor.orange 1.0f 0.8f 0.0fColor.pink 1.0f 0.7f 0.7fColor.yellow 1.0f 1.0f 0.0fColor.white 1.0f 1.0f 1.0f

Area de Computación , Universidad de La Serena16

Page 17: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Pintando FigurasPodemos usar objetos Graphics2D para colorear el interior de una figura, tales como rectángulos o elipses que encierran un área. La forma de hacerlo no sera usando setColor, sino el método fill,encargado de rellenar las áreas.

g2.fill(s)

Usando un objeto g2 de Graphics2D para desplegar la figura s rellena con los coloresasignados a g2. Por ejemplo, la siguiente declaración crea un pequeño circulo y lo despliega pintado de amarillo usando el objeto g2 de Graphics2D.

Ellipse2D.Double sol = new Ellipse2D.Double(140,50,20,20); g2.setColor(Color.yellow); g2.fill(sol);

El siguiente ejemplo usa la misma técnica que genero el carro, pero ahora pintado de rojo. Las ruedas son blancas, y tienen bordes como si fuesen neumáticos. La línea de base a sido reemplazada por un color azul de fondo. Note que el background debe ser pintado antes que el carro, de otra manera no verá el carro.

Ejemplo 5

import java.applet.*;import java.awt.*;import java.awt.geom.*;

public class PintaCarro extends Applet

{ public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g;

/* Pinta el background. */ Color paleBlue = new Color(0.75f, 0.750f, 1.0f); g2.setColor(paleBlue); g2.fill(new Rectangle2D.Double(0,0,300,300));

/* Pinta el cuerpo del carro. */ g2.setColor(Color.red); g2.fill (new Rectangle2D.Double(50,100,120,80)); g2.fill (new Rectangle2D.Double(170,130,80,50));

/* Pinta las ruedas */ g2.setColor(Color.darkGray); g2.fill(new Ellipse2D.Double(70,160,40,40)); g2.setColor(Color.white);

Area de Computación , Universidad de La Serena17

Page 18: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

g2.fill(new Ellipse2D.Double(80,170,20,20));

/* Pinta las ruedas */ g2.setColor(Color.darkGray); g2.fill(new Ellipse2D.Double(190,160,40,40)); g2.setColor(Color.white); g2.fill(new Ellipse2D.Double(200,170,20,20)); }}

Aquí está el carro pintado, las ondas se verán para cuando Ud. incorpore al código otros métodos. En todo caso en archivo PintaCarro.java esta el código que lo genera.

Escribiendo TextoAsí como hemos ya dibujado y pintado figuras , la próxima capacidad de los objetos Graphics2D es de usarlos para desplegar texto sobre la pantalla. Antes de llevar a cabo esto es necesario llamar a Graphics2D para saber que font usa. Un font(fuente) es un conjunto particular de figuras que pueden ser usadas para la habilitación de caracteres. Un font esta representado por objetos de tipo Font. El constructor siguiente puede ser usado para crear un objeto Font.

Font(family, style, size)

El parámetro family es un string asociado a un conjunto de fonts, un ejemplo de esto es Times Roman el cual es usado por el texto principal de estas notas y Courier usado para el texto de programas. Esto fue escrito con Ariel. Estos son los nombres que pueden ser usados para la familia de font

Area de Computación , Universidad de La Serena18

Page 19: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

SerifSansSerifMonospacedDialogDialogueInput

El parametro style indica si será usado en el texto italics o boldface:

Font.PLAINFont.ITALICFont.BOLDFont.ITALIC+Font.BOLD.

El parámetro size es el tamaño del punto font. Esta es la altura del carácter medido en unidades de 1/72 pulgadas(1pulg = 25.4 milímetros). Un punto de tamaño 1 es aprox. El tamaño de un pixel. Estas notas son escritas con punto12. De manera que Ud. puede crear un objeto Font llamar a Graphics2D para usarlo por medio del método.

g2.setFont(f)

Setea el objeto g2 de Graphics2D para usar el font f para escribir el texto que desee.

Otro método interesante es.

g2.drawString(text, x, y)

usando objeto g2 de Graphics2D para desplegar el string text, partiendo de la posición (x, y)en el área desplegada, estos valores son de tipo int. (x es la posición del texto e y es la altura de la linea base). El siguiente ejemplo ilustra el uso de font. En cada caso el estilo(style) es FONT.PLAIN, es decir no italic y no bold, y el tamaño de punto es 30.

Ejemplo 6

import java.applet.*;import java.awt.*;

public class Fuentes extends Applet{ final int TAM = 30;

public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g;

Font font1 = new Font("Serif", Font.PLAIN, TAM); g2.setFont(font1); g2.drawString("Serif", 50, 50);

Area de Computación , Universidad de La Serena19

Page 20: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Font font2 = new Font("SansSerif", Font.PLAIN, TAM); g2.setFont(font2); g2.drawString("SansSerif", 50, 100);

Font font3 = new Font("Monospaced", Font.PLAIN, TAM); g2.setFont(font3); g2.drawString("Monospaced", 50, 150);

Font font4 = new Font("Dialog", Font.PLAIN, TAM); g2.setFont(font4); g2.drawString("Dialog", 50, 200);

Font font5 = new Font("DialogInput", Font.PLAIN, TAM); g2.setFont(font5); g2.drawString("DialogInput", 50, 250); }}

Aquí esta lo que el applet despliega

Area de Computación , Universidad de La Serena20

Page 21: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

3.5 Creando un objeto Carro

A veces hace bien recopilar y volver al caso de dibujar o pintar, como el carro de mudanzas en ejemplo anteriores, sin embargo ahora el interés es volver a la definición de una clase Carro, así como un applet que crea y dibuja varios carros de mudanzas. Un objeto Carro contiene la situación de un carro de mudanzas, y su tamaño. Nosotros podremos crear carros de mudanzas con el constructor siguiente.

Carro(x, y, w)

Crea un objeto Carro, cuya esquina superior-izquierda está en (x, y) y ancho w.Un objeto Carro tiene un método.

c.PintaCarro(g2)

Pinta el carro c, usando un objeto g2 de Graphics2D.

La parte fundamental radica en la definición de la clase Carro, que se refiere a cambiar la declaración usada para que trabaje correctamente para cualquier esquina superior izquierda (x,y) (en vez de (50,100), como en ejemplo anterior), y cualquier w (en vez de 200). Aquí tenemos un esquema preliminar para la distancia que son usadas. Note que ellas dependen de x, y, w.

(0,0)

(x+0.6w, y+0.15w) (x,y)

0.6w

0.4w 0.4w0.1w 0.25w

(x+0.2w, y+0.4w) (x+0.8w, y+0.4w)

Area de Computación , Universidad de La Serena21

Page 22: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Luego veremos un ejemplo que contiene la clase Carro basada sobre este esquema, que además contiene una inscripción de una cierta fuente sobre el carro. La inscripción es:

JavaHelados

Otra clase importante será la clase applet MasCarros, la cual es capaz de crear una serie de carros pintados con la inscripción en cada uno de ellos en el área desplegada del applet.

Ejemplo 7

import java.awt.*;import java.awt.geom.*;

public class Carro

{ double x,y; // Coordenadas de esquina superior izquierda de Carro.

double w; // Ancho de Carro.

final Color COLOR1 = Color.red; // Color para el cuerpo. final Color COLOR2 = Color.darkGray; final Color COLOR3 = Color.lightGray; // Color de las ruedas( aros).

public Carro(double x0, double y0, double s0) { x = x0; y = y0; w = s0; }

public void PintaCarro(Graphics2D g2) { /* Pintar cuerpo de Carro. */ g2.setColor(COLOR1); Rectangle2D.Double tras = new Rectangle2D.Double (x, y, w*0.6, w*0.4); g2.fill(tras); Rectangle2D.Double delan = new Rectangle2D.Double (x+w*0.6, y+w*0.15, w*0.4, w*0.25); g2.fill(delan);

/* Paint ruedas. */ g2.setColor(COLOR2); Ellipse2D.Double ext1 = new Ellipse2D.Double (x+w*0.1, y+w*0.3, w*0.2, w*0.2); g2.fill(ext1);

Area de Computación , Universidad de La Serena22

Page 23: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Ellipse2D.Double ext2 = new Ellipse2D.Double (x+w*0.7, y+w*0.3, w*0.2, w*0.2); g2.fill(ext2);

/* Paint ruedas. */ g2.setColor(COLOR3); Ellipse2D.Double rueda1 = new Ellipse2D.Double (x+w*0.15, y+w*0.35, w*0.1, w*0.1); g2.fill(rueda1); Ellipse2D.Double rueda2 = new Ellipse2D.Double (x+w*0.75, y+w*0.35, w*0.1, w*0.1); g2.fill(rueda2);

/* Pinta el logo. */ Font f = new Font("Serif", Font.ITALIC, (int)(w/8)); g2.setFont(f); g2.setColor(Color.white); g2.drawString ("Java", (int)(x+w*0.05), (int)(y+w*0.12)); g2.drawString ("Helados", (int)(x+w*0.05), (int)(y+w*0.24)); }}

Notar que este programa si lo ejecuta tal como esta le saldrá un mensaje de excepción, y esto es debido a que no tiene public static main(), ya que es una clase que será utilizada por el applet MasCarro, cuyo código se describe a continuación. Este tipo de errores es frecuente.

import java.applet.*;import java.awt.*;

/* Display Carros. */

public class MasCarros extends Applet

{ public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g;

new Carro(200,200,130).PintaCarro(g2); new Carro(25,75,50). PintaCarro(g2); new Carro(-60,140,200).PintaCarro(g2); new Carro(180,20,250). PintaCarro(g2); new Carro(50,-20,100). PintaCarro(g2); new Carro(70,270,30). PintaCarro(g2); }}

Area de Computación , Universidad de La Serena23

Page 24: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Cuya ejecución origina el applet siguiente

Leyendo la EntradaRespecto a los ejemplos que se vieron en las primeras clases y que hacían mención a las aplicaciones, en donde la forma de dialogo estaba creada por la clase JoptionPane. Ahora volvemos a esta idea con el fin de interactuar con el usuario a través de un mensaje del programa. Por ejemplo, la siguiente declaración causa un dialogo desplegando el mensaje ‘Ingrese el ancho del Carro’, a lo que el usuario deberá ingresar el string de caracteres y click OK (o tipee Return). Finalmente el string será asignado a la nueva variable carrete y el diálogo desaparece.

String carrete = JOptionPane.showInputDialog (Ingrese el ancho del Carro.);

Area de Computación , Universidad de La Serena24

Page 25: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

La misma técnica puede ser usada para leer números: primero el usuario ingresa el nombre el cual es leído como string en st, y entonces lo puede convertir a número usando los métodos Integer.parseInt(st) ó Double.parseDouble(st).

En esta otra versión el programa presenta una variante utilizando lo que aquí se menciona, en particular se presenta un dialogo al usuario en términos de ingresar el ancho del carro, para así el applet pueda generar un carro del tamaño solicitado y en la posición correcta.

La declaración que presenta el dialogo al usuario debería ser localizada a la partida del método paint(). Sin embargo, el efecto de hacer esto es que el dialogo es desplegado cada vez que windows manager decide refrescar el área del applet y llamar a paint. Lo que se quiere es que aparezca el dialogo justamente a la partida. Afortunadamente Java proporciona un conveniente camino para hacerlo. El método paint no es el único método en un applet que el window manager llama. Si proporcionamos un método con el encabezado,

public void init()

el window manager llamara justamente una vez, al comienzo de la ejecución. Este método puede ser usado para llevar a cabo cualquier proceso que se requiera una sola vez por el applet.

Ejemplo 8

import java.applet.*;import java.awt.*;import javax.swing.*;

/* Lee el tamaño y despliega el Carro con esa dimensión. */public class TamCarro extends Applet{ private double tamCarro; public void init() { String input = JOptionPane.showInputDialog ("Ingrese el ancho del Carro: "); tamCarro = Double.parseDouble(input); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; double x = (300 - tamCarro)/2; double y = (300 - tamCarro/2)/2; new Carro(x,y,tamCarro).PintaCarro(g2); }}

Area de Computación , Universidad de La Serena25

Page 26: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Para cuando se ingrese ancho 56, se genera el siguiente applet

Este applet ha sido diseñado sobre el supuesto que el tamaño de área desplegada es 300300. Ud. podrá hacer el applet más pequeño si lo desea chequeando el tamaño actual del área desplegada antes que posicione el carro. El método llama a getWidth() retornando el ancho del área desplegada, y getHeight() entrega la altura actual. Supongamos que reemplazamos las declaraciones 2 a 4 del método paint

double x = (getWidth() - tamCarro)/2;double y = (getHeight() - tamCarro/2)/2;new Carro(x,y,tamCarro).PintaCarro(g2);

Suponga que ejecutamos esta versión del programa y luego tendrá la oportunidad de ajustar las fronteras de la ventana del appletviewer pulsando el mouse cuidadosamente en los bordes del applet. Cada vez que esto pasa el windows manager repintará el carro centrada en el medio de la nueva área de despliegue con la frontera cambiada. A propósito, si usted quiere darle un fondo que consiste en un solo color a una escena, la manera más simple de hacerlo es agregando una declaración del tipo

setBackground(Color.blue);

al método init, o paint.

Unas palabras finales sobre la ejecución de applets. Si Ud. quiere chequear que esta haciendo su applet en cualquier momento, podrá siempre insertar la llamada a

Area de Computación , Universidad de La Serena26

Page 27: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

System.out.println., a lo que desplegara información en la ventana DOS en el sentido usual. Me explico, si Ud. ingresa la declaración

System.out.println(llamada a paint());

al comienzo del método paint, entonces Ud. verá que tan a menudo el window manager llama a paint, pues el mensaje llamada a paint() aparece en la ventana DOS cada vez.

Podemos seguir manipulando el código, por ejemplo incorporar al código de PintaCarro.java un patrón de relleno degradado, que es un ejemplo de otras alternativas tales como usar colores sólidos como se hizo antes, texturas o un patrón creado por nosotros. El patrón de relleno se usa definiendo el método setPaint() de Graphics2D con un objeto Paint como su único argumento. Esta interfaz se rellena ya sea por GradientPaint(), TexturePaint() y Color(). Una llamada al método constructor GradientPaint() tiene el formato siguiente:

GradientPaint(x1, y1, color1, x2, y2, color2); x1 e y1 es donde comienza el color representado por color1, x2, y2 donde termina el desplazamiento en color2. Si usa un desplazamiento de gradiente cíclico una variable booleano se le incorpora como 7-parámetro al final. true cíclico, false acíclico.Las instrucciones siguientes crean y seleccionan un degradado cíclico.

GradientPaint gp = new GradientPaint(0F,0F,Color.green, 50F,50F,Color.orange,true); g2.setPaint(gp);

Java2D agrega la capacidad de variar el ancho de la línea de dibujo al usar el método setStroke() con BasicStroke. Un constructor de este tipo tiene 3-argumentos. Un valor float que representa el ancho de la línea, con 1.0 como la norma. Un valor int que determina el estilo del final de línea. Un valor int que determina el estilo de unión entre dos segmentos de línea. Los estilos de final de línea son: CAT_BUTT, CAP_ROUND y CAP_SQUARE. Mientras que los estilos de unión de líneas son JOIN_MITTER, JOIN_ROUND, y

JOIN_BEVEL.Por otra parte, los arcos se crean con la clase Arc2D.Float y la gracia que tiene es poder definir como cerrar un arco, estos estilos son: Arc2D.OPEN, Arc2D.CHORD y Arc2D.PIE

Ejemplo de un matiz con olas (se lo incorpóre al archivo PintaCarro.java) como trasfondo

g2.setColor(Color.white);BasicStroke pint = new BasicStroke(2F, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);g2.setStroke(pint);

Area de Computación , Universidad de La Serena27

Page 28: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

for (int ax = 10; ax < 340; ax += 10) for (int ay = 30; ay < 340 ; ay += 10) { Arc2D.Float olas = new Arc2D.Float(ax, ay, 10, 10, 0, -180, Arc2D.OPEN); g2.draw(olas); }

PolígonosSe crean polígonos definiendo cada movimiento desde un punto a otro. Los movimientos para crear un polígono están definidos como un objeto GeneralPath() que también es parte del paquete java.awt.geom. Un objeto GeneralPath puede ser creado sin ningún argumento, como por ejemplo.

GeneralPath poli = new GeneralPath();

El método moveTo() de GeneralPath se usa para crear el primer punto en el polígono. Si Ud. quisiera iniciarlo en las coordenadas 5, 0 debería declarar moveTo(5f, 0f), después de haber creado el punto de partida puede usar lineTo() para crear líneas que finalizan en un nuevo punto. Poli.lineTo(205f, 0f); podría ser otro punto. Si desea cerrar un polígono utilice el método closePath().

Turtle graphics( Gráfica de Tortugas)

Ahora queremos hacer un ejemplo diferente basado sobre Turtle graphics, que proviene del Logo, introducido por MIT (Massachusetts Institute of Technology) en los años 70 para enseñar a programar. Uno de las aplicaciones era poder comandar un robot llamado 'Turtle' (Tortuga) que se mueve en alguna dirección, con la facilidad de poder describir la trayectoria según el lápiz si está en la posición ‘down’ o no describe nada si el lápiz está en la posición ‘up’. La idea en general es transferir el mundo de Logo a Java, para tal efecto, definiremos una clase llamada Turtle, que como es de esperar tiene un objeto Turtle. Usando esta clase podremos construir los turtles que queramos. Un Turtle puede ser controlado llamando a métodos que deberán definirse. Aquí esta la lista de métodos que son definidos en la clase Turtle. Ellos son métodos public.

Métodos:t.move(s) Se mueve t hacia delante una distancia s. s es medido en pixeles.

t.left(cant) Gira t, cant grados a la izquierda.

t.right(cant) Gira t, cant grados a la derecha.

t.penDown() t baja el lápiz y escribe.

Area de Computación , Universidad de La Serena28

Page 29: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

t.penUp() t levanta el lápiz y no escribe.

Los parametros s y cant son todos de tipo double. Aquí se da algunas declaraciones que crean un Turtle t, dibujando un triángulo.

Turtle t = new Turtle();t.penDown();t.move(50);t.left(120);t.move(50);t.left(120);t.move(50);

Cada vez que la tortuga se mueve, va hacia delante a una distancia 50 describiéndo una línea sobre la pantalla, al alcanzar el final de la línea, gira un ángulo de 120, y luego se mueve hacia delante nuevamente, todo el camino lo hace marcando su trayectoria.

etapa2

etapa1

etapa3

La tortuga empieza y termina aquí.

Otro ejemplo de una trayectoria para turtle es:

Turtle t = new Turtle();t.penDown();for (int i = 0; i < 100; i++){ t.move(i); t.left(36);

}

Area de Computación , Universidad de La Serena29

Page 30: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Notar que el cuerpo del loop esta limitado por 100 veces. Esta vez, el turtle se mueve hacia delante y gira a la izquierda. Observar que si estos movimientos hacia delante estuviesen hechos al mismo tiempo hubiesen dibujado un círculo, sin embargo debido a que el movimiento hacia delante decrece cada vez en 36 grados ocasiona una espiral concéntrica, que es la figura que Ud. acabo de observar. Hasta ahora hemos visto como usar objetos Turtle, más no del cómo se diseña Turtle.Los campos de un objeto Turtle deben contener todos los datos necesarios para representar el estado de un turtle en un momento particular. Algunos rasgos de un turtle no son pertinentes en estos programas de dibujo, es decir no tiene necesidad de grabar por ejemplo, cuántos años tiene, o el color de su caparazón, pero sí, su posición en la pantalla, y en qué dirección está apuntando, y si tiene la capacidad de describir, estos si que son datos pertinente. Así una Turtle esta dado por los siguientes campos.

1. Dos campos que representan las coordenadas x, y de su posición sobre la pantalla son declaradas.

private double x,y;

Es decir, ellos miden en pixeles el origen en la esquina superior izquierda del area desplegada.

Area de Computación , Universidad de La Serena30

Page 31: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

2. Un campo llamado dir representa la dirección en la que está apuntando el turtle. Este es el ángulo entre la línea que apunta al Este y la línea que apunta en la dirección del turtle.

turtle

dir

El ángulo esta medido en grados. Por ejemplo, si el turtle esta apuntando hacia la parte superior de la pantalla, la dirección es 90. El campo se declara.

private double dir;

3. Un campo para registrar la capacidad de describir su trayectoria( up o down) es un campo boolean isDown, donde es true si esta down, false si esta up. Se declara como sigue.

private boolean isDown;

Algunas de las decisiones hechas para escoger estos cuatro campos que representan el estado de un turtle son bastante arbitrarios. El origen de las coordenadas podría haberse puesto en el centro del área desplegada, y el eje y podría apuntar hacia arriba de la manera tradicional. La dirección podría medirse en radianes y así sucesivamente. Note que éstos son todos los problemas asociados al diseño, pues ninguno de ellos afecta el comportamiento de los métodos públicos. De manera que 'customer' está completamente ajeno a los cambios que se pudieron haber hecho, esta situación es un ejemplo concreto de encapsulación, que es uno de los rasgos más útiles de la programación orientación a objetos. Uno de los objetivos de encapsular la aplicación del turtle en la definición de la clase Turtle es que usted pueda algún día reescribir completamente la definición y los cinco métodos básicos y el constructor, y los programas “Escalera de Caracol” y “Estrella” correrían sin dificultad.

Una vez que los campos han sido escogidos, la próxima tarea es implementar los métodos y constructores. El método penDown debe asegurar que el lápiz esté “down”. Para ello deberá setear el campo istDown a true, por el contrario debería setear isDown a false. Aquí está las definiciones de estos dos métodos.

/** Alzar el lápiz.*/public void penUp(){ isDown = false;

Area de Computación , Universidad de La Serena31

Page 32: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

}

/** Apoyar el lápiz.*/public void penDown(){ isDown = true;}

Los métodos left y right son también muy simples. left(cant) simplemente agrega cant a la direccion que esta apuntando el turtle. right(cant) substrae cant.

/** Girar el turtle a la izquierda cant grados.*/public void left(double cant){ dir = dir + cant;}

/** Girar el turtle a la derecha cant grados.*/public void right(double cant){ dir = dir - cant;}

Si el turtle se mueve a una distancia s, la coordenada x, debera ser incrementada por s Math.cos(dir) y la coordenada y, decrementada s Math.sin(dir). Ver diagrama.

s

s Math.sin(dir) dir

s Math.cos(dir)

Usando estas dos expresiones podemos empezar a trabajar sobre la nueva posición del turtle. Ahora, si el lápiz está down podremos dibujar la línea desde la posición vieja a la nueva, el método move interpreta lo dicho anteriormente. Notar que el ángulo dir debe ser convertido de grados a radianes antes de usar Math.cos y Math.sin.

/** Mover la tortuga hacia delante una distancia s.*/public void move(double s)

Area de Computación , Universidad de La Serena32

Page 33: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

{ double oldX = x; double oldY = y; double radians = dir * Math.PI / 180; x = x + s*Math.cos(radians); y = y - s*Math.sin(radians); if (isDown) Draw la línea desde (oldX,oldY) a (x,y).}

A este punto la definición de la clase Turtle ha sido casi tan simple como la clase Alumno, sin embargo los problemas que deberemos solucionar son :

¿Cómo dibujar la línea de la posición vieja de la tortuga a su nueva posición? . Es fácil crear la línea. usando la declaración

Line2D.Double = new Line2D.Double(oldX, oldY, x, y);

Pero, para dibujar esta línea necesitamos objetos Graphics2D conectados al area desplegada. Cómo encontrar una conveniente Graphics2D?

Otro problema surge cuando tratamos de implementar el constructor que debe crear una nueva tortuga localizada en el centro del área desplegada. Las coordenadas de éste punto son (w/2, h/2) donde w es la anchura del área desplegada, y h es su altura. Con esta información el constructor tiene la forma:

/** Crea una nueva turtle centrada en la pantalla, mirando

al norte y el lápiz levantado.*/public Turtle(){ Setea w = ancho del area display Setea h = alto del area display x = 0.5*w; y = 0.5*h; dir = 90; isDown = false;}

¿Pero cómo puede obtenerse la anchura y altura del área desplegada? El método move y el constructor necesitan tener acceso al area desplegada en la que las tortugas están dibujando. Una manera de darles acceso involucra averiguar más sobre la forma en que Java maneja ventanas.

Lo que usted ve en la pantalla cuando un programa está corriendo es la graphical user interface ( interfaces gráfica del usuario , GUI). Los botones, menús, áreas del despliegue, etc.

Area de Computación , Universidad de La Serena33

Page 34: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

que constituyen el GUI son sus components. Hasta ahora nuestros programas de Java han estado muy limitados en ese sentido, pues nuestros applets tienen un área de despliegue muy simple, y nuestras aplicaciones tienen la ventana de DOS, pero sabemos que podemos generar mensajes de dialogos usando JOptionPane. En el caso de un programa Java toda componente GUI esta asociada con alguna forma de objetos Component que son los que manejan las componentes del area desplegada en la pantalla. Si pudiesemos organizar los Turtles de manera que accedan al objeto Component, el cual maneja el área desplegada que ellas estan utilizando, entonces ellos podrían llevar a cabo las operaciones que se necesitan. Suponga que c es cualquier tipo de objeto Component. Se asociará con una área rectangular en la pantalla. El valor de la expresión

c.getWidth()

será el ancho medido en pixeles de esta area rectangular. Y

c.getHeight()

es la altura del área. También la expresión

c.getGraphics()

retorna un objeto Graphics, el que puede ser usado para dibujar o pintar sobre el área de la pantalla.

Lo que haremos entonces para completar la definición de la clase Turtle, es agregar una variable estática, llamada window, la que contendrá una referencia al objeto Component que maneja el área de despliegue que las turtles estan dibujando. Window no será un campo de un objeto Turtle, sino que será una simple variable que puede ser accesada por cualquier método y constructor definido en la clase. Entonces la expresión window.getWidth() puede ser usada para obtener la anchura del área del despliegue, y window.getHeight() puede usarse para conseguir la altura. Mientras que window.getGraphics() genera un objeto Gráfico. Aquí esta la definición completa del constructor.

public Turtle(){ int w = window.getWidth(); int h = window.getHeight(); x = 0.5*w; y = 0.5*h; dir = 90; isDown = false;}

Area de Computación , Universidad de La Serena34

Page 35: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Y aquí esta la definicion del método move. El objeto Graphics producido por window.getGraphics() puede ser considerado como objeto grafico Graphics2D en el mismo sentido que habiamos visto en el método applet’s paint.

public void move(double s){ double oldX = x; double oldY = y; double radians = dir * Math.PI / 180; x = x + s*Math.cos(radians); y = y - s*Math.sin(radians); if (isDown) {

Line2D.Double line =new Line2D.Double(oldX, oldY, x, y); Graphics2D g2 =(Graphics2D) window.getGraphics(); g2.draw(line); g2.dispose(); }}

Para completar la definicion de la clase Turtle, agregamos el método llamado setWindow para setear la variable window a una componente particular. Este es independiente de cualquier objeto Turtle, y por eso es declarado static.

/** Setear 'window' (= el componente sobre el cual todo turtle son dibujadas) a c.

*/public static void setWindow(Component c){ window = c;}

Ahora podemos usar las turtles en un applet y asegurarnos que las turtles dibujen sobre el área desplegada del applet. Resulta que un applet es un ejemplo de un objeto Component, y el área de la pantalla esta asociado al área desplegada del applet. De manera que para hacer esto se necesita llamar a Turtle.setWindow(c) donde c es una referencia al mismo applet. Java tiene una palabra reservada this que simboliza una referencia al objeto asociado con el método que está ocurriendo actualmente. Si la declaración es

Turtle.setWindow(this);

ejecutada en uno de los métodos applet’s, entonces la variable window sera asignada como una referencia al applet, y todo Turtles dibujara en el área desplegada por el applet’s. Puesto que esto tiene que ser realizado al principio, el lugar natural para poner la declaración es en el

Area de Computación , Universidad de La Serena35

Page 36: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

método init. (Nota: Ud. puede notar que los métodos init y paint en la clase applet no son static).

import java.applet.Applet;import java.awt.Graphics;

public class Espiral extends Applet{

public void init() {

Turtle.setWindow(this); }

/* Draw una espiral. */ public void paint(Graphics g) { Turtle t = new Turtle(); t.penDown(); for (int i = 0; i < 100; i++) { t.move(i); t.left(36); } }}

La próxima aplicación utiliza cuatro turtles que empiezan desde las 4 esquinas del cuadrado, bajan sus plumas y empiezan a cazarnos. La tortuga de la esquina inferior izquierda apunta a la turtle situada en la esquina inferior derecha , la que a su vez apunta a la turtle de la esquina superior derecha, la que a su vez apunta a la turtle situada en la esquina superior izquierda y esta a la turtle de la esquina inferior izquierda y asi sucesivamente.... Vea el diagrama.

Después de estar a corta distancia, cada una ajusta su dirección de tal manera que apunta hacia la tortuga designada. Aquí está el dibujo que ellas generaron.

Area de Computación , Universidad de La Serena36

Page 37: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Los métodos del caso proporcionados hasta ahora por la clase Turtle no son suficientes para este programa, notar que una vez que parten no hay como detenerlas, es decir hasta el momento no nos dan el poder para hacer que una turtle vuelva a mirar a otra. Para conseguir este tipo de interacción es necesario extender el juego original de métodos proporcionado por la clase. Nosotros agregaremos el método siguiente

t1.atracts(t2);Gira t2 mirando a Turtle t1.

Aquí esta la definición de atracts.

/** Gira Turtle t para mirarla, se atraen.*/

public void atracts(Turtle t){ double dX = x - t.x; double dY = t.y - y; double rad = Math.atan2(dY,dX); t.dir = 180*rad/Math.PI;}

Area de Computación , Universidad de La Serena37

Page 38: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Notar que el método llamado es Math.atan2(dY,dX),el cual entrega el ángulo (en radianes) en la esquina izquierda del triángulo.

Math.atan2(dY,dX)dY

dX

La declaración final es una constante del tipo #define en C, convirtiéndo los ángulos a grados. Aquí esta el applet completo que dibuja la curva Acoso.

import java.applet.Applet;import java.awt.Graphics;

public class Acoso extends Applet

{ final int ETAP = 5; final int DIAG = 200; final int CUANTOS = 58;

public void init() { Turtle.setWindow(this); }

public void paint(Graphics g) { /* Posicion del turtles. */ Turtle t0 = new Turtle(); t0.left(45); t0.move(DIAG); t0.penDown();

Turtle t1 = new Turtle(); t1.left(135); t1.move(DIAG); t1.penDown();

Turtle t2 = new Turtle(); t2.left(225); t2.move(DIAG); t2.penDown();

Turtle t3 = new Turtle(); t3.left(315); t3.move(DIAG); t3.penDown();

/* Hacer que el turtles acose a los otros. */

Area de Computación , Universidad de La Serena38

Page 39: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

for (int i = 0; i < CUANTOS; i++) { t1.atracts(t0); t0.move(ETAP);

t2.atracts(t1); t1.move(ETAP);

t3.atracts(t2); t2.move(ETAP);

t0.atracts(t3); t3.move(ETAP);

} }}

Como ya se ha visto en los capítulos preliminares existen procesos que se llaman a sí mismo, tales procesos o métodos son llamados métodos recursivos, muy útiles y fácil de programar en contraste con los métodos iterativos. A continuación mostramos un ejemplo para turtle graphics donde usamos recursión que es mucho mejor que usar declaraciones de ciclo.

Fractales: (drawTree)

El programa contiene un método drawTree, cuya especificación drawTree(tam), dibuja un árbol en donde el tamaño del tronco es tam.

Aquí hay un árbol llamando al método drawTree(60).

Area de Computación , Universidad de La Serena39

Page 40: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

import java.applet.Applet;import java.awt.Graphics;

/* Use turtle para dibujar un fractal. */

public class Tree extends Applet

{ Turtle fred; // turtle que dibuja el árbol.

public void init() { Turtle.setWindow(this); }

public void paint(Graphics g) { fred = new Turtle(); fred.move(-100); drawTree(60); } /* Use turtle fred para dibujar un árbol recursivo. size = longitud del tronco. */ void drawTree(double size) { if (size < 1) return; fred.penDown(); fred.move(size); fred.penUp(); fred.left(20); drawTree(size*0.75); fred.right(50); drawTree(size*0.65); fred.left(30); fred.move(-size); }}

Que hace este método?. Si el tamaño del tronco del árbol es muy pequeño el método no hace nada. Si por otro lado no es tán pequeño dibujará el tronco y agrega 2 ramas. Las ramas forman

un ángulo, y ambos consisten de una pequeña versión de árbol. Ellos son dibujados por llamadas recursivas al mismo método drawTree

rama1 rama2

Area de Computación , Universidad de La Serena40

Page 41: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

Si bien es cierto que los métodos recursivos son a veces más fácil de programar cabe preguntarse. Cuándo podría usar recursión? Desafortunadamente no existe una respuesta en forma general, pues dependerá de la situación y los recursos de memoria que Ud. pueda disponer.

Listado de la clase Turtle

import java.awt.*;import java.awt.geom.*;import java.applet.*;

/** Un objeto Turtle representando un Logo turtle. El turtle esta en una cierta posición sobre la pantalla mirando en

una cierta dirección. Si se mueve hacia delante dibuja una línea sobre la pantalla, si el lápiz está bajo.

*/

public class Turtle

{ private double x,y; // coordenadas x e y de turtle.

private double dir; /* dirección actual del turtle medido en grados contrario a los

sentidos del reloj.*/

private boolean isDown; // isDown = true si el turtle's esta down, // false si esta up.

private static Component window; // La componente sobre la cual todo turtles dibujara.

/** Mueve turtle hacia delante una distancia s. */ public void move(double s) { double oldX = x; double oldY = y; double radians = dir * Math.PI / 180; x = x + s*Math.cos(radians); y = y - s*Math.sin(radians); if (isDown) { Line2D.Double line = new Line2D.Double(oldX, oldY, x, y); Graphics2D g2 = (Graphics2D) window.getGraphics(); g2.draw(line); g2.dispose(); } }

Area de Computación , Universidad de La Serena41

Page 42: Applet03+ (1)

Prof. Dr. Eric Jeltsch F. Programación en Java2 Cap 3: Applets

/** Gira el turtle a la izq deg grados. */ public void left(double deg) { dir = dir + deg; }

/** Gira el turtle a la derecha deg grados. */ public void right(double deg) { dir = dir - deg; }

/** levanta el lapiz el turtle's. */ public void penUp() { isDown = false; }

/** baja el lápiz el turtle's. */ public void penDown() { isDown = true; }

/** Gira el Turtle t mirando a los otros. */ public void atracts(Turtle t) { double dX = x - t.x; double dY = t.y - y; double rad = Math.atan2(dY,dX); t.dir = 180*rad/Math.PI; }

/** Crea new turtle como centro de pantalla mirando al north, lapiz levantado.

*/ public Turtle() { int w = window.getWidth(); int h = window.getHeight(); x = 0.5*w; y = 0.5*h; dir = 90; isDown = false; }

/** Setea 'window' (= la component que dibujan)a c. */ public static void setWindow(Component c) { window = c; }}

Area de Computación , Universidad de La Serena42