Você está na página 1de 21

Instituto Tecnolgico Metropolitano

Programacin en Java Parte 2: Uso de la POO y las interfaces grficas bsicas


Objetivo General Aplicar el estilo de la programacin orientada a objetos a los programas en Java y aprovechar el uso de la interfaces grficas para hacer programas ms amigables.

Introduccin La clase es el ncleo de Java. Es la construccin lgica sobre la que se construye el lenguaje Java, ya que define la forma y la naturaleza de un objeto. La clase constituye la base de la programacin orientada a objetos en Java. Cualquier concepto que se desee implementar en un programa Java debe ser encapsulado en una clase. TEMA 1 La POO en Java En los programas realizados hasta el momento se han utilizado clases, pero de la manera ms simple: Una clase que encapsula al mtodo main(), lo que ha permitido ilustrar las bases de la sintaxis de Java. Pero las clases son ms poderosas de lo visto hasta ahora. Lo ms importante acerca de una clase es que define un nuevo tipo de dato. Una vez definido, este nuevo tipo de dato se puede utilizar para crear objetos de ese tipo. Una clase es una plantilla para un objeto y un objeto es una instancia de una clase. Clases Cuando se define una clase, se declara su forma y naturaleza exacta. Esto se hace especificando los datos que contiene la clase y el cdigo que opera sobre ellos. Una clase se declara utilizando la palabra clave class. Una clase tiene la siguiente forma: Class NombreClase { tipo variable1; tipo variable2; ... tipo variableN; tipo metodo1(listaParametros){ ... } tipo metodo2(listaParametros){ ... } ... tipo metodoN(listaParametros){ ... } } Las variable definidas en una clase se llaman variables de instancia. Los subprogramas se denominan mtodos. Para objetos de una clase es necesario realizar dos pasos: Declarar una variable del tipo de la clase. La variable no define un objeto, sino una referencia a l. 1

Instituto Tecnolgico Metropolitano

Obtener una copia fsica y real objeto y asignarla a la variable. Para ello se utiliza el operador new. Este operador asigna dinmicamente en tiempo de ejecucin, memoria para un objeto y devuelve una referencia a este.

Por ejemplo, cuando decidimos utilizar la clase InputStreamReader, las instruccin fue: InputStreamReader isr=new InputStreamReader(System.in); La cual se puede dividir as InputStreamReader isr; //Se declara la referencia al objeto isr=new InputStreamReader(System.in); //Reserva espacio para el objeto Mtodos Java le da mucho poder y flexibilidad a los mtodos. Una de las caractersticas es que pueden devolver un tipo especfico de dato o de clase. Si no devuelve ningn valor el tipo devuelto debe ser void. La lista de parmetros es una secuencia de parejas de tipo e identificador separadas por coma. Los parmetros son variables que reciben el valor de los argumentos que se pasan al mtodo. Si el mtodo no tiene parmetros, entonces la lista estar vaca. Cuando el mtodo devuelve un tipo distinto de void, deben retornar un valor utilizando la instruccin return: return valor; Los mtodos definen la interfaz de la mayora de las clases. Esto permite que la clase oculte sus estructuras de datos internas detrs de un conjunto de mtodos. Adems de definir mtodo que proporcionan acceso a los datos, tambin pueden definirse mtodos que sern utilizados internamente por la propia clase. Un programa ejemplo: Rescribiendo una aplicacin utilizando POO El cdigo de la derecha permite calcular valor de una cuota en una deuda con base en el valor de prstamo, la tasa de inters y el nmero de perodos. (Fue descrito con anterioridad). En l se observa que no slo se atiende el problema del clculo de los resultados sino tambin de la entrada de datos. Esto dificulta un poco entender el programa. Aplicando la POO se podra pensar en dividir el problema en dos: La entrada de datos por consola El calculo del valor de la cuota. Para ello sera conveniente definir dos clases: Una que contenga los mtodos para la lectura de variables, no slo de valores reales, sino tambin de enteros y cadenas (para poder reutilizarla despus en otro programa). Una que contenga el mtodo principal, donde se calcule el valor de la cuota.
import java.io.*; public class Cuota{ public static void main(String args[]){ InputStreamReader isr=new InputStreamReader(System.in); BufferedReader br=new BufferedReader(isr); String texto; double p,i,n,a; System.out.println("Calculo del valor de una cuota:"); try{ System.out.print("Valor del Prstamo? "); texto=br.readLine(); Double d1=new Double(texto); p=d1.doubleValue(); System.out.print("Inters por perodo? "); texto=br.readLine(); Double d2=new Double(texto); i=d2.doubleValue()/100; System.out.print("Perodos? "); texto=br.readLine(); Double d3=new Double(texto); n=d3.doubleValue(); double factor=Math.pow(1+i,n); a=p*(factor*i)/(factor-1); System.out.print("Valor Cuota="+a); } catch (Exception e) { System.out.println("Error "+e); } }

} El cdigo para la primer clase sera: 2

Instituto Tecnolgico Metropolitano


import java.io.*; class LeerVariable{ InputStreamReader isr=new InputStreamReader(System.in); BufferedReader br=new BufferedReader(isr); public int leerEntero(String mensaje){ int num=0; try{ System.out.print(mensaje); num=Integer.parseInt(br.readLine()); } catch (Exception e) { System.out.println("Error "+e); } return num; } public double leerReal(String mensaje){ double num=0; try{ System.out.print(mensaje); Double d=Inew Double(br.readLine()); num=d.doubleValue(); } catch (Exception e) { System.out.println("Error "+e); } return num; } } y el cdigo para la segunda: public class Cuota{ public static void main(String args[]){ System.out.println("Calculo del valor de una cuota:"); LeerVariable lv=new LeerVariable(); double p=lv.leerReal("Valor del Prstamo? "); double i=lv.leerReal("Inters por perodo? ")/100; double n=lv.leerReal("Perodos? "); double factor=Math.pow(1+i,n); double a=p*(factor*i)/(factor-1); System.out.print("Valor Cuota="+a); } } Cmo se podr observar, se simplifica mucho el cdigo para la segunda clase, y la primera clase puede ser reutilizada en otras aplicaciones. La Herencia La herencia es una de las piedras angulares de la POO ya que permite la creacin de clasificaciones jerrquicas. Gracias a la herencia se puede definir una clase general que define caractersticas comunes a un conjunto de elementos relacionados. En la terminologa Java, a la clase general se le llama superclase y a las clases ms especficas que heredan de la general se les llama subclases. Una subclase es una versin especializada de una 3

Instituto Tecnolgico Metropolitano


superclase, que hereda todas las variables de instancia y los mtodos definidos por la superclase y que aade sus propios elementos. La forma general de la declaracin de una clase que hereda de otra es la siguiente: Class nombreSubClase extends nombreSuperClase { } Una subclase no puede acceder a aquellos miembros de la superclase que han sido declarados como private. Un programa ejemplo: Uso de la herencia Se requiere una aplicacin que permita crear objetos crculo y cilindro para calcular las magnitudes correspondientes a cada uno de ellos, tales como rea, permetro y volumen. Se requiere por tanto, disear la jerarqua de clases Crculo y Cilindro. En esencia se puede decir que un objeto de la clase cilindro se compone de un objeto de la clase crculo y una altura.

Las magnitudes se calcularan as: Permetro = 2 r rea = r Volumen = r h La clase Circulo la definiramos as: class Circulo { double radio; public double perimetro(){ return 2*Math.PI*radio; } public double area(){ return Math.PI*Math.pow(radio,2); } } La clase Cilindro heredara la clase Circulo y quedara as: class Cilindro extends Circulo { double altura; public double volumen(){ return altura*area(); } } Observe como para calcular el volumen se utiliza el mtodo area() como si estuviera en la propia clase. El siguiente sera el cdigo para calcular el volumen de un cilindro, leyendo su altura y radio: public class PruebaCilindro{ public static void main(String args[]){ 4

Instituto Tecnolgico Metropolitano


LeerVariable lv=new LeerVariable(); Cilindro c=new Cilindro(); c.radio=lv.leerReal("radio?"); c.altura=lv.leerReal("altura?"); System.out.println("Volumen cilindro:"+c.volumen()); } } Esta aplicacin instancia un objeto de la clase LeerVariable la cual ha sido previamente compilada y est en la misma carpeta, as como un objeto de la clase Cilindro. La Sobrecarga de constructores En java es posible definir dos o ms mtodos dentro de la misma clase que tengan el mismo nombre, pero con su lista de parmetros distintas. Cuando ocurre esto, se dice que los mtodos estn sobrecargados. La sobrecarga es lo que utiliza Java para implementar el polimorfismo. Cuando se invoca un mtodo sobrecargado, Java utiliza el tipo y nmero de argumentos como gua para determinar la versin del mtodo sobrecargado. Por eso, los mtodos sobrecargados deben diferenciarse en el tipo y nmero de parmetros. Adems de sobrecargar los mtodos, tambin se pueden sobrecargar los constructores. Los constructores son mtodos especiales que permiten que los objetos se inicialicen cuando son creados. Tienen el mismo nombre que la clase en que reside. Una vez definido, se llama automticamente al constructor despus de crear el objeto, antes de que termine el operador new. Los constructores parecen un poco extraos porque no devuelven ningn tipo, ni siquiera void. Esto se debe a que el tipo implcito que devuelve un constructor de clase es el propio tipo de la clase. Podemos aplicar la sobrecarga de constructores para redefinir la manera como podemos instanciar los objetos de la clase Cilindro. En el siguiente cdigo la clase Circulo contiene dos constructores para la instancia de los objetos. En el primero pide un argumento para inicializar el radio y en el segundo no pide ningn parmetro e inicializa el radio en 0. class Circulo { double radio; public double perimetro(){ return 2*Math.PI*radio; } public double area(){ return Math.PI*Math.pow(radio,2); } Circulo(double r){ radio=r; } Circulo(){ radio=0; } } Aplicamos lo mismo a la clase Cilindro: Un constructor que pide argumentos para inicializar el radio y la altura, y otro constructor que no pide argumentos y los inicializa en 0. class Cilindro extends Circulo { double altura; public double volumen(){ 5

Instituto Tecnolgico Metropolitano


return altura*area(); } Cilindro(double r,double h){ radio=r; altura=h; } Cilindro(){ radio=0; altura=0; } } Una aplicacin que instancie objetos de estas dos clases podra ser: public class Prueba{ public static void main(String args[]){ LeerVariable lv=new LeerVariable(); Cilindro cil=new Cilindro(5,4); System.out.println("Volumen cilindro:"+cil.volumen()); Circulo cir=new Circulo(); cir.altura=lv.leerReal("radio?"); System.out.println("Area circulo:"+cir.area()); } } En este ejemplo se define un objeto de la clase Cilindro con radio=5 y altura=4 y se le calcula el volumen. Se instancia adems un objeto de la clase Circulo a la cual se le lee el radio y se le calcula el rea. TEMA 2 Applets Un Applet, como su nombre lo indica, es una especie de miniaplicacin, diseada para ser ejecutada mediante un navegador del Web. Las applets se diferencian de las aplicaciones regulares en numerosas formas. Una de las ms imprtantes es que los applet tienen restricciones de seguridad sobre lo que est permitido realizar. A menudo, un applet consiste de un cdigo poco fiable, por lo que se les impide tener acceso al sistema de archivo local. Todas las applets son subclases de Applet, por lo que deben importar el paquete java.applet. Adems, las applets tienen que importar java.awt. AWT es un conjunto de herramientas para disear interfaces grficas de usuario. Como todas las applets se ejecutan sobre una ventana, es necesario incluir el soporte para trabajar con esa ventana. Las applets no son ejecutadas por el intrprete de Java a travs de una consola, sino que son ejecutadas por un navegador compatible con Java o por un visualizador de applets. Para un programador, una de las diferencias ms grandes entre los applets y las aplicaciones es que los primeros no tienen mtodo main() u otro simple punto de entrada desde el cual comience a ejecutarse. En vez de eso, para escribir un applet, se hace una subclase de la clase Applet y anula los mtodos estndares. Ahora bien, la tarea de escribir un applet se reduce a definir los mtodos apropiados. Veamos: Mtodo void init() void destroy void start() void stop() Descripcin Este mtodo se ejecuta cuando una applet comienza su ejecucin. Es el primer mtodo que se ejecuta en una applet. Es llamado cuando el applet est a punto de ser descargadp del navegador. Este debe liberar cualquier recurso o memoria que el applet tenga asignado Es llamado cuando al applet se vuelve visible y debe comenzar a hacer lo que debe. A menudo se usa con la animacin y con los hilos. Es llamado cuando el applet se vuelve temporalmente invisible, por ejemplo, cuando el usuario lo ha arrastrado fuera de la pantalla. Le ordena al applet detener la ejecucin de 6

Instituto Tecnolgico Metropolitano


una animacin o cualquier otra tarea. Aparte de estos mtodos, hay otros heredados de las superclases de Applet, que el navegador invoca en el momento apropiado y que un applet debe invalidar. El ms conocido es paint(), al que el navegador invoca para pedirle al applet que se dibuje a si mismo en la pantalla. La clase Applet tambin define algunos mtodos comnmente usados por los applet: Mtodo Image getImage() AudioClip getAudioClip() String[] getParameter() URL getCodeBase() URL getDocumentBase() void showStatus() Descripcin Carga un archivo de imagen desde la estacin de trabajo y devuelve un objeto Image. Carga un sonido desde la estacin de trabajo y devuelve un objeto AudioClip. Localiza y devuelve el valor de un parmetro nombrado, especificado en el archivo HTML que hace referencia al applet con la etiqueta <PARAM>. Devuelve el URL base, desde el cual el archivo de clase applet fue cargado. Devuelve el URL base del archivo HTML que hace referencia al applet. Muestra un mensaje en la lnea de estado del navegador.

Un ejemplo sencillo de applet sera: import java.applet.*; import java.awt.*; public class AppletHola extends Applet { public void paint(Graphics g){ g.drawString("Hola",10,20); } } Este ejemplo utiliza el mtodo paint(), invocado por el navegador del Web cuando el applet necesita ser dibujado. Este mtodo ejecuta una salida grfica, que en este caso es el texto hola. paint() utiliza un argumento que es un objeto de la clase Graphics. La clase Graphics es todo lo que se necesita para dibujar en Java. Para desplegar el applet , se necesita un archivo HTML que le haga referencia. <html> <head> <title>Applet</title> </head> <body> <applet code=AppletHola.class width=200 height=100> </applet> </body> </html> La etiqueta utilizada es la <APPLET></APPLET> la cual pide 3 parmetros: El nombre del archivo compilado (*.class) El ancho del rea de despliegue (WIDTH) El alto del rea de despliegue (HEIGHT) En el navegador, as se vera el applet:

Instituto Tecnolgico Metropolitano

Mtodos grficos bsicos Como se mencion anteriormente, un applet utiliza el mtodo drawString(), que es miembro de la clase Graphics. Normalmente este mtodo se utiliza en los mtodos update() y paint() del applet y tiene la siguiente sintaxis: public void drawString(String mensaje, int x, int y) Para darle color al fondo del applet se utiliza el mtodo setBakcground(), mientras que setForeGround() permite asignarle color al texto y a las lneas. La clase Color define las siguientes constantes para especificar colores: Color.black Color.blue Color.cyan Color.darkGray Color.gray Color.green Color.lightGray Color.magenta Color.orange Color.pink Color.red Color.white Color.yellow Las siguientes instrucciones asignan un fondo de color cyan y el texto de color azul. setBackGround(Color.cyan); setForeGround(Color.blue); Para obtener los colores actuales, se utilizan los mtodos getBackGround() y getForeGround(). Cuando un applet necesita actualizar la informacin mostrada en su ventana, se utiliza el mtodo repaint(). Cuando se necesita mostrar un mensaje, un applet puede utilizar la barra de estado del navegador mediante una llamada al mtodo showStatus Para el trazado de figuras geomtricas se tienen los siguientes mtodos: Mtodo Descripcin void drawLine(int x1, int y1, int x2, int y2) Dibuja una lnea desde las coordenadas x1,y1 hasta x2,y2 void drawRect(int x1, int y1, int ancho, int alto) Dibuja un rectngulo desde las coordenadas x1,y1 con un ancho y un alto especficos. void drawRoundRect(int x1, int y1, int ancho, int Dibuja un rectngulo redondeado desde las alto, int xDiametro, int yDiametro) coordenadas x1,y1 con un ancho y un alto especficos, y los dimetros de los arcos de las esquinas xDiametro y yDiametro. void fillRect(int x1, int y1, int ancho, int alto) Rellena un rectngulo desde las coordenadas x1,y1 con un ancho y un alto especficos. 8

Instituto Tecnolgico Metropolitano


void fillRoundRect(int x1, int y1, int ancho, int Rellana un rectngulo redondeado desde las alto, int xDiametro, int yDiametro) coordenadas x1,y1 con un ancho y un alto especficos, y los dimetros de los arcos de las esquinas xDiametro y yDiametro. void drawOval(int x, int y, int ancho, int alto) Dibuja la elipse comprendida por el rectngulo que va desde las coordenadas x1,y1 con un ancho y un alto especficos. void fillOval(int x, int y, int ancho, int alto) Rellena la elipse comprendida por el rectngulo que va desde las coordenadas x1,y1 con un ancho y un alto especficos. void drawArc(int x1, int y1, int ancho, int alto, Dibuja el arco comprendido por el rectngulo que va int anguloInicial, int anguloBarrido) desde las coordenadas x1,y1 con un ancho y un alto especficos. El arco comienza en un anguloInicial y recorre la distancia dada por anguloBarrido. void fillArc(int x1, int y1, int ancho, int alto, int Rellena el arco comprendido por el rectngulo que va anguloInicial, int anguloBarrido) desde las coordenadas x1,y1 con un ancho y un alto especficos. El arco comienza en un anguloInicial y recorre la distancia dada por anguloBarrido. void drawPolygon(int x[], int y[], int puntos) Dibuja el polgono definido por los vrtices correspondientes a los vectores x[] y y[], con un total de vrtices definido por puntos. void fillPolygon(int x[], int y[], int puntos) Rellena el polgono definido por los vrtices correspondientes a los vectores x[] y y[], con un total de vrtices definido por puntos. Para ajustar el tamao de un grfico al tamao actual del applet, se utilizan los mtodos getWidth() y getHeight() para consultar el ancho y el alto del applet respectivamente y hacer los clculos necesarios. Un applet de ejemplo: Grfica de una funcin A continuacin emplearemos un applet para graficar una funcin matemtica. Una funcin matemtica permite calcular un valor como resultado de aplicar una expresin a una variable. Por ejemplo, dada la funcin f(x)=x3, para cada valor de x, donde x es un nmero real, f(x) corresponde al valor de x elevado al cubo. Con base en esto, se puede obtener la siguiente tabla:
X f(x) -10 100 -9 81 -8 64 -7 49 -6 36 -5 25 -4 16 -3 9 -2 4 -1 1 0 0 1 1 2 4 3 9 4 16 5 25 6 36 7 49 8 64 9 81 10 100

Esta tabla permite definir una grfica en un plano cartesiano de dos ejes, uno para los valores de la variable x (horizontal) y otro para los valores de la funcin (vertical). La grfica se realiza trazando lneas entre dos puntos cada uno correspondiente a la pareja compuesta por un valor de la variable y el respectivo valor de la funcin (x, f(x)). Por ejemplo: Punto 1=(-10,-100) al Punto 2=(-9,-81) Punto 2=(-9,-81) al Punto 2=(-8,-64)

Instituto Tecnolgico Metropolitano


Se va a implementar entonces un applet que grafique la funcin f(x)=x3. Para ello se debe tener en cuenta que las coordenadas para graficar la funcin no corresponden a las coordenadas utilizadas para hacer trazos en el applet, por lo que hay que hacer los respectivos clculos para hacer la adaptacin.

Estos clculos comprenden el manejo de las siguientes variables: xi: Valor inicial de x. Corresponde al pixel 0

xf: Valor final de x. Corresponde al pixel del tamao del applet dado por getWidth(). yi: Valor mximo de la funcin. Corresponde al pixel 0 yf: Valor mnimo de la funcin. Corresponde al pixel del tamao del applet dado por getHeight(). dx: Valor de incremento de x para un pixel. Equivalente a (xf xi)/getWidth(). dy: Valor de incremento de la funcin para un pixel. Equivalente a (yi yf)/getHeight()

Para un valor de x determinado, el pixel correspondiente sera: (x xi)/dx Para un valor de y determinado, el pixel correspondiente sera: (yi - y)/dx La grfica de la funcin se har trazando pequeas lneas con una distancia horizontal de slo 1 pixel lo cual dar el efecto de curva de la funcin. Para ello se calculan dos valores de la variable x contiguos (con una diferencia de dx) y sus respectivos valores f(x) y se traza una lnea. Seguido, se traza la lnea siguiente y as sucesivamente de izquierda a derecha hasta llegar al ltimo pxel que corresponde al valor xf. El siguiente cdigo resuelve el problema: import java.awt.*; import java.applet.*; public class Funcion extends Applet { float f(float x) { Float f=new Float(Math.pow(x,3)); return f.floatValue(); } public void paint(Graphics g) { g.setColor(Color.blue); //Lmites de X float xi=-10;float xf=10; //Incremento de X por pixel float dx=(xf-xi)/getSize().width; 10

Instituto Tecnolgico Metropolitano


//Mximo y mnimo de Y float yi=f(xi);float yf=f(xi); float x=xi; while(x<=xf) { if(f(x)>yi) yi=f(x); if(f(x)<yf) yf=f(x); x+=dx; } //Incremento de Y por Pixel float dy=(yi-yf)/getSize().height; //Eje Vertical int px; if((xi<=0)&&(0<=xf)) { px=Math.round(-xi/dx); g.drawLine(px, 0, px, getSize().height); } //Eje Horizontal int py; if((yf<=0)&&(0<=yi)) { py=Math.round(yi/dy); g.drawLine(0, py, getSize().width,py); } //Hallar punto inicial g.setColor(Color.red); float x1=xi; float y1=f(x1); int py1=Math.round((yi-y1)/dy); float x2,y2; int py2; for (px=0 ; px<getSize().width ; px++) { //Hallar punto final x2=x1+dx; y2=f(x2); py2=Math.round((yi-y2)/dy); g.drawLine(px, py1, px+1, py2); //Siguiente lnea x1=x2; y1=y2; py1=py2; } } } En el cdigo se trazan adems las lneas correspondientes a los ejes horizontal (cuando y=0) y vertical (cuando x=0) La ejecucin en un navegador se vera as:

11

Instituto Tecnolgico Metropolitano

Imgenes Una imagen es bsicamente un objeto grfico rectangular. Inicialmente las grficas aceptadas en el Web eran en formato GIF que fue creado por Compuserve en 1987 para hacer posible que las imgenes se viesen mientras cargaban pero slo podan tener hasta 256 colores. Luego apareci el formato JEPG el cual fue creado por un grupo experto en fotografas para almacenar imgenes en color real. El formato JEPG tiene un mayor grado de compresin pero no soporta transparencia ni animacin. Cuando se trabaja con imgenes, se pueden realizar las siguientes operaciones: Mtodo Descripcin Image getImage(URL url, String archivoImagen) Carga la imagen desde fuentes externas. boolean drawImage(Image objetoImagen, int x, int y, Muestra una imagen cargada. Es un mtodo de ImageObserver objetoImagen) la clase Graphics. El objeto de la clase ImafeObserver generalmente es null. Image createImage(ImageProducer generadorImagen) Crea una imagen a partir de un generador de imgenes, como por ejemplo FilteredImageSource, la cual es una clase que permite filtrar imgenes. El siguiente ejemplo permite mostrar la imagen de un dibujo tridimensional del relieve de la ciudad de Medlln almacenado en el archivo Medelln.jpg: import java.applet.*; import java.awt.*; public class ImagenMedellin extends Applet{ Image imagen; public void init() { imagen=getImage(getDocumentBase(),"Medellin.jpg"); } public void paint(Graphics g) { 12

Instituto Tecnolgico Metropolitano


g.drawImage(imagen,0,0,null); } } En un navegador lo veramos as:

Recorte de imgenes Basado en el trabajo con imgenes, es posible realizar applets que muestren una secuencia de imgenes para generar una animacin. Las tramas de la animacin se obtienen de una nica imagen que se puede dividir en una especie de rejilla utilizando coordenadas.

La clase CropImageFilter filter filtra una imagen origen para extraer una regin rectangular, lo cual es til cuando se desean utilizar varias imgenes pequeas obtenidas a partir de una imagen origen ms grande. Cargar 20 imgenes de 2K es mucho ms lento que cargar un nico archivo de 40K. Para que se efecte el filtrado de la imagen se requiere un objeto de la clase FilteredImageSource la cual es una subclase de ImageProducer que es una interfaz que genera datos de imagen. 13

Instituto Tecnolgico Metropolitano


La clase CropImageFilter es una subclase de ImageFilter y sus mtodos se usan para la comunicacin entre el filtro y su FilteredImageSource, y nunca se deben llamar directamente. Un filtrado sencillo de imagen sera:

El cdigo en Java es el siguiente: import java.applet.*; import java.awt.*; import java.awt.image.*; public class RecorteImagen extends Applet { Image imagen, imagenFiltrada; public void init() { imagen=getImage(getDocumentBase(),"Monalisa.jpg"); CropImageFilter cif=new CropImageFilter(0,0,50,50); FilteredImageSource fis=new FilteredImageSource(imagen.getSource(),cif); imagenFiltrada=createImage(fis); } public void paint(Graphics g) { g.drawImage(imagenFiltrada,0,0,null); } public void update(Graphics g) { paint(g); } } Cuya ejecucin se vera as:

14

Instituto Tecnolgico Metropolitano

Hilos Un programa multihilo contiene dos o ms partes que pueden ejecutarse de forma concurrente. Cada parte de ese programa se llama hilo (Thread) y cada hilo establece un camino de ejecucin independiente. Es un tipo de multitarea distinta a la multitarea por procesos, la cual ejecuta varios programas a la vez. En Java, es un solo programa con varios hilos a la vez. La programacin multihilo permite escribir programas muy eficientes que utilizan al mximo la CPU, reduciendo al mnimo el tiempo que est libre. Esto es importante en los entornos interactivos y en red en los que se trabaja con Java. Los hilos en Java son algo comn. Dado que Java hace tan sencillo emplear los hilos, las bibliotecas de clase de Java requieren su uso en cierto nmero de casos. Por ejemplo, todo applet que ejecute animacin lo logra mediante un hilo. En un entorno de programacin de un hilo nico, cuando el hilo se bloquea, deteniendo la ejecucin porque est esperando algn recurso, detiene por completo el programa. En el entorno de programacin multihilo de Java, un hilo puede detenerse sin parar las otras partes del programa. Por ejemplo, el tiempo que queda libre cuando un hilo lee datos de una red o espera datos de entrada de un usuario, se puede utilizar en cualquier otra parte. Cuando un hilo se bloquea en un programa Java, slo ese hilo se detiene y todos los dems continan su ejecucin. Los hilos pueden estar en distintos estados. Un hilo puede estar ejecutndose. Tambin puede estar preparado para ejecutarse tan pronto como disponga de tiempo de CPU. Un hilo que est ejecutndose puede suspenderse, lo que equivale a detener temporalmente su actividad. El hilo suspendido puede reanudarse permitiendo que continue su tarea all donde la dej. Un hilo puede estar bloqueado cuando espera un recurso. En cualquier momento, un hilo puede detenerse, finalizando su ejecucin de manera inmediata. Una vez detenido, un hilo no puede reanudarse. El intrprete de Java utiliza prioridades para determinar como debe tratar cada hilo con respecto a los dems. Es un valor entero que se utiliza para decidir cundo se pasa a ejecutar otro hilo, lo cual se conoce como cambio de contexto. Un hilo puede ceder el control voluntariamente al bloquearse o en espera de una E/S pendiente. La CPU ejecuta a continuacin, el hilo que tenga mayor prioridad y est preparado para ejecucin. Un hilo tambin puede ser desalojado por otro de mayor prioridad.

15

Instituto Tecnolgico Metropolitano


Debido a que los hilos permiten y potencian el comportamiento asncrono de los programas, debe existir alguna manera de forzar el sincronismo all donde sea necesario. Por ejemplo, si se desea que dos hilos se comuniquen para compartir una estructura de datos, necesitar alguna manera de garantizar que no exista conflicto entre dichos hilos, es decir, es necesario evitar que un hilo escriba datos mientras el otro est leyndolos. Una vez que el programa se ha dividido en hilos, es preciso definir cmo se comunicarn entre s dichos hilos. Java proporciona un sistema de mensajes que permite que un hilo entre en un mtodo sincronizado de un objeto y espere ah hasta que otro hilo le notifique explcitamente que debe salir de ah. El sistema multihilo de Java est construido en torno a la clase Thread, sus mtodos y su interfaz de apoyo Runnable. La clase Thread involucra la nocin hilo de ejecucin. Para crear un hilo, se debe transferir un objeto Runnable (esto es, un objeto que instrumenta la interfaz Runnable al definir un mtodo run()) al constructor Thread para que defina su propio mtodo run(). El mtodo run() del Thread o el objeto Runnable especificados es el cuerpo del hilo. Empieza a ejecutarse cuando se llama al mtodo start() del objeto Thread. El hilo funciona hasta que regresa el mtodo run() o hasta que se llama al mtodo stop() del objeto Thread. Los mtodos estticos de esta clase operan sobre el hilo que funciona en ese momento. Pueden llamarse mtodos de una instancia de un hilo para que operen en un hilo diferente. Mtodo void start() voif stop() void suspend() void resume() void sleep(long milesimas) void yield() void join() void interrupt() boolean isAlive() int getPriority String getName Descripcin Inicia el funcionamiento del hilo. Detiene el hilo al activar un error Thread Death. Detiene temporalmente un hilo. Reanuda un hilo suspendido. Hace que el hilo se detenga durante una cantidad de tiempo. Hace que el hilo actual entregue el control a otros hilos de igual prioridad en espera de ejecutarse. Espera que se extinga un hilo. Activa un hilo en espera o inactivo. Determina si un hilo est ejecutndose todava. Obtiene la prioridad del hilo. Obtiene el nombre del hilo

Al comenzar la ejecucin de un programa en Java, ya hay un hilo ejecutndose. Es el llamado hilo principal del programa. Este es muy importante porque es el hilo a partir del cual se crean el resto de hilos y debe ser el ltimo que termine su ejecucin. Aunque el hilo principal se crea automticamente cuando comienza el programa, se puede controlar a travs de un objeto Thread. Para hacer esto, es necesario obtener una referencia a l, llamando al mtodo currentThread(). El cdigo que aparece a continuacin permite simular el funcionamiento de un reloj de manecillas. Para ello se realiza la grfica del reloj compuesta de: circunferencia, nmeros y manecillas. Esta grfica se debe estar actualizando constantemente para brindar el efecto del desplazamiento de las manecillas. Esto se logra redibujando el applet en instantes de tiempo cortos, para lo cual se utiliza un hilo que se encargar de hacer las pausas. Este hilo har referencia al hilo principal. import java.util.*; import java.awt.*; import java.applet.*; import java.text.*; public class Reloj extends Applet implements Runnable 16

Instituto Tecnolgico Metropolitano


{ /* Un objeto Runnable es requerido para crear un hilo a travs del mtodo run() el cual se convierte en el 'cuerpo' del hilo. El hilo comienza a ejecutarse cuando se llama el mtodo start() del objeto Thread */ Thread reloj; int ultxs, ultys, ultxm, ultym, ultxh, ultyh; // Dimensiones ltimas manecillas Color colorManecilla,colorNumero; //Colores para los elementos del reloj public void init() { ultxs = ultys = ultxm = ultym = ultxh = ultyh = 0; colorManecilla=Color.blue; colorNumero = Color.red; } public void paint(Graphics g) { int radio=50; // radio de la circuferencia del reloj // Dimensiones actuales manecillas int xh, yh, xm, ym, xs, ys, s = 0, m = 0, h = 0, xcentro, ycentro ; // Obtiene la fecha del sistema Date fecha = new Date(); // Obtiene el valor de los segundos aplicndole un formato de fecha slo con segundos SimpleDateFormat formatofecha = new SimpleDateFormat("s",Locale.getDefault()); try {s=Integer.parseInt(formatofecha.format(fecha));} catch (NumberFormatException n) {s=0;} // Obtiene el valor de los minutos aplicndole un formato de fecha slo con minutos formatofecha.applyPattern("m"); try {m=Integer.parseInt(formatofecha.format(fecha));} catch (NumberFormatException n) {m=0;} // Obtiene el valor de las horas aplicndole un formato de fecha slo con horas formatofecha.applyPattern("h"); try {h=Integer.parseInt(formatofecha.format(fecha));} catch (NumberFormatException n) {h=0;} xcentro=radio+10; ycentro=radio+10; // Halla las coordenadas correspondientes a las lneas de las manecillas del reloj xs = (int)(Math.cos(s * 3.14f/30 - 3.14f/2) * (radio-5) + xcentro); ys = (int)(Math.sin(s * 3.14f/30 - 3.14f/2) * (radio-5) + ycentro); xm = (int)(Math.cos(m * 3.14f/30 - 3.14f/2) * (radio-10) + xcentro); ym = (int)(Math.sin(m * 3.14f/30 - 3.14f/2) * (radio-10) + ycentro); xh = (int)(Math.cos((h*30 + m/2) * 3.14f/180 - 3.14f/2) * (radio-20) + xcentro); yh = (int)(Math.sin((h*30 + m/2) * 3.14f/180 - 3.14f/2) * (radio-20) + ycentro); // Dibuja el crculo y los nmeros 17

Instituto Tecnolgico Metropolitano


g.setColor(colorManecilla); g.drawOval(xcentro-radio,ycentro-radio,2*radio,2*radio); g.setColor(colorNumero); g.drawString("9",xcentro-(radio-5),ycentro+3); g.drawString("3",xcentro+(radio-10),ycentro+3); g.drawString("12",xcentro-5,ycentro-(radio-13)); g.drawString("6",xcentro-3,ycentro+(radio-5)); // Borra las anteriores lneas si es necesario y dibuja las nuevas. g.setColor(getBackground()); // Obtener color del fondo // dibujar la anterior lnea del segundero si es necesario if (xs != ultxs || ys != ultys) { g.drawLine(xcentro, ycentro, ultxs, ultys); } // dibujar la anterior lnea del minutero si es necesario if (xm != ultxm || ym != ultym) { g.drawLine(xcentro, ycentro-1, ultxm, ultym); g.drawLine(xcentro-1, ycentro, ultxm, ultym); } // dibujar la anterior lnea del horario si es necesario if (xh != ultxh || yh != ultyh) { g.drawLine(xcentro, ycentro-1, ultxh, ultyh); g.drawLine(xcentro-1, ycentro, ultxh, ultyh); } // dibujar la nueva lnea del segundero g.setColor(colorManecilla); g.drawLine(xcentro, ycentro, xs, ys); // dibujar la nueva lnea del minutero g.drawLine(xcentro, ycentro-1, xm, ym); g.drawLine(xcentro-1, ycentro, xm, ym); // dibujar la nueva lnea del horario g.drawLine(xcentro, ycentro-1, xh, yh); g.drawLine(xcentro-1, ycentro, xh, yh); //Conservar las ltimas coordenadas ultxs=xs; ultys=ys; ultxm=xm; ultym=ym; ultxh=xh; ultyh=yh; fecha=null; } public void start() { // Crea un hilo para la ejecucin del reloj reloj = new Thread(this); reloj.start(); } public void run() { // Establece el actual hilo en ejecucin Thread hilo = Thread.currentThread(); while (reloj == hilo) { // Realiza una pausa durante unas milsimas de segundo try 18

Instituto Tecnolgico Metropolitano


{Thread.currentThread().sleep(100);} catch (InterruptedException e) {} // Redibuja el applet repaint(); } } } En el navegador se vera as:

Animaciones Ahora bien, para poder realizar una animacin, es imprescindible hacer una buena gestin de las imgenes cargadas simultneamente. Para ello se tiene la clase MediaTracker la cual define un objeto que comprueba el estado de un nmero arbitrario de imgenes en paralelo. Para utilizar MediaTracker hay que crear una nueva instancia y usar su mtodo addImage() para aadir una imagen al control del estado de la carga. Este mtodo tiene dos argumentos: el objeto Image y un nmero entero para identificar la imagen. Cuando se utiliza MediaTracker, una vez que se ha llamado al mtodo addImage() sobre una imagen, su referencia en MediaTracker evita que el sistema la elimine a travs del mecanismo de recogida de basura. Una vez que se ha cargado la imagen original, sta se corta en un nmero determinado de pequeas imgenes. Entonces se comienza la ejecucin de un hilo que va mostrando las imgenes en el orden que se considera conveniente. El hilo debe dormir un tiempo suficiente para mantener la velocidad en la que se muestran las tramas. import java.applet.*; import java.awt.*; import java.awt.image.*; public class Animacion extends Applet implements Runnable{ Image imagen,fondo; Image diapositiva[]=new Image[22]; public void init() { try { fondo=getImage(getDocumentBase(),"FondoCasa.jpg"); 19

Instituto Tecnolgico Metropolitano


imagen=getImage(getDocumentBase(),"animacion.gif"); MediaTracker mt=new MediaTracker(this); CropImageFilter cif; FilteredImageSource fis; mt=new MediaTracker(this); for(int i=0;i<=21;i++) { cif=new CropImageFilter(i*45+1,1,44,95); fis=new FilteredImageSource(imagen.getSource(),cif); diapositiva[i]=createImage(fis); mt.addImage(diapositiva[i],i); } mt.waitForAll(); } catch (InterruptedException e) {} } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { g.drawImage(fondo,0,0,null); g.drawImage(diapositiva[numeroDiapositiva],x,55,null); } Thread t; int numeroDiapositiva; int x; public void start() { t=new Thread(this); t.start(); } public void stop() { t.stop(); } public void run() { numeroDiapositiva=0; x=0; for(numeroDiapositiva=0;numeroDiapositiva<=21;numeroDiapositiva++) { paint(getGraphics()); if(numeroDiapositiva<16) { x+=10; try { Thread.sleep(200); 20

Instituto Tecnolgico Metropolitano


} catch (Exception e) {} } else { x+=3; try { Thread.sleep(400); } catch (Exception e) {} } } } } La ejecucin del applet se puede ver as:

Donde se puede observar una especie de desplazamiento de la figura. TEMA 3 Ejercicios de aplicacin

1. Elaborar una animacin en un applet que permita hacer una transicin de una imagen a otra en varios barridos. Cada barrido va mostrando ms de la figura siguiente y menos de la segunda, como se observa en la siguiente grfica:

21

Você também pode gostar