Sei sulla pagina 1di 38

Programacin en el lenguaje Java

Captulo 6

APPLETS
2002 por Angel Franco Garca de la Escuela Universitaria de Ingeniera Tcnica Industrial de Eiba 1. Adaptado por Diego L Aristizbal Ramrez, para el curso Introduccin a la Fsica Computacional y a la Simulacin que se ofrece a los estudiantes de Ingeniera Fsica de la Escuela de Fsica de la Universidad Nacional de Colombia Sede Medelln

En este captulo se estudiar la elaboracin de applets con herramientas grficas de java 1 y java 2.

6.1 Elementos bsicos de un Applet


6.1.1 Introduccin
Tal como lo dijimos en el captulo 1, el lenguaje Java se puede usar para crear dos tipos de programas: los applets y las aplicaciones. Un applet es un elemento ms de una pgina web, como una imagen o una porcin de texto. Cuando el navegador carga la pgina web, el applet insertado en dicha pgina se carga y se ejecuta. Mientras que un applet puede transmitirse por la red Internet, una aplicacin reside en el disco duro local. Una aplicacin Java es como cualquier otra que est instalada en el ordenador. La otra diferencia es que un applet no est autorizado a acceder a archivos o directorios del ordenador cliente si no es un applet completamente fiable. Un applet, no es como una aplicacin que tiene un mtodo main . El applet est insertado en una pgina web que se muestra en la ventana del navegador. El navegador toma el control del applet llamando a algunos de sus mtodos, uno de estos es el mtodo paint que se llama cada vez que se necesita mostrar el applet en la ventana del navegador. Cuando el applet se carga, el navegador llama a su mtodo init . En este mtodo el programador realiza tareas de inicializacin, por ejemplo, establecer las propiedades de los controles, disponerlos en el applet, cargar imgenes, etc. El mtodo init se llama una sla vez. Despus, el navegador llama al mtodo paint . A continuacin, se llama al mtodo start . Este mtodo se llama cada vez que se accede a la pgina que contiene el applet. Esto quiere decir, que cuando dejamos la pgina web que contiene el applet y regresamos de nuevo pulsando en el botn "hacia atrs" el mtodo start vuelve a llamarse de nuevo, pero no se llama el mtodo init. Cuando dejamos la pgina web que contiene el applet, por ejemplo, pulsando en un enlace, se llama al mtodo stop . La gran parte del material que se encuentra en este captulo fue tomado del excelente curso sobre programacin JAVA que ofrece el profesor Angel Franco Garca: http://www.sc.ehu.es/sbweb/fisica/cursoJava/Intro.htm. Las secciones 6.3 en adelante fueron creadas por Diego L. Aristiz bal R
1

119

Programacin en el lenguaje Java

Final mente, cuando salimos del navegador se llama al mtodo destroy. Recomendamos al lector ir al captulo 1 seccin 1.4.2 donde se dan los pasos para elaborar el primer applet. Otra forma ligeramente diferente a la expuesta en el captulo 1, de incluir un applet en una pgina web es comprimiendo los archivos .class en archivos .jar La ventaja de este mtodo es que la bajada de ellos en la red Internet es mucho ms rpida. En la siguiente seccin expondremos como se deber proceder para lograr esto.

6.1.2 Comprensin de los archivos .class


Cuando el proyecto es complejo, al compilarlo se crean varios archivos .class en el mismo subdirectorio. Resulta engorroso trasladarlos desde nuestro ordenador al servidor cuando publicamos las pginas web. Se corre el peligro de mezclar los archivos o perder alguno por el camino. Para facilitar esta tarea, se puede comprimir todos los archivos .class resultantes del proceso de compilacin de un proyecto en un nico archivo cuya extensin es .jar, mediante un asistente denominado En las versiones anteriores a la 1.1, si un applet estaba formado por varias clases o tena recursos como imgenes GIF o archivos de sonido, cada uno de los archivos se tena que descargar individualmente del servidor. Esto supona una carga extra para el servidor, y la necesidad de que el usuario tuviese que esperar hasta que todos los componentes que forman el applet estuviesen disponibles. Para solventar este problema Sun introdujo los archivos JAR, que son similares a los archivos ZIP, de hecho se pueden descomprimir con la misma herramienta WinZip. De este modo, todos los archivos que forman el applet estn situados en un nico archivo comprimido, con lo que disminuye el trabajo del servidor y el tiempo de descarga. Los archivos JAR incluyen una archivo denominado MANIFEST.MF en el subdirectorio META-INF que contiene la lista de los componentes del archivo JAR y puede incluir firmas digitales. 6.1.2 .1 Cmo comprimir los arhivos .class con el jdk? En la lnea de comandos del DOS, nos ubicamos en el directorio donde estn las clases y archivos . Por ejemplo si estn nuestros archivos en el directorio C\mis_proyectos \ejemplo_1>, y le quere mos colocar al archivo .jar el mismo nombre del applet, procede ramos as: C\mis_proyectos\ejemplo_1> jar cf NombreApplet. jar *.class

Si adems tiene por ejemplo archivos de imagen .gif tambin se podrn empaquetar en el mismo archivo .jar: C\mis_proyectos\ejemplo_1> jar cf NombreApplet. jar *.class *.gif De la misma forma se procedera para otros archivos de imgenes y de sonido.

120

Programacin en el lenguaje Java

Para ms detalles sobre los archivos .jar se deber consultar un manual de java o visitar la pgina de SUN . 6.1.2 .2 Cmo incluir los archivos .jar en una pgina web? Supongamos que colocamos el archivo applet1.jar en el mismo subdirectorio que documento HTML que contiene el applet, la etiqueta <APPLET>... </APPLET > se escribe de la forma que sigue. Fija rse que aparece un nuevo parmetro ARCHIVE que indica el nombre y la ubicacin del archivo comprimido .jar.

<APPLET CODE = "applet1.Applet1.class" ARCHIVE = "applet1.jar" WIDTH = 400 HEIGHT = 300 HSPACE = 0 VSPACE = 0 ALIGN = middle > </APPLET>

Si el archivo applet1.jar est en un subdirectorio denominado jars por debajo del documento HTML escribimo s

<APPLET CODE = "applet1.Applet1.class" ARCHIVE = "jars/applet1.jar" WIDTH = 400 HEIGHT = 300 HSPACE = 0 VSPACE = 0 ALIGN = middle > </APPLET>

Si el archivo applet1.jar est en un subdirectorio denominado jars al mismo nivel que el subdirectorio que contiene el documento HTML escribimos

<APPLET CODE = "applet1.Applet1.class" ARCHIVE = "../jars/applet1.jar"

121

Programacin en el lenguaje Java

>

WIDTH HEIGHT HSPACE VSPACE ALIGN

= 400 = 300 =0 =0 = middle

</APPLET>

6.1.3 Los parmetros del applet


Los parmetros es la forma en la que se comunica la pgina web y el applet. 6.1.3.1 La anchura y altura del applet Las dimesiones de la applet se establecen mediante los valores de los parmetros WIDTH y HEIGHT de la etiqueta applet. La anchura y altura del applet se pueden establecer mediante la funcin setSize, de la cual existen dos versiones setSize(400,300); o bien, setSize(new Dimension(400,300)); Donde Dimension , es una clase del jdk con dos miembros datos pblicos width y height . Ambas sentencias establecen la dimensin del applet en 400 pixels de ancho y 300 pixels de alto. Ahora bien, hemos de tener cuidado con esta sentencia ya que podra plantearse la siguiente situacin contradictoria <APPLET CODE = "applet2.Applet2.class" ARCHIVE = "applet2.jar" WIDTH = 400 HEIGHT = 300 HSPACE = 0 VSPACE = 0 ALIGN = middle >

</APPLET>

public class Applet2 extends Applet{


public void init(){ setSize(150,200); } //...

122

Programacin en el lenguaje Java

} En el appletviewer el tamao de la ventana y tamao del applet son distintos. La ventana del appletviewer es mayor que el applet. Sin embargo, en Internet Expl orer 5.0 la ventana que aparece en el navegador y el applet tienen las mismas dimensiones, las dadas por los parmetros WIDTH y HEIGHT dejando sin efecto la sentencia setSize. Para evitar posibles inconvenientes, el applet puede leer los datos asociados a los parmetros WIDTH y HEIGHT de la etiqueta APPLET mediante la funcin getParameter miembro de la clase base Applet, y despus pasarle dichos datos a la funcin setSize para establecer el tamao del applet. En la funcin miembro init, getParameter miembro de la clase Applet lee el dato asociado al parmetro (WIDTH o HEIGHT), y devuelve un string, que ha de convertirse en un dato numrico de tipo int . Los valores numricos se guardan en las variables locales ancho y alto, y luego, se pasan a la funcin setSize para establecer el tamao del applet. De este modo el tamao y disposicin del applet est controlado por la pgina web en la que est insertado. public void init(){ int ancho = Integer.parseInt(this.getParameter("WIDTH")); int alto = Integer.parseInt(this.getParameter("HEIGHT")); this.setSize(ancho,alto); } Como vimos al estudiar el captulo de las excepciones (seccin 5.1) , la conversin de un string en un nmero es mejor llevarla a cabo, por razones de seguridad, en un bloque try...catch. En el caso de que el proceso de conversin falle, se crea y se lanza un objeto ex de la clase NumberFormatException que es capturado por el bloque catch para notificar este problema al usuario. public void init(){ int ancho=400; //valores por defecto int alto=300; try{ ancho = Integer.parseInt(this.getParameter("WIDTH")); alto = Integer.parseInt(this.getParameter("HEIGHT")); }catch(NumberFormatException ex){ System.out.println("Error en los parmetros WIDTH y HEIGHT") ; } this.setSize(ancho,alto); } 6.1.3.2 Otros parmetros Los parmetros que vamos a definir son tres, la posicin (ABSCISA y ORDENADA) del mensaje que se va a imprimir en el applet, y el MENSAJE mismo. En la figura y en el cuadro adjunto se mue stra la definicin de cada uno de los parmetros Nombre ABSCISA MENSAJE Tipo Variable int x y String texto Valor por defecto 10 20 El primer applet

ORDENADA int

123

Programacin en el lenguaje Java

Para pasar los parmetros al applet se deber escribir unas lneas adicionales en el archi vo .html: <APPLET CODEBASE = "." CODE = "applet2.Applet2.class" NAME = "TestApplet" WIDTH = 400 HEIGHT = 300 HSPACE = 0 VSPACE = 0 ALIGN = middle > <PARAM NAME = "ABSCISA" VALUE = "10"> <PARAM NAME = "ORDENADA" VALUE = " 20"> <PARAM NAME = "MENSAJE" VALUE = "El primer applet"> </APPLET> Asimismo, genera una funcin la redefinicin de getParameterInfo de la clase base Applet que devuelve la informacin relativa a los parmetros pero que no tiene de momento inters El cdigo fuente del applet se da a continuacin: package applet2; public class Applet2 extends Applet { int x; int y; String texto; public void init() { int ancho=250; //valores por defecto int alto=100; x=10; y=20; try{ ancho=Integer.parseInt(this.getParameter("WIDTH")); alto=Integer.parseInt(this.getParameter("HEIGHT")); x=Integer.parseInt(this.getParameter("ABSCISA")); y=Integer.parseInt(this.getParameter("ORDENADA")); }catch(NumberFormatExcept ion ex){ System.out.println("Error en los parmetros"); } texto=this.getParameter("MENSAJE"); this.setSize(ancho,alto); } public void paint(Graphics g){ g.drawString(texto, x, y); } }

124

Programacin en el lenguaje Java

Ahora bien, los valores devueltos por getParameter y despus convertidos se deben de guardar en variables de instancia para que luego puedan ser utilizadas por otras funciones miembro. As, el valor del parmetro ABSCISA se guarda en el miembro dato x, el valor del parmetro ORDENADA en y, y el valor del parmetro MENSAJE en texto. En la redefinicin de paint , se muestra en el contexto grfico g, el contenido del mensaje guardado en texto en la posicin x e y mediante la llamda a la funcin drawString . Se invita al lector a que corra el applet anterior (Applet2). Para ello deber ubicarlo acuerdo a como lo exige la instruccin package . Complelo y luego comprmalo. Para ejecutarlo utilice el archivo .html con la configuracin requerida.

6.2 Dibujando con JAVA 1


Hemos introducido la nocin de contexto grfico, cuando se ha creado el primer applet, que muestra un mensaje. En esta seccin se estudiarn algunas funciones grficas definidas en la clase Graphics, y tres clases que sirven de apoyo para dibujar en el contexto grfico: la clase Col or que describe los colores, la clase Font que nos permite crear fuentes de texto y la clase FontMetrics que nos proporciona sus caractersticas. 6.2.1 El contexto grfico La funcin paint y update nos suministran el contexto grfico del applet o del componente, en otros casos, hemos de obtener el contexto grfico del componente mediante la funcin getGraphics. Una vez obtenido el contexto grfico podemos llamar desde este objeto a las funciones grficas definidas en la clase Graphics. public void paint(Graphics g){ //usar el contexto grfico g } public void update(Graphics g){ //usar el contexto grfico g } void funcion(){ Graphics g=getGraphics(); //usar el contexto grfico g g.dispose(); } Como vemos en estas porciones de cdigo existe una sutil diferencia entre suministrar y obtener el contexto grfico g. Solamente es necesario liberar los recursos asociados al contexto g, mediante la llamada a la funcin dispose, cuando se obtiene el contexto grfico mediante getGraphics. La clase Graphic s es abstracta por lo que no se pueden crear mediante new objetos de esta clase, pero se pueden guardar en una referencia g de la clase Graphics los contextos grficos concretos de los distintos componentes.

125

Programacin en el lenguaje Java

Un contexto grfico es como la hoja en blanco situada en un trazador (plotter). Para dibujar en dicha hoja se toma una pluma, se dibuja, se toma otra pluma de distinto color o grosor, se dibuja otra porcin del grfico, y as sucesivamente. Cuando no se selecciona explcitamente, se dibuja con una pluma que se establece por defecto. Las libreras grficas como la de Windows, disponen de plumas de distinto grosor para dibujar lneas con distintos estilos, brochas para rellenar el interior de una figura cerrada con un color slido, con una determinada trama o figura, y fuentes de texto, para dibujar texto con distintas fuentes y estilos. La librera grfica que viene con la versin 1.1 de Java es muy limitada. No hay objetos pinceles, ni brochas. Las lneas tienen un nico grosor y estilo, solamente se pueden cambiar de color, las figuras cerradas solamente se pueden rellenar con un color slido, y las fuentes de texto disponibles son muy pocas. La clase Graphics describe el contexto grfico y proporciona un conjunto de funciones para dibujar las siguientes figuras Lneas Crculos y elipses Rectngulos y polgones Imgenes Texto El sistema de coordenadas que se usa en Java es similar a Windows. El rea de trabajo del applet est compuesta por una matriz bidimensional de puntos o pixels. Decimos que un punto tiene de coordendas (x, y) cuando est en la columna x medida desde la izquierda, y est en la fila y, medida desde arriba.

La esquina superior izquierda es el origen (0, 0). La esquina inferior derecha viene determinada por las dimensiones del componente. La funcin getSize nos devuelve un objeto de la clase Dimension cuyos miembros width y height nos suministran la anchura y altura del componenete. int ancho=getSize().width; int alto=getSize().heigth; 6.2.2 Funciones grficas No vamos a examinar completamente la clase Graphics , pero si vamos a mostrar mediante un applet el uso de algunas funciones de esta clase. En el captulo dedicado al estudio de los ejemplos completos se representarn diagramas en forma de barras o tarta, y funciones matemticas (Captulo 11). La funcin paint nos va a proporcionar el objeto g de la clase Graphics que denominamos contexto grfico del componente (a pplet). Desde dicho objeto llamaremos a las funciones miembro de la clase Graphics.

126

Programacin en el lenguaje Java

6.2.2.1 Establecer un color El color negro es el color por defecto del contexto grfico. Para establecer otro color , como veremos en la seccin siguiente, se utiliza la funcin setColor , y se le pasa un color predefinido o definido por el usuario. g.setColor(Color.cyan); 6.2.2.2 Dibujar una lnea Para dibujar una lnea recta se llama a la funcin drawLine, le pasamos el punto inicial y el punto final. Para dibujar una lnea diagonal desde el origen (0, 0) o esquina superior izquierda, hasta la esquina inferior derecha, obtenemos las dimensiones del applet mediante la funcin getSize, que devuelve un objeto de la clase Dimension . El miembro width nos sproporciona la anchura y el miembro height la altura. g.drawLine(0, 0, getSize().width-1, getSize().height-1); 6.2.2.3 Dibujar un rectngulo Un rectngulo viene definido por un origen (esquina superior izquierda), su anchura y altura. La siguiente sentencia dibuja un rectngulo cuyo origen es el punto 50, 150, que tiene una anchura de 50, y una altura de 60. La funcin drawRect dibuja el contorno del color seleccionado, y fillRect dibuja el rectngulo pintando su interior del color seleccionado, en este caso de color rojo. g.setColor(Color.red); g.fillRect(50, 150, 50, 60); 6.2.2.4 Dibujar un arco Los elipses (oval), arcos (arc), se dibujan en el interior del rectngulo circundante. Una elipse de dibuja mediante drawOval o fillOval , con los mismos parmetros que el rectngulo. Un arco requiere dos parmetros ms el ngulo inical y el ngulo final. Las sentencias que vienen a continuacin, dibujan un arco en el interior del rectngulo cuyo origen es el punto 10, 10, cuya anchura es 150, y cuya altura es 100. El ngulo inicial es 0 y el ngulo final es 270, expresado en grados. g.setColor(Color.cyan); g.fillArc(10, 10, 150, 100, 0, 270); g.setColor(Color.black); g.drawArc(10, 10, 150, 100, 0, 270); 6.2.2.5 Dibujar un polgono Para dibujar un polgono, se requieren un array de puntos. Un polgono y una polilnea son parecidos, el primero es una figura cerrada mientas que una polilnea es un conjunto de segmentos. Para formar un polgono a partir de una pililnea se une el punto inicial y el punto final. El polgono precisa de un array de abscisas x, un array de ordenadas y, y la dimensin del array. int[] x={100, 150, 170, 190, 200}; int[] y={120, 280, 200, 250, 60}; g.setColor(Color.blue); g.drawPolygon(x, y, x.length);

127

Programacin en el lenguaje Java

Alternativamente, se puede usar un objeto de la clase Polygon , al cual se le aaden puntos mediante la funcin miembro addPoint. Polygon poligono=new Polygon(); poligono.addPoint(100, 120); poligono.addPoint(150, 280); poligono.addPoint(170, 200); poligono.addPoint(190, 250); poligono.addPoint(200, 60); Para dibujar el polgono con su interior pintado del color seleccionado se llama a la funcin fillPolygon y se le pasa el objeto poligono de la clase Polygon . g.setColor(Color.yellow); g.fillPolygon(poligono); Veremos en el applet un polgono cuyo contorno est dibujado en azul y su interior en amarillo. 6.2.2.6 Dibujar una imagen Para dibujar una imagen se requieren dos pasos: Cargar la imagen y crear un objeto de la clase Image Dibujar dicho objeto en el contexto grfico

Para crear una imagen u objeto disco de la clase Image a partir del archivo disco.gif se usa la funcin getImage. Le hemos de indicar la ubicacin de dicho archivo relativa a la pgina web que contiene el applet o al cdigo compilado. En nuestro caso, hemos situado la imagen en el mismo subdirectorio que la pgina web que contiene al applet. El lugar ms adecuado para cargar la imagen es en la funcin init, ya que como se ha mencionado se llama una sola vez. public void init(){ disco=getImage(getDocumentBase(), "disco.gif"); } Para dibujar la imagen en el contexto grfico g, se llama a la funcin drawImage. Hay varias versiones de esta funcin, la ms simple es aquella a la que se le proporciona el objeto disco de la clase Image, las coordenadas de su esquina superior izquierda (250, 50), y el observador, el propio applet o this. g.drawImage(disco, 250, 50, this); Si deseamos obtener las dimensiones del objeto disco de la clase Image, llamamos a dos funciones de esta clase getWidth y getHeight int ancho=disco.getWidth(this); int alto=disco.getHeight(this);

package funciones; import java.awt.*; import java.awt.event.*;

128

Programacin en el lenguaje Java

import java.applet.*; public class FuncionesApplet extends Applet { Image disco; public void init() { this.setSize(400,300); disco=getImage(getDocumentBase(), "disco.gif" ); } public void paint(Graphics g){ g.drawLine(0, 0, getSize().width-1, getSize().height-1); g.setColor(Color.red); g.fillRect(50, 150, 50, 60); g.setColor(Color.cyan); g.fillArc(10, 10, 150, 100, 0, 270); g.setColor(Color.black); g.drawArc(10, 10, 150, 100, 0, 270); Polygon poligono=new Polygon(); poligono.addPoint(100, 120); poligono.addPoint(150, 280); poligono.addPoint(170, 200); poligono.addPoint(190, 250); poligono.addPoint(200, 60); g.setColor(Color.yellow); g.fillPolygon(poligono); int[] x={100, 150, 170, 190, 200}; int[] y={120, 280, 200, 250, 60}; g.setColor(Color.blue); g.drawPolygon(x, y, x.length); g.drawImage(disco, 250, 50, this); } } Se invita al lecto r a que corra el applet anterior (FuncionesApplet). Para ello deber ubicarlo acuerdo a como lo exige la instruccin package. Complelo y luego comprmalo. Para ejecutarlo utilice el archivo .html con la configuracin requerida. 6.2.3 Las clases Color, Font y FontMetrics 6.2.3.1 La clase Color Los colores primarios son el rojo, el verde y el azul. Java utiliza un modelo de color denominado RGB, que significa que cualquier color se puede describir dando las cantidades de rojo (Red), verde (Green), y azul (Blue). Estas cantidades son nmeros enteros comprendidos entre 0 y 255, o bien, nmeros reales comprendidos entre 0.0 y 1.0. La siguiente tabla nos proporciona los colores ms comunes y sus valores RGB. Nombre white lightGray gray Red (rojo) 255 192 128 Green (verde) 255 192 128 Blue (azul) 255 192 128

129

Programacin en el lenguaje Java

drakGray black red pink orange yellow green magenta cyan blue

64 0 255 255 255 255 0 255 0 0

64 0 0 175 200 255 255 0 255 0

64 0 0 175 0 0 0 255 255 255

Para crear un objeto de la clase Color , se pasan tres nmeros a su constructor que indican la cantidad de rojo, verde y azul. Color colorRosa=new Color(255, 175, 175); Mediante la funcin setColor, cambiamos color con el que dibujamos una lnea, un texto o rellenamos una figura cerrada en el contexto grfico g . g.setColor(colorRosa); No es necesario tener a mano la tabla de las componentes RGB de cada color. La clase Color nos proporciona un conjunto de colores predefinidos en forma de miembros estticos de dicha clase. Podemos escribir alternativamente g.setColor(Color.pink); Los colores predefinidos son los siguientes Color.white Color.black Color.lightGray Color.red Color.gray Color.pink Color.blue El color d e fondo del componente se establece con setBackground y se obtiene con getBackground. En el siguiente applet observamos cmo se utiliza esta segunda funcin para crear una diana. En la funcin init establecemos el color de fondo en blanco mediante setBackground. En la funcin miembro paint obtenemos el color de fondo mediante getBackground. Los crculos se pintan de mayor a menor radio. Se pinta un crculo de color rojo y se borra parte de su interior con el color de fondo, de este modo se crea un anillo, luego otro y as scuesivamente, hasta completar cuatro anillos de color rojo con la apariencia de una diana. En el programa, tambin podemos apreciar que la funcin paint suministra el contexto grfico g del componente (applet) en el cual podemos dibujar. El objeto g llama a setColor para establecer el color, y a fillOval para dibujar un crculo pintado de dicho color. Las funcin getSize nos devuelve el tamao del componente (applet), de modo que los dimetros de la elipse mayor son respectivamete la anchura y altura del applet. Color.yellow Color.green Color.magenta

Color.darkGray Color.orange Color.cyan

130

Programacin en el lenguaje Java

package paint1; import java.awt.*; import java.awt.event.*; import java.applet.*; public class PaintApplet extends Applet { public void init(){ setBackground(Color.white); } public void paint(Graphics g) { int x, y, ancho, alto; int appletAlto = getSize().height; int appletAncho = getSize().width; for (int i=8; i>=0; i--) { if ((i % 2)==0) g.setColor(Color.red); else g.setColor(getBackground()); alto = appletAlto*i/8; ancho = applet Ancho*i/8; x=appletAncho/2-i*appletAncho/16; y=appletAlto/2-i*appletAlto/16; g.fillOval(x, y, ancho, alto); } } } Se invita al lector a que corra el applet anterior (PaintApplet). Para ello deber ubicarlo acuerdo a como lo exige la instruccin package. Complelo y luego comprmalo. Para ejecutarlo utilice el archivo .html con la configuracin requerida. 6.2.3 .2 La clase Font Para crear una fuente de texto u objeto de la clase Font llamamos a su constructor, y le pasamos el nombre de la fuente de texto, el estilo y el tamao. Por ejemplo, Font fuente=new Font("TimesRoman", Font.BOLD, 12); Esta sentencia, crea una fuente de texto Times Roman, en letra negrita, de 12 puntos. Los estilos vienen datos por constantes ( miembros estticos de la clase Font), Font.BOLD establece el estilo negrita, Font.ITALIC, el estilo cursiva, y Font.PLAIN, el estilo normal. Se pueden combinar las constantes Font.BOLD+Font.ITALIC para establecer el estilo negrita y cursiva a la vez. La funcin setFont de la clase Graphics establece la fuente de texto en el contexto grfico g. g.setFont(fuente); La funcin getFont obtiene la fuente de texto actual de dicho contexto grfico. La funcin drawString dibuja el string guardado en el objeto texto de la clase String, y lo sita en la posicin cuyas coordenadas vienen dadas por los dos nmeros enteros que le siguen.

131

Programacin en el lenguaje Java

En la siguiente porcin de cdigo, establecemos una fuente de texto, dibujamos el texto, y reestablecemos la fuente de texto por defecto, una operacin habitual que se realiza al programar un applet. Font oldFont=getFont(); Font fuente=new Font("Monospaced", Font.BOLD, 36); g.setFont(fuente); g.drawString(texto, 100, 50); g.setFont(oldFont); g.drawString(otroTexto, 100, 70); Para obtener el nombre de las fuentes de texto disponibles se escribe el siguiente cdigo String[] nombreFuentes=getToolkit().getFontList(); for(int i=0; i<nombreFuentes.length; i++){ System.out.println(nombreFuentes[i]); }

6.2.3 .3 La clase FontMetrics La clase FontMetrics nos permite conocer las caractersticas de una fuente de texto. Desde el contexto grfico g, llamamos a la funcin getFontMetrics para obtener un objeto f m de la clase FontMetrics que nos describe las caractersticas de una fuente determinada o de la fuente actualmente seleccionada. En el primer caso escribimos Font fuente=new Font("Dialog", Font.BOLD, 36); FontMetrics fm=g.getFontMetrics(fuente); En el segundo caso, escribimos Font fuente=new Font("Courier", Font.BOLD, 36); g.setFont(fuente); FontMetrics fm=g.getFontMetrics(); En el applet mostramos las caractersticas de una fuente de texto: Ascent es la distancia entre lnea horizontal de color azul (baseline) y la lnea horizontal de color rojo. Descent es la distancia entre la lnea h orizontal de color azul (baseline) y la lnea horizontal de color verde. Leading sera la distancia entre las lnea de color verde (descent) y la lnea roja (ascent) de la siguiente lnea de texto.. Para obtener la altura de una fuente de texto, llamamos a la funcin getHeight miembro de FontMetrics. La altura de una fuente de texto, es la distancia entre dos lneas base (baseline) consecutivas, y es la suma de el ascent, descent y leading. Tres funciones que comienzan por get devuelven los valores de

132

Programacin en el lenguaje Java

estos tres atributos de una fuente de texto: getAscent, getDescent, y getLeading . Para escribir dos lneas de texto, una debajo de otra escribimos FontMetrics fm=g.getFontMetrics(); String texto="La cigea vendr"; g.drawString(texto, 10, 50); int hFont=fm.getHeight(); texto=new String("ser en primavera"); g.drawString(texto, 10, 50+hFont); La primera lnea de texto, se sita en el punto (10, 50), la ordenada 50, seala la posicin vertical de la lnea base de la fuente de texto, vase la figura. La segunda lnea de texto tiene una lnea base cuya posicin vertical se obtiene sumando a 50 la altura hFont de la fuente de texto. Otro valor interesante, es la anchura de un texto, que se obtiene mediante la funcin miembro stringWidth, y se le pasa el texto. Por ejemplo, para centrar horizontalmente un texto en el applet escribimos. String texto="La cigea vendr"; int ancho=fm.stringWidth(texto); g.drawString(texto, (anchoApplet -ancho)/2, 50); La funcin getSize().width obtiene la anchura del componente (applet), y la variable ancho , guarda la anchura del string texto. Un poco ms difcil es centrar un texto verticalmente, en una determinada posicin. Teniendo en cuanta, que las coordendas que se le pasan a la funcin drawString se refieren a la lnea base del primer carcter, tal como se ve en la figura. La frmula de centrado vertical en un punto de ordenada y sera: la ordenda y de la lnea base menos descent ms la mitad de la altura de los caracteres hFont. Se ha de tener en cuenta que la ordenada y aumenta de arriba hacia abajo. g.drawLine(0, y, anchoApplet, y); g.setColor(Color.red); texto="Centrado: a, p, , , "; g.drawString(texto, 10, y+hFont/2-descent);

Como los caracteres pueden estar o no acentuados, escritos en maysculas o minsculas, etc, la frmula para mostrar un texto centrado verticamente no es nica, se sugiere probar estas dos dadas por otros autores g.drawString(texto, 10, y+ascent/4);
g.drawString(texto, 10, y-hFont/2+ascent); El cdigo completo de este ejemplo es, el siguiente package fonts2; import java.awt.*;

133

Programacin en el lenguaje Java

import java.applet.*; public class FontApplet2 extends Applet { public void init() { setBackground(Color.white); } public void paint(Graphics g){ int anchoApplet=getSize().width; Font oldFont=getFont(); Font fuente=new Font("Monospaced", Font.BOLD, 36); g.setFont(fuente); FontMetrics fm=g.getFontMetrics(); String texto="La cigea vendr"; int ancho=fm.stringWidth(texto); int y=50; g.drawString(texto, (anchoApplet-ancho)/2, y); texto=new String("ser en primavera"); ancho=fm.stringWidth(texto); //caractersticas de las fuentes de texto int hFont=fm.getHeight(); int ascent=fm.getAscent(); int descent=fm.getDescent(); int leading=fm.getLeading(); g.drawString(texto, (anchoApplet-ancho)/2, y+hFont); //dibuja lnea base g.setColor(Color.blue); g.drawLine(0, y, getSize().width, y); g.drawLine(0, y+hFont, anchoApplet, y+hFont); //dibuja ascent g.setColor(Color.red); g.drawLine(0, y- ascent, anchoApplet, y-ascent); g.drawLine(getSize().width/2, y+hFont-ascent, anchoApplet, y+hFontascent); //dibuja descent g.setColor(Color.green); g.drawLine(0, y+descent, anchoApplet/2, y+descent); g.drawLine(0, y+hFont+descent, anchoApplet, y+hFont+descent); //texto centrado verticalmente en la posicin y y+=2*hFont; g.setColor(Color.black); g.drawLine(0, y, anchoApplet, y); g.setColor(Color.red); texto="Centrado: a, p, , 5, "; g.drawString(texto, 10, y+hFont/2-descent); //Escribe tres lneas de texto en la fuente de texto por defecto. g.setFont(oldFont); fm=g.getFontMetrics(); hFont=fm.getHeight(); y+=3*hFont; g.setColor(Color.black); texto="leading ="+leading; g.dra wString(texto, 10, y); texto="ascent ="+ascent; y+=hFont;

134

Programacin en el lenguaje Java

g.drawString(texto, 10, y); texto="descent ="+descent; y+=hFont; g.drawString(texto, 10, y); texto="altura=ascent+descent+leading= "+(ascent+descent+leading); y+=hFont; g.drawString(texto, 10, y); } } Se invita al lector a que corra el applet anterior (FonttApplet2). Para ello deber ubicarlo acuerdo a como lo exige la instruccin package. Complelo y luego comprmalo. Para ejecutarlo utilice el archivo .html con la configuracin requerida.

6.2.4 Objetos Propios Dibujables :


Nosotros podremos construir nuestros propios objetos de tal forma que se puedan dibujar. Por ejemplo, podramos disponer de un kit que contenga: poleas, resortes, dinammetros, relojes, voltmetros, etc. Con el fin de realizar desarrollos ordenados y escalables, lo mejor sera ubicar el kit en un paquete. En los ejemplos que vamos a tratar ubicaremos en el paquete dos clases que nos proporcionaran objetos dibujables : Resorte.java (nos proporciona resortes) y Flecha.java (que nos proporciona vectores). Al paquete lo denominaremos: org.opensourcephysics.unal 6.2.4.1 Pasando el contexto grfico del applet a nuestros objetos dibujables Una forma de lograr construir objetos propios dibujables, es proveerlos de un mtodo dibujar(Graphics g) , que cuando sea invocado, por ejemplo, por un applet, recoja el contexto grfico g de ste y se dibuje sobre l devolviendo luego el contexto al invocador. A continuacin damos dos clases que generan objetos pensados as: resortes y flechas. La clase resorte: /*Autor: Diego Aristizbal*/ package org.opensourcephysics.unal; import java.awt.*;

public

class

Resorte

private int X1, Y1, X2, Y2, a, largo, N, n; private double alfa ; private double[] exes ;

135

Programacin en el lenguaje Java

private private private private

int[] exesint; double[] eyes; int[] eyesint; Color c=Color.yellow;

// Constructor /**(X1,Y1) coordenadas de un extremo del resorte *(X2,Y2) coordenadas del otro extremo del resorte *ancho es el radio de las espiras *Espiras es el nmero de espiras */ public Resorte(int X1,int Y1,int X2,int Y2,int a,int N){ //ancho Espiras this.X1=X1; this.Y1=Y1; this.X2=X2; this.Y2=Y2; this.a=a; this.N=N; calculo(); } /** Recibe el color con el cual se debe dibujar el resorte*/ public void setColorResorte(Color c){ this.c=c; } /**Mtodo que realiza los clculos para dibujar el resorte con //base en los parmetros dados */ private void calculo(){ //Decide que valor le da al ngulo respecto a la horizontal

if ((X1-X2) = 0 ) //valor diferente a 90 {alfa = Math.atan(-(1.0*(Y2-Y1))/(1.0*(X1-X2)));} else //valor igual a 90 {alfa=((Math.PI)/2.0);} //Calcula la longitud del resorte double l=0.5D*(Math.sqrt((Y1-Y2)*(Y1 -Y2)+(X1 -X2)*(X1 -X2))); //calcula el nmero de vtices que tiene la figura que va a //generar el resorte n = 2*N + 1; double h = Math.sqrt((a*a) + ((0.5*l)/N)*((0.5*l)/N));

136

Programacin en el lenguaje Java

//clculos adicionales para lograr saber la ubicacin de los //vtices que generan el resorte //que sern los arreglos exes y eyes double beta = Math.asin(a/h); double gama1 =(Math.PI/2)- ((alfa)+beta ); double gama2 =(Math.PI/2) ((alfa) -beta ); exes =new double[n+2]; eyes =new double[n+2]; exesint =new int[n+2]; eyesint =new int[n+2]; exes[0]=(X1) ; exes[1]=( X1 + 10*Math.cos(alfa)) ; exes[2]=( exes[1] + h*Math.sin(gama1)) ; eyes[0]=(Y1) ; eyes[1]=( Y1 + 10*Math.sin(alfa)); eyes[2]=( eyes[1] + h*Math.cos(gama1));

for (int i=4 ;i<=n-1; i++) {

if (I % 2 == 0) { exes[i-1]=( exes[i-2]+2*h*Math.sin(gama2)) ; eyes[i-1]=(eyes[i-2]+2*h*Math.cos(gama2)) ; } else { exes[i-1]=(exes[ i-2] +2*h*Math.sin(gama1)) ; eyes[i-1]=(eyes[i-2]+2*h*Math.cos(gama1)) ; }

}//fin for

if ((n) % 2 == 0){ exes[n-1]=( exes[n-2]+h*Math.sin(gama2)) ; eyes[n-1]=( eyes[n-2]+h*Math.cos(gama2)) ; } else{ exes[n-1]=( exes[n-2]+h*Math.sin(gama1)) ; eyes[n-1]=( eyes[n-2]+h*Math.cos(gama1)) ; } exes[n]=X2; eyes[n]=Y2; //convierte los arreglos de doubles a arreglos de int for (int i=0;i<n+1;i++){ double d1= exes[i]; double d2= eyes[i]; exesint[i]=(int)(d1);

137

Programacin en el lenguaje Java

eyesint[i]=(int)(d2); } }//fin calculo //Metodo que recoge el contexto grfico del contenedor donde se //dibuja (por ejemplo un applet) public void dibujar (Graphics g){ //Obtiene el color actual de los objetos que se estn //dibujando en el contenedor de dibujo (por ejemplo applet Color c1=g.getColor(); //Asigna el color con que se va a dibujar el resorte g.setColor; //Dibuja el resorte g.drawPolyline(exesint,eyesint, n+1); //Devuelve el color con que se estaban dibujando lo s objetos //en el contenedor antes de que Resorte se apoderara del //contexto grfico g.setColor(c1); }//Fin Dibujese }//fin de la clase Resorte La clase Flecha:

/* * Copyright (c) 200 2 Diego Aristizbal R */ package org.opensourcephysics.unal; import java.awt.*; public class Flecha extends Canvas{ private int x1,y1,x2,y2; private Color c= Color.black;; private Graphics g; //constructor /** (x1,y1)coordenadas de un extremo de la flecha * (x2,y2) coordenadas del otro extremo de la flecha */

public Flecha( int x1,int y1,int x2,int y2){ this.x1=x1; this.y1=y1; this.x2=x2;

138

Programacin en el lenguaje Java

this.y2=y2; } /**recibe el color con el cual se dibujar la flecha*/ public void setColorFlecha(Color c){ this.c=c; }

private void dibuja_flecha( int x1, int y1, int x2, int y2) { //asegura que las vraiables loclales x1,y1,x2,y2 //sean las mismas que las variables de instancia //x1,y1,x2,y2 this.x1=x1; this.y1=y1; this.x2=x2; this.y2=y2; //dibuja la lnea de la flecha Linea( x1, y1, x2, y2); //realiza clculos necesarios para lograr obtener //los vrtices de las lneas que dibujarn //la cabeza de la flecha double d = 0.20000000000000001D; double d1 = 10D; double d2 = x2 - x1; double d3 = y1 - y2;

//dibuja la cabezaCabeza if(d2 * d2 + d3 * d3 <= 16D) { return; } else { //clculos adicionales para obtener vrtices de los //segmentos de la cabeza double d4 = Math.atan2(d3, d2); x1 = (int)(((double)x2 - d1 * Math.cos(d4 + d)) + 0.5D); y1 = (int)((double)y2 + d1 * Math.sin(d4 + d) + 0.5D); //dibuja un segemento de la cabeza Linea( x1, y1, x2, y2); x1 = (int)(((double)x2 - d1 * Math.cos(d4 - d)) + 0.5D); y1 = (int)((double)y2 + d1 * Math.sin(d4 - d) + 0.5D); //dibuja el otro segmento de la cabeza Linea( x1, y1, x2, y2); return; }

139

Programacin en el lenguaje Java

private void Linea( int x1, int y1, int x2, int y2) { g.drawLine(x1, y1, x2, y2);

public void dibujar(Graphics g){ //asegura que el contexto grafico g sea el mismo //en toda esta clase this.g=g; //Obtiene el color actual de los objetos que se estan estn //dibujando en el contenedor (por ejemplo el applet) Color c1 = g.getColor(); //Asigna el color con que se dibujar la flecha g.setColor(c); dibuja_flecha( x1, y1, x2,y2); //regresa el color con que se estaban dibujando los //objetos en el contenedor (por ejemplo el applet) g.setColor(c1);

}//Fin dibujar }//Fin flecha 6.2.4.2 Cmo usar nuestros objetos dibujables? La recomendacin es hacer un paquete con ellos. Por ejemplo, la clase Resorte y la clase Flecha las hemos colocado en el paquete, org.opensourcephysics.unal;

Si nuestro directorio de desarrollo est en c \>mis_proyectos, entonces las clases se debern ubicar en el siguiente subdirectori o, tal y como lo indica el nombre del paquete: C\>mis_proyectos\>org\>opensourcephysics\>unal\>

Para usar las clases deber importar el paquete: import org.opensourcephysics.unal; Se sugiere al lector corra el siguiente applet siguiendo estos consejos : import java.awt.event.*; import java.applet.*; import org.opensourcephysics.unal.* ;

140

Programacin en el lenguaje Java

public class ObjetosDibujablesPropios Applet extends Applet { public void init() { setBackground(Color.white); } public void paint(Graphics g){ //crea un objeto resorte Resorte r=new Resorte (20,50,200,100,10,8); //le asigna el color al resorte r.setColorResorte(Color.red); //dibuja el resorte pasando el contexto grfico //desde este applet al objeto resorte r.dibujar(g); //crea un objeto flecha Flecha f= new Flecha(100,100,200,200); //le asigna el color a la flecha f.setColorFlecha(new Color(180,250,90)); //dibuja el resorte pasando el contexto grfico //desde este applet al objeto flecha f.dibujar(g); }

6.3 Dibujando con JAVA 2


Una de las mejoras ofrecidas con Java 2 es Java 2D, un conjunto de clases para ofrecer grficos de alta calidad, imgenes y texto es los programas. Las clases Java2D amplan las capacidades de las clases java.awt existentes que manejan grficos, como los que usted ha aprendido hasta ahora. No reemplazan las clases existentes, de modo que usted puede seguir usando estas clases y programas que las implementan. El API 2D de Java nos permite fcilmente: Dibujar lneas de cualquier anchura Rellenar formas con gradientes y texturas Mover, rotar, escalar y recortar texto y grficos. Componer texto y grficos solapados.

Por ejemplo, podramos usar el API 2D de Java para mostrar grficos y charts complejos que usan varios estilos de lnea y de relleno para distinguir conjuntos de datos, como se muestra en la siguiente figura:

El API 2D de Java tambin nos permite a lmacenar datos de imgenes. Por ejemplo, podemos realizar fcilmente filtros de imgenes, como blur o recortado, como se muestra en la siguiente figura:

141

Programacin en el lenguaje Java

Recome ndamos al lector que profundice su conocimiento en esta EXCELENTE API en alguna de las siguientes direcci ones: http://java.sun.com/products/jdk/1.2/docs/guide/2d/spec/j2d-title.fm.html http://www.programacion.com/tutorial.2d.html En esta seccin nos limit aremos a indicar los usos bsicos.

6.3.1 Funciones grficas


6.3.1.1 Renderizado en Java 2D El mecanismo de renderizado bsico es el mismo que en las versiones anteriores del JDK : el sistema de dibujo controla cundo y cmo dibuja un programa. Cuando un componente necesita ser mostrado, se llama automticamente a su mtodo paint o update dentro del contexto Graphics apropiado. El API 2D de Java presenta java.awt.Graphics2D , un nuevo tipo de objeto Graphics. Graphics2D desciende de la clase Graphics para proporcionar acceso a las caractersticas avanzadas de renderizado del API 2D de Java. Para usar las caractersticas del API 2D de Java, tenemos que forzar el objeto Graphics pasado al mtodo de dibujo de un componente a un objeto Graphics2D. Esto lo hacemos mediante un casting: public void Paint (Graphics g) { Graphics2D g2 = (Graphics2D) g; ... } 6.3.1.2 Contexto de Renderizado de Graphics2D Al conjunto de atributos de estado asociados con un objeto Graphics2D se le conoce como Contexto de Renderizado de Graphics2D . Para mostrar texto, formas o imgenes, podemos configurar este contexto y luego llamar a uno de los mtodos de renderizado de la clase Graphics2D, como draw o fill . Cmo describimos a continuacin, el contexto de renderizado de Graphics2D contiene varios atributos:

El estilo de lpiz que se aplica al exterior de una forma. Este atributo stroke nos permite dibujar lneas con cualquier tamao de punto y patrn de sombreado y aplicar finalizadores y decoraciones a la lnea.

142

Programacin en el lenguaje Java

El estilo de relleno que se aplica al interior de la forma. Este atributo paint nos permite rellenar formas con colores slidos, gradientes o patrones.

El estilo de composicin se utiliza cuando los objetos dibujados se solapan con objetos existentes.

La transformacin que se aplica durante el dibujado para convertir el objeto dibujado desde el espacio de usuario a las coordenadas de espacio del dispositivo. Tambin se pueden aplicar otras transformaciones opcionales como la translacin, rotacin escalado, recortado, a travs de este atributo.

El Clip que restringe el dibujado al rea dentro de los bordes de la Shape se utiliza para definir el re a de recorte. Se puede usar cualquier Shape para definir un clip.

La fuente se usa para convertir cadenas de texto.

Punto de Renderizado que especifican las preferencias en cuanto a velocidad y calidad. Por ejemplo, podemos especificar si se debera usar antialiasing, si est disponible.

Para configurar un atributo en el contexto de renderizado de Graphics2D, se usan los mtodos setAttribute. setStroke setPaint setComposite setTransform setClip setFont setRenderingHints

Cuando configuramos un atributo, se le pasa al objeto el atributo apropiado. Por ejemplo, para cambiar el atributo paint a un relleno de gradiente azul-gris, deberamos construir el objeto GradientPaint y luego llamar a set Paint. gp = new GradientPaint(0f,0f,blue,0f,30f,green);

143

Programacin en el lenguaje Java

g2.setPaint(gp); Graphics2D contiene referencias a sus objetos atributos: no son clonados. Si modificamos un objeto atributo que forma parte del contexto Graphics2D, necesitamos llamar al mtodo set para notificarlo al contexto. La modificacin de un atributo de un objeto durante el renderizado puede causar comportamientos impredecibles. 6.3.1.3 Mtodos de renderizado de Graphics2D Graphics2D proporciona los siguientes mtodos generales de dibujado que pueden usarse para dibujar cualquier primitivo geomtrico, texto o imagen. Draw.: dibuja el exterior de una forma geomtrica primitiva usando los atributos stroke y paint. Fill: dibuja cualquier forma geomtrica primitiva rellenado su interior con el color o patrn especificado por el atributo paint. drawString: dibuja cualquier cadena de texto. El atributo font se usa para convertir la fuente a glyphs que luego se rellenan con el color o patrn especificados por el atributo paint. drawImage: dibuja la imagen especificada.

Adems, Graphics2D soporta los mtodos de renderizado de Graphics para formas particulares, como drawOval y fillRect.

6.3.1.4 Espacios de coordenadas Uno de los conceptos introducidos con Java2D es la diferencia entre un espacio de coordenadas de un dispositivo de salida y el espacio de coordenadas al que uno se refiere cuando dibujamos un objeto. Para todas las operaciones de dibujo que hemos realizado hasta aqu y todas las operaciones previas a Java 2, el nico espacio de coordenadas que se us fue el del espacio de coordenadas de dispositivo. Especificamos las coordenadas (x,y) de una superficie de salida como una ventana de un applet y las coordenadas que se usaron para dibujar lneas, textos y otros elementos. Java2D presenta otro espacio de coordenadas al que uno se refiere cuando se cree un objeto y realmente se dibuje. Este se le denomina espacio de coordenadas de usuario . Antes de que cualquier dibujo de 2D haya ocurrido en un programa, el espacio de dispositvo y el espacio de usuario tienen la coordenada (0,0) en el mismo lugar: la esquina superior izquierda del rea de dibujo. La coordenada (0,0) del espacio del usuario se puede mover como resultado de las operaciones de dibujo de 2D que se llevan a cabo. Incluso los ej es x,y se pueden rotar. Resumiendo: e l sistema 2D de Java mantiene dos espacios de coordenadas: El espacio de usuario es el espacio en que se especifican los grficos primitivos. El espacio de dispositivo es el sistema de coordenadas para un diopositivo de salida, como una pantalla, una ventana o una impresora.

144

Programacin en el lenguaje Java

El espacio de usuario es un sistema de coordenadas lgicas independiente del dispositivo: el espacio de coordenas que usan nuestros programas. Todos los objetos geomtricos pasados a las rutinas Java 2D de renderizado se especifican en coordenadas de espacio de usuario. Cuando se utiliza la transformacin por defecto desde el espacio de usuario al espacio de dispositivo, el origen del espacio de usuario es la esquina superior izquierda del rea de dibujo del componente. La coordenada x se incrementa hacia la derecha, y la coordenada y hacia abajo. El espacio de dispositivo es un sistema de coordenadas dependiente del dispositivo que vara de acuerdo a la fuente del dispositivo. Aunque el siste ma de coordenadas para una ventana o una pantalla podra ser muy distinto que para una impresora, estas diferencias son invisibles para los programas Java. Las conversiones necesarias entre el espacio de usuario y el espacio de dispositivo se realizan automticamente durante el dibujado.
6.3.1.5 Formas 2D

Las clases del paquete java.awt.geom definen grficos primitivos comunes, como puntos, lneas, curvas, arcos, rectngulos y elipses. Clases en el paquete java.awt.geom Arc2D Area Ellipse2D QuadCurve2D RectangularShape RoundRectangle2D

GeneralPath Rectangle2D

CubicCurve2D Line2D Dimension2D Point2D

Excepto para Point2D y Dimension2D , cada una de las otras clases geomtricas implementa el interface Shape , que proporciona un conjunto de mtodos comunes para describir e inspeccionar objetos geomtricos bi-dimensionales. Con estas clases podemos crear de forma virtual cualquier forma geomtrica y dibujarla a travs de Graphics2D llamando al mtodo draw o al mtodo fill. Por ejemplo, las formas geomtricas del siguiente applet (ShapesDemo2D) estn definidas usando los objetos geomtricos bsicos de Java 2D.

A continuacin se lista el cdigo del applet ShapesDemo2D.java.

145

Programacin en el lenguaje Java

/* * 1.2 version. */ import import import import java.awt.*; java.awt.event.*; java.awt.geom.*; javax.swing.*;

public class ShapesDemo2D extends JApplet { public void init() { //Initialize drawing colors setBackground(Color.white); setForeground(Color.black); } public void paint(Graphics g) { //Contexto grfico Graphics2D g2 = (Graphics2D) g; //Mejora la calidad del dibujo g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //Rectngulos 3D g2.setPaint(Color.red); g2.draw3DRect(10, 10, 40,30, true); g2.setPaint(Color.blue); g2.draw3DRect(60,10, 40,30, false); //Cadenas con tipo de letra por defecto g2.setPaint(Color.black); g2.drawString("Rectngulos 3D",10 ,60); //Line2D.Double g2.setPaint(Color.black); g2.draw(new Line2D.Double(120,10, 180 , 30)); //Cadenas con tipo de letra definido Font letra_1= new Font("NewTimes",Font.PLAIN,10); g2.setFont(letra_1); g2.drawString("Lnea2D",120 ,60); //Bug //Rectangle2D.Double g2.setPaint(new Color(200,150,250)); g2.draw(new Rectangle2D.Double(220, 10, 40, 30)); //Rectangle2D.Double cambiando el ancho de la lnea BasicStroke stroke = new BasicStroke(2.0f);

146

Programacin en el lenguaje Java

g2.setStroke(stroke); g2.draw(new Rectangle2D.Double(280, 10, 40, 30)); //Rectangle2D.Double con otro trazo BasicStroke dashed = new BasicStroke(4.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND); g2.setStroke(dashed); g2.draw(new Rectangle2D.Double(340, 10, 40, 30)); //Dibujar Arco g2.setPaint(Color.red); BasicStroke wideStroke = new BasicStroke(6.0f); g2.setStroke(wideStroke); g2.draw(new Arc2D.Double(10,80,40,40, 90, 135, Arc2D.OPEN)); //Dibujar elipse g2.setStroke(stroke); g2.draw(new Ellipse2D.Double(60,80,60,40)); //Dibujar polgono GeneralPath (polygon) int x1Points[] = {120,180, 120, 180}; int y1Points[] = {80, 140, 140, 80}; GeneralPath polygon = new GeneralPath ( GeneralPath.WIND_EVEN_ODD, x1Points.length); polygon.moveTo(x1Points[0], y1Points[0]); for ( int index = 1; index < x1Points.length; index++ ) { polygon.lineTo(x1Points[index], y1Points[index]); }; polygon.closePath(); g2.draw(polygon); // Dibujar lnea poligonal GeneralPath (polyline) int x2Points[] = {220, 280, 220, 280}; int y2Points[] = {80, 140, 140, 80}; GeneralPath polyline = new GeneralPath( GeneralPath.WIND_EVEN_ODD, x2Points.length); polyline.moveTo (x2Points[0], y2Points[0]); for ( int index = 1; index < x2Points.length; index++ ) { polyline.lineTo(x2Points[index], y2Points[index]); }; g2.draw(polyline); // Rectngulo relleno: fill Rectangle2D.Double (red) g2.fill(new Rectangle2D.Double(340, 80, 60, 40)); // Arco relleno: fill Arc2D g2.fill(new Arc2D.Double(10, 140, 60, 60, 90, 135, Arc2D.OPEN)); // Elipse rellena con color gradiente

147

Programacin en el lenguaje Java

GradientPaint redtowhite = new GradientPaint(120,160, Color.blue,180, 160,Color.white); g2.setPaint(r edtowhite); g2.fill (new Ellipse2D.Double(120, 160, 60,40)); } } Se recomienda al lector correr el applet y construir ms figuras consultando la API de Java 2. Las dimensiones del applet son width=500 heigth=200

6.3.2 Transformaciones afines


Las transformaciones afines es una herramienta muy potente que incorporo Java2D para manipular objetos tales como puntos, figuras geomtricas (shapes) y texto . Una transformacin afn es una transformacin en la cual las lneas paralelas continan siendo paralelas an despus de la transformacin. Dos ejemplos de tales transformaciones (escritas en forma matricial) son la rotacin en un ngulo ,

x y = 1
y la traslacin en una cantidad

cos sen 0

sen cos 0

0 0 1

x y 1 b
en la direccin y:

en la direccin x y

x y = 1

1 0 a x 0 1 b y 0 0 1 1

La transformacin afn ms general es una combinacin de un escalado, una traslacin, y una rotacin. Esta puede ser escrita as:

x y = 1

m00 m 10 0

m01 m02 m11 m12 0 1

x y 1

Esta transformacin es creada en Java2D usando el constructor AffineTransform: AffineTransform t = new AffineTransform(double m00,double m10,double m01, double m11, double m02, double m12) ; Hay mtodos que implementan las rotaciones y traslaciones puras.

148

Programacin en el lenguaje Java

6.3.2.1 Formas de implementar las transformaciones afnes: Podemos modificar el atributo transform en el contexto Graphics2D para mover, rotar, escalar y modificar grficos primitivos mientras son dibujados. El atributo transform est definido por una instancia de AffineTransform. Graphics2D proporciona varios mtodos para cambiar el atributo transform . Podemos construir un nuevo AffineTransform y cambiar el atributo transform de Graphics2D llamando al mtodo setTransform. AffineTransform define los siguientes mtodos para hacer ms sencilla la construccin de nuevas transformaciones: getRotateInstance getScaleInstance getShearInstance getTranslateInstance

De forma alternativa podemos usar uno de los mtodos de transformaci n de Graphics2D para modificar la transformacin actual. Cuando se llama a uno de esos mtodos de conveniencia, la transformacin resultante se concatena con la transformacin actual y es aplicada durante el dibujado. r otate: para especificar un ngulo de rotacin en radianes. scale: para especificar un factor de escala en direcciones x e y. shear : para especificar un factor de comparticin en direcciones x e y translate: para especificar un desplazamiento de movimiento en direcciones x e y

Tambin po demos construir directamente un AffineTransform y concatenarlo con la transformacin actual llamando al mtodo transform . El mtodo drawImage tambin est sobrecargado para permitirnos especificar un AffineTransform que es aplicado a la imagen a dibujar. Especificar un transform cuando se llama a drawImage no afecta al atributo transform de Graphics2D. 6.3.2.2 Ejemplos Los dos programas que se listan a continuacin ilustran diferentes formas de implementar las transformaciones afines . El lector deber co rrerlos y hacerles variaciones para practicar. Ambos applets tiene como dimensiones width=500 height=400: import import import import java.awt.*; java.awt.event.*; java.awt.geom.*; javax.swing.*;

public class AffineTransformApplet extends JApplet {

public void init() { //Initialize drawing colors setBackground(Color.white);

149

Programacin en el lenguaje Java

setForeground(Color.black); }

public void paint(Graphics g) { //Contexto grfico Graphics2D g2 = (Graphics2D) g; //Mejora la calidad del dibujo g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

//Mtodo 1: Creando una transformacin afn //Traslacin del origen al punto (100,0) y rotacin de 45 alrededor de el AffineTransform t_1=new AffineTransform(); Shape rectangulo_1=new Rectangle2D.Double(0, 0, 150, 100); g2.setPaint(Color.red); t_1.translate(100.0,0.0); t_1.rotate(Math.PI/4); g2.setTransform(t_1); g2.draw(rectangulo_1);

//Traslacin del origen al punto (100,100) y rotacin de 45 alrededor de el AffineTransform t_2=new AffineTransform(); Shape rectangulo_2= (new Rectangle2D.Double(0, 0, 150, 100)); g2.setPaint(new Color(0,128,0)); t_2.translate(100.0,200.0); t_2.rotate(Math.PI/4); g2.setTransform(t_2); g2.draw(rectangulo_2); g2.fill(rectangulo_2); //Rotacin alrededor de 60 del punto (100,100) AffineTransform t_3=new AffineTransform(); Shape rectangulo_3= (new Rectangle2D.Double(0, 0, 150, 100)); g2.setPaint(Color.green); t_3.rotate(Math.PI/3,100.0,200.0); g2.setTransform(t_3); g2.draw(rectangulo_3);

//Traslacin del origen al punto (250,200)y rotacin alrededor de el de -60 double teta=-Math.PI/3; AffineTransform t_4= new AffineTransform(Math.cos(teta),Math.sin(teta), Math.sin(teta),Math.cos(teta),250.0,200.0); Shape rectangulo_4= (new Rectangle2D.Double(0, 0, 150, 100)); g2.setPaint(Color.black); g2.setTransform(t_4);

150

Programacin en el lenguaje Java

g2.draw(rectangulo_4); //Transformacin sobre una cadena AffineTransform t_5=new AffineTransform(); t_5.rotate(Math.PI/3,100.0,100.0); g2.setPaint(Color.magenta); g2.setTransform(t_5); g2.setFont(new Font("SanSerif",Font.BOLD,40)); g2.drawString("Fsica",350,0);

} }

import import import import

java.awt.*; java.awt.event.*; java.awt.geom.*; javax.swing.*;

public class AffineTransform1Applet extends JApplet {

public void init() { //Initialize drawing colors setBackground(Color.white); setForeground(Color.black); }

public void paint(Graphics g) { //Contexto grfico Graphics2D g2 = (Graphics2D) g; //Mejora la calidad del dibujo g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

//Metodo 2 : Actuando directamente sobre el objeto Graphics2D. //Hace las operaciones respecto al estado actual de Graphics2D Shape rectangulo_1=new Rectangle2D.Double(0, 0, 150, 100); g2.translate(250,200); g2.setPaint(new Color(0,128,0)); g2.draw(rectangulo_1); //rotacin de 45 Shape rectangulo_2=new Rectangle2D.Double(0, 0, 150, 100); g2.rotate(Math.PI/4); g2.setPaint(Color.green); g2.draw(rectangulo_2);

151

Programacin en el lenguaje Java

//escalar Shape rectangulo_3=new Rectangle2D.Double(0, 0, 150, 100); g2.scale(0.5,0.5); g2.setPaint(Color.blue); g2.draw(rectangulo_3); //Estiramiento g2.shear(2.5,1.5); g2.setPaint(Color.red); g2.draw(rectangulo_1); //Transformacn sobre cadenas g2.shear(2.5,3.5); g2.setFont(new Font("SanSerif",Font.BOLD,20)); g2.drawString("Fsica",-40,20);

} }

6.3.3 Objetos Propios Dibujables :

Aplazado 6.4 Implementacin de una interfaz: Dibujable:


En este caso primero debemos organizar la interfaz . El cdigo que proponemos es el siguiente: public interface Dibujable { public void dibujar(PanelDibujo, Graphics g); }

Aplazado 6.5 Dibujando con JAVA 3D


El API Java 3D es un interface para escribir programas que muestran e interactan con grficos tridimensionales. Java 3D es una extensin estndard del JDK 2 de Java. El API Java 3D proporciona una coleccin de constructores de alto-nivel para crear y manipular geometras 3D y estructuras para dibujar esta geometra. Java 3D proporciona las funciones para creacin de imgenes, visualizaciones, animaciones y programas de aplicaciones grficas 3D interactivas.

152

Programacin en el lenguaje Java

6.5.1 Qu es el API 3D de Java?


El API 3D de Java es un rbol de clases Java que sirven como interface para sistemas de renderizado de grficos tridimensionales y un sistema de sonido. El programador trabaja con constructores de alto nivel para crear y manipular objetos geomtricos en 3D. Estos objetos geomtricos residen en un universo virtual, que luego es renderizado. El API est diseado con flexibilidad para crear universos virtuales precisos de una amplia variedad de tamaos, desde astronmicos a subatmicos. A pesar de toda esta funcionalidad, el API es sencillo de usar. Los detalles de renderizado se manejan automticamente. Aprovechndose de los Threads Java, el renderizador Java 3D es capaz de renderizar en paralelo. El renderizador tambin puede optimizarse automticamente para mejorar el rendimiento del renderizado. Un programa Java 3D crea ejemplares (instancias) de objetos Java 3D y los sita en un estructura de datos de escenario grfico. Este escenario grfico es una composicin de objetos 3D en una estructura de rbol que especifica completamente el contenido de un universo virtual, y cmo va a ser renderizado. Los programas Java 3D pueden escribirse para ser ejecutados como aplicaciones solitarias o como applets en navegadores que hayan sido extendidos para soportar Java 3D, o ambos.

6.5.2 Qu Software se Necesita?


Te aconsejo que te de s una vuelta por la Home Page de Java 3D en Sun: http://java.sun.com/products/java-media/3d El desarrollo de programas empleando la API Java 3D desborda el objetivo de este curso. Si el lector desea entrar a estudiar esta API, le recomiendo el siguiente sitio web: http://www.programacion.com/java/tutorial.php?id=3d En las figuras siguientes se ilustran dif erentes aplicaciones de Java 3D Visualizaci n astronmica:

153

Programacin en el lenguaje Java

Software Educativo:

Publicidad:

154

Programacin en el lenguaje Java

Visualizaci n de datos:

Diseo:

6.6 Cmo convertir un applet en una aplicacin?


Es posible hacer que un programa en java tenga doble comportamiento: sea un applet y a la vez una aplicacin. Esto se logra agregando unas pocas lneas. A continuacin ilustramos un applet que cumple con este propsito. Se recomienda al lector que lo ejecute tanto como aplicacin que como applet. Como applet tiene las siguientes dimensiones: width=350 heght=200.

import import import import

java.awt.*; java.awt.event.*; java.awt.geom.*; javax.swing.*;

155

Programacin en el lenguaje Java

public class AppletAplicacion extends JApplet {

public void init() { //Initialize drawing colors setBackground(Color.yellow); setForeground(Color.black); }

public void paint(Graphics g) { //Contexto grfico Graphics2D g2 = (Graphics2D) g; //Mejora la calidad del dibujo g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

//Transformacn sobre cadenas g2.rotate(Math.PI/6); g2.setFont(new Font("SanSerif",Font.BOLD,20)); g2.drawString("Fsica Computacional",40,20);

} //Este mtodo esttico hace que el applet se pueda ejecutar como una aplicacin public static void main(String[] args) { JApplet applet = new AppletAplicacion(); JFrame f = new JFrame("Aplicacin y Applet"); //evento de cerrar ventana: se ver ms adelante f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); f.getContentPane().add(applet, BorderLayout.CENTER); f.setSize(new Dimension(350, 200)); f.setVisible(true); }

156

Potrebbero piacerti anche