Sie sind auf Seite 1von 196

Tema 1: Aspectos imperativos del lenguaje

0 Antes de empezar 1 Primer programa 2 Variables (y constantes) 3 Entrada/Salida en modo texto 4 Tipos Primitivos 5 Instrucciones de control

Tabla A: Palabras Reservadas en Java Tabla B: Rango de los tipos primitivos Tabla C: Asociatividad de los operadores Apndice A: Instalacin y uso de un compilador Apndice B: Uso de Javadoc Apndice C: Ficheros JAR

0 Antes de empezar

0.1 Objetivos 0.1 El secreto del xito 0.2 Un poco de terminologa

Tema 1: Aspectos imperativos del lenguaje

0.1 Objetivos

Estos apuntes pretenden ser una introduccin al lenguaje de programacin Java. Java es un lenguaje muy extenso, con muchas "caras", y ningn libro o coleccin de apuntes pueden pretender cubrir con suficiente profundidad todos los aspectos del lenguaje. De hecho, hoy en da es normal designar mediante la palabra "Java" no a un lenguaje sino a toda un conjunto de herramientas, metodologas, etc. basadas en el lenguaje. Por eso no est de ms que tratemos de delimitar desde el principio cules son los objetivos, qu se pretende y qu no se pretende.
Lo que se pretende es mostrar en suficiente detalle los conceptos bsicos del lenguaje. Para ello se parte de cero, tratando de hacer el aprendizaje lo ms gradual y "suave" posible. El precio a pagar: no ser posible cubrir todos los aspectos del lenguaje. Muchos de los aspectos ms avanzados, y puede que para muchos ms atractivos, del lenguaje no sern tratados. Tambin se ignoran algunos trucos y tcnicas comunes entre los programadores de Java que, aunque tiles, podran confundir al principiante. Se pretende explicar slo lo principal, pero bien, procurando que el lector entienda el porqu de cada paso. El objetivo es llegar a tener un conocimiento slido, una buena base del lenguaje. Ms adelante, si as lo queremos o lo necesitamos, estos conocimientos nos ayudarn a comprender libros dedicados a aspectos ms especficos del lenguaje. En los apndices al final de cada captulo mencionaremos algn aspecto ms especfico que consideremos curioso o interesante. La lista siguiente incluye la mayor parte de los aspectos del lenguaje cubiertos por estos apuntes. Contiene muchos trminos que posiblemente suenen de los ms extraos (e incluso amenazadores) al que an no sabe nada del lenguaje, pero puede resultar de utilidad para los que s sepan algo y quieran evitar perder el tiempo. Breve introduccin a las sentencias de control (bucles, sentencias condicionales, etc.) y otros aspectos bsicos como el manejo de excepciones. Principios de programacin orientada a objetos en Java: encapsulacin, herencia, clases abstractas e interfaces. Programacin de interfaces grficos: control de eventos, clases AWT y Swing (esta ltima slo superficialmente), y desarrollo de Applets. Utilizacin de los recursos bsicos del lenguaje tales como vectores y arrays, y desarrollo de nuestros propios tipos abstractos de datos. Esta otra lista (compuesta por trminos an ms esotricos) incluye parte de lo que no se puede encontrar en estos apuntes: Programacin de Servlets y JSP (Java Server Pages). Programacin concurrente.

Tema 1: Aspectos imperativos del lenguaje


Acceso a bases de datos (JDBC). Java Beans. Una vez las cosas en su sitio, podemos empezar a divertirnos con ellas.

0.1 El secreto del xito


Nacimiento de Java Java fue desarrollado en 1995 por Sun Microsystems. Es heredero directo de C++ y es por tanto un lenguaje orientado a objetos. Fue pensado en principio como un lenguaje sencillo para escribir programas de control de microprocesadores para electrodomsticos. Sin embargo ha sido con el desarrollo de internet y en particular con el crecimiento de las pginas WEB cuando el lenguaje ha alcanzado su mxima difusin, hasta llegar hoy en da a ser uno de los lenguajes ms demandados. Pero Por qu?. Para comprender las razones tenemos que entender cmo se ejecutan los programas Java en un ordenador. Aunque estos detalles no tienen que ver con la programacin en si, no est de ms conocerlos, aunque sea mnimamente. Compiladores El ordenador slo entiende un lenguaje: el cdigo mquina (o ensamblador). Es un lenguaje muy poco "natural" para los humanos. Consta de instrucciones bsicas que hacen referencia a la estructura del microprocesador (por ejemplo del Pentium). Realizar programas de gran tamao y complejidad directamente en cdigo mquina es una tarea prcticamente imposible. Es por esta razn por la que surgieron los llamados lenguajes de alto nivel (como Java, Pascal, Fortran, C, C++). Estos lenguajes son ms cercanos al ser humano, y por tanto ms adecuados para la programacin de aplicaciones. De hecho llamar a estos lenguajes de alto nivel es demasiado optimista. En realidad estn, por as decirlo "a medio camino" entre lo que a los humanos les gustara poder escribir y lo que el ordenador admite realmente. Por ejemplo al humano le gustara poder decir: "Anda, calclame la raz cuadrada de 2 y mustrame el resultado por pantalla" Mientras que el procesador del ordenador (que es quin realmente ejecuta el programa) slo admitira algo as como: "001001101001011101010100001101011101010101010101110111101001110100011111 1" Un lenguaje de alto nivel como Java permite alcanzar cierto compromiso y as podemos escribir: System.out.println( Math.sqrt(2) ); donde System.out.println significa "escribe en pantalla" y Math.sqrt(2) "calcula la raz cuadrada de 2".

Tema 1: Aspectos imperativos del lenguaje


Pero cmo hacer que el procesador admita esta instruccin en Java? Pues para eso hace falta utilizar un programa especial, llamado compilador . Este programa se encarga del "trabajo sucio": traduce el programa en el lenguaje de alto nivel (por ejemplo Java) al lenguaje del ordenador (por ejemplo a cdigo mquina del procesador Pentium). Vindolo de forma simplificada podemos representar esta idea as:

Por supuesto el programador no tiene porqu preocuparse del funcionamiento interno del compilador: le basta con usarlo. Sin embargo, no viene mal echar un breve vistazo brevemente cual es la estructura interna de los compiladores tradicionales. En una primera (y muy burda) divisin, el compilador consta de dos fases consecutivas: 1. Anlisis. En esta fase se lee el programa original (al que se suele denominar cdigo fuente) y se analiza para descubrir sus significado. Por ejemplo, al llegar a la instruccin System.out.println( Math.sqrt(2) ); , el compilador leer el cdigo letra a letra (S-y-s-t-e-m-...) reconociendo en primer lugar la palabras "System". Si nos equivocamos y escribimos en nuestro programa Sostem.out.println( Math.sqrt(2) ); , el compilador detectar en esta fase que "Sostem" no corresponde a nada conocido, y nos dar un mensaje de error. Si en cambio el compilador no detecta ningn error la primera fase habr finalizado con xito. El resultado de esta primera fase es una representacin interna del programa fuente (a la que el programador no tiene, en principio, acceso) y que la segunda fase tomar a su vez como entrada. El anlisis de un programa por parte de un compilador no es una tarea complicada (hay tcnicas muy conocidas para automatizar esta parte), pero es farragosa, y a menudo lenta: el compilador debe leer todo el cdigo fuente e ir examinando cada posibilidad para ver cual es el significado de lo escrito por el programador. 2. Generacin de cdigo mquina. En esta segunda fase se genera ya el cdigo mquina a partir de la representacin interna producida en el paso anterior. La generacin de cdigo no es una tarea trivial: cuando se disea el lenguaje hay que pensar en cmo se representarn en el cdigo mquina del microprocesador todas las caractersticas que forman parte del lenguaje. Cuanto ms complejo o de ms "alto nivel" sea el lenguaje, ms difcil ser traducirlo a cdigo mquina. Sin embargo, una vez que todas estas decisiones estn tomadas y se ha conseguido escribir esta parte del compilador, su ejecucin s es veloz, es decir se tarda menos en generar cdigo que en hacer el anlisis del cdigo fuente (fase 1). En este punto conviene recordar que en general diferentes microprocesadores tienen diferentes cdigos mquina asociados, y que stos en general no son compatibles entre s. Habitualmente olvidamos esto porque estamos acostumbrados a trabajar con ordenadores cuyos microprocesadores son compatibles (los Intel x86, Pentium, etc.). Pero si somos usuarios, por ejemplo de Mac, sabremos que los programas que se ejecutan en nuestro PC no se pueden ejecutar en el Mac. La razn no es tanto el uso de sistemas operativos diferentes sino que los cdigos mquinas de los microprocesadores no son compatibles.

Tema 1: Aspectos imperativos del lenguaje


Igualmente un programa de un PC de los llamados "32 bits" no corre en un antiguo PC de "16 bits" por incompatibilidad entre los cdigos mquina. Por tanto, si queremos, por ejemplo, programar en C++ en nuestro ordenador, lo primero que tenemos que hacer (aparte de aprender C++) es conseguir un compilador de C++ que est desarrollado para nuestro microprocesador. Si por ejemplo (y por error) conseguimos un compilador de C++ que genera cdigo para ordenadores con procesadores SPARC, aunque logremos compilar nuestro programa, ste no podr ejecutarse satisfactoriamente. Esto en realidad no es ningn problema ... siempre y cuando no pensemos en aplicaciones para internet. Vamos a ver por qu. Programar en la WEB Cuando visitamos una pgina html en internet, se desarrolla el siguiente proceso: 1. Nuestro ordenador (el "cliente") se conecta con el ordenador ("servidor") en el que se encuentra la pgina que deseamos, y se la solicita. 2. El servidor enva (utilizando una copia del protocolo http) una copia de la pgina solicitada hacia nuestro ordenador. 3. Nuestro ordenador recibe la pgina, la procesa y nos muestra utilizando el navegador correspondiente (Netscape, explorer, etc.). A partir de ahora, y siempre cuando no pulsemos en ningn enlace la pgina (en realidad una copia) est fsicamente en nuestro ordenador; podramos incluso interrumpir la conexin con internet y seguiramos teniendo la pgina en el explorador, con la posibilidad de movernos por ella libremente. Una pgina html bsica slo consiste en tres elementos: texto, imgenes y enlaces a otras pginas. Sin embargo, desde el principio los programadores de pginas web queran disear pginas ms interactivas, capaces de responder a acciones del usuario Y esto, evidentemente, equivala a incluir programas como parte de las pginas html. Sin embargo, cmo hacerlo? En principio hay dos posibilidades obvias: Mandar al usuario el programa, ya compilado, junto con la pgina html. Pero hemos dicho que el programa ya compilado est en cdigo mquina, y que el cdigo mquina slo es vlido para un procesador determinado qu pasa si el usuario tiene un ordenador con un procesador diferente? Una solucin sera que el cliente informara al servidor acerca de qu procesador tiene, y el servidor le enviara el programa compilado para su procesador particular. Pero esto obligara a actualizar el servidor cada vez que aparezca un tipo de procesador nuevo y no es nada prctico. Mandar al usuario el programa fuente, sin compilar. El navegador compilara entonces el programa y lo mostrara al usuario. Esto requiere que el navegador incluya un compilador, pero esto no es un problema si se "convence" a las empresas que distribuyen los navegadores. El problema es que los programas fuentes ocupan bastante espacio, y la compilacin (sobre todo en la fase 1) es un proceso largo, que retrasara enormemente la ejecucin del programa. De nuevo la solucin no es prctica. Fue entonces cuando se pens en una posible solucin que combinaba y mejoraba las dos posibilidades anteriores. Y esta fue la razn (o una de las razones) del xito de Java.

Tema 1: Aspectos imperativos del lenguaje


Uno de los secreto del xito: los bytecodes La solucin que se usa hoy en da se basa en una mezcla las dos ideas expuestas en el apartado anterior. Curiosamente los creadores de Java pensaron en esta solucin pero no para pginas web sino para electrodomsticos. El programa que queremos enviar con la pgina html se compila en el servidor, pero no para un cdigo mquina concreto sino para una especie de cdigo intermedio universal llamado bytecodes. Este proceso se hace slo una vez, antes de poner la pgina a disposicin del pblico. Cuando el usuario solicita la pgina, sta viaja al ordenador cliente acompaada de los correspondientes bytecodes. El navegador del usuario debe tener un pequeo compilador (en realidad un intrprete porque traduce y ejecuta instruccin a instruccin) llamado mquina virtual de Java (MVJ) para ejecutar este programa. Lo bueno de esta solucin es que el cdigo que viaja (bytecodes) ya ha pasado la primera fase de la compilacin; que como hemos dicho es la ms lenta. Ocupa menos espacio que el cdigo fuente original y est con (casi) seguridad libre de errores por haber superado la fase 1. El intrprete incluido en el navegador slo tiene que traspasar el cdigo en bytecodes a cdigo para su procesador concreto. Como los bytecodes ya son algo similar a un cdigo mquina la traduccin no es complicada y se hace de forma veloz. Se obtiene una ventaja que explica parte del xito de Java: La parte ms difcil, el compilador de Java a bytecodes, es ahora independiente del procesador (ya que no genera cdigo para ningn procesador real): al cambiar del sistema slo hay que construir un nuevo intrprete de bytecodes lo que, como hemos dicho, es mucho ms sencillo.

En particular los navegadores ms usuales (explorer, Mozilla, Netscape) incluyen intrpretes de bytecodes. Ahora tambin resulta ms fcil de entender por qu se oye a menudo hablar de juegos en Java para telfonos mviles. El creador del juego no tiene por qu preocuparse de todos los modelos de telfono mvil del mercado: slo de escribir el juego y compilarlo generando los bytecodes. Es cada fabricante del telfono el que se encarga de incluir un pequeo intrprete de bytecodes, lo que garantiza que su telfono ser capaz de ejecutar juegos en

Tema 1: Aspectos imperativos del lenguaje


java. Por tanto cuando "bajamos" un juego o una aplicacin en Java de internet para nuestro telfono, lo que estamos descargando son sencillamente programas traducidos a bytecodes. Ms razones para el xito Acabamos de ver que algunas de las razones ms importantes del xito del lenguaje no tienen nada que ver con el lenguaje como tal, sino con cmo se compilan los programas. Pero el lenguaje tambin tiene caractersticas que han sido fundamentales para que los programadores se "animaran" a usarlo. Algunas de estas caractersticas son: Java es un lenguaje orientado a objetos. Este tipo de lenguajes, entre los que tambin se incluye C++, tiene numerosas ventajas sobre los llamados lenguajes imperativos no orientados a objetos a los que pertenecen por ejemplo Pascal, Fortran y C (en un tema posterior veremos estas ventajas). Java fue desarrollado despus de C++ y corrige gran parte de los inconvenientes de este lenguaje (aunque introduce otros). Se puede ver en este sentido como una evolucin con respecto a C++. Una de las diferencias con respecto a C++ es la gestin de la memoria dinmica. En C++ (y en C) el programador tiene responsabilidad sobre el uso de la memoria adicional que pueda requerir durante la ejecucin (los amados/odiados punteros): debe solicitar la memoria, usarla -con precaucin- y no olvidar liberarla. En Java el manejo de memoria dinmica es ms sencillo, y los errores se detectan ms fcilmente. En particular la liberacin de la memoria, ya no es responsabilidad del programador sino del lenguaje, que cuando detecta que un fragmento de memoria ha quedado libre, llama al recolector de basura que se encarga de marcar el fragmento como disponible. Una de las razones ms importantes: en Java la programacin de interfaces grficos es parte del lenguaje estndar. En C++, por ejemplo, el lenguaje no incluye ninguna referencia a cmo hacer interfaces grficos ni sobre cules deben ser las libreras grficas. Sin embargo hoy en da todas las aplicaciones reales trabajan en modo grfico (ventanas, tipos de letra, etc.). Como consecuencia, cada compaa (Borland, Microsoft) desarroll sus propias libreras, llegando en la prctica a haber distintos "dialectos" del lenguaje. En Java, al ser ms moderno, se decidi desde el principio incluir como parte del lenguaje todas las caractersticas grficas. As el programador no depende de la compaa concreta que ha hecho el compilador; basta con que aprenda Java estndar. Adems desde el comienzo Sun ofreci su compilador, con entorno grfico y depurador, de forma gratuita. Esto ha "animado" (obligado?) a otras compaas a ofrecer a su vez sus compiladores, al menos en la versin bsica, de forma gratuita. No puede ser todo tan bonito... Pues no, no lo es. Java tambin tiene su "lado oscuro". Defectos y problemas que podemos resumir en los siguientes puntos: Poca velocidad. Comparado C e incluso con C++, la ejecucin de programas en Java es habitualmente ms lenta. Esto es debido en parte a algunas caractersticas especficas del lenguaje (como la "recogida de basura" mencionada), y en parte a que cada vez que se ejecuta un programa hay que convertir los bytecodes en cdigo de la mquina, proceso ms costoso que ejecutar cdigo mquina directamente.

Tema 1: Aspectos imperativos del lenguaje


No es adecuado para controlar hardware.. En efecto, Java intenta, como hemos dicho, ser independiente del procesador de la mquina en la que se est ejecutando. Por ello no dispone de instrucciones de acceso a los puertos de entrada/salida del ordenador y no permite controlar perifricos o acceder a hardware. Es, por tanto, poco adecuado para hacer aplicaciones que tengan que ver con, por ejemplo, robtica. El aprendizaje es, al comienzo, ms difcil que en otros lenguajes. Como veremos enseguida incluso el programa ms corto incluye desde el principio gran cantidad de trminos extraos. Al principio debemos aceptarlos sin ms, aunque poco a poco iremos aclarndolos todos.

0.2 Un poco de terminologa


A los informticos les encantan los acrnimos. Son cortos, designan expresiones complicadas... y sobre todo sirven para sentirse superiores al resto de los mortales que, pobres, no conocen su profundo significado. Vamos a repasar algunos de los ms usuales en Java: JSDK (Java Software Development Kit, SDK para los amigos, si los hubiere): Entorno de desarrollo (compilador y otras herramientas) que permite la creacin de aplicaciones en tecnologa Java. No incluye ningn interfaz grfico; son todo comandos de lnea, es decir que deben ser tecleados desde una consola. Para evitar esto se suele utilizar en la prctica un entorno grfico (como Eclipse o JCreator) que es el que se encargar de "llamar" al compilador de JSDK. A menudo se emplea la variante J2SDK para indicar que se trata del JSDK correspondiente a la segunda revisin del lenguaje, que es el que se usa actualmente. JRE (Java Runtime Environment): Se necesita para ejecutar un programa Java previamente compilado (es decir, es el intrprete de los famosos bytecodes). JVM (Java Virtual Machine): Similar a JRE, pero se suele utilizar ms para referirse al intrprete de bytecodes incluido como parte de un navegador. API (Application Programming Interface): Se usa para referirse al conjunto de funcionalidades que ofrece un lenguaje (o un sistema operativo). En el caso de Java se refiere al conjunto de clases que ofrece el lenguaje al programador y que incluyen la posibilidad de usar componentes grficos (botones, ventanas, etc), vectores, operaciones matemticas (clase Math) y un largusimo etctera. J2SE (Java 2 Standard Edition), y J2EE (Java 2 Enterprise Edition): Se llama J2SE al ncleo del lenguaje actual, incluyendo el J2SDK y el JRE. Se llama J2EE a una ampliacin del J2EE que incluye un API ms extenso, pensado, sobre todo, para el desarrollo de programas Java como servidores de pginas HTML. En estos apuntes nos ocuparemos de J2SE pero no de J2EE. Applet: No es un acrnimo, sino el nombre que se da al programa Java diseado para ser parte de una pgina HTML (HTML ... otro acrnimo!). Esto por supuesto no es ms que un mnimo catlogo del variado bestiario que adorna los libros de Java, donde el inquieto aventurero podr encontrar otras pintorescas criaturas tales como EJBs (Enterprise Java Beans), JSPs (Java Server Pages), JDBC (Java DataBase Connection), JACC (Java Authorization Contract For Containers), RMI (Remote Method

Tema 1: Aspectos imperativos del lenguaje


Invocation), JMS (Java Message Service), JND (Java Naming and Directory), JTA (Java Transaction API) o JTS (Java Transaction Service). Casi todas, como las bestias medievales, son sumamente nombradas pero raramente explicadas, lo que nos llevar a dudar de su existencia.

1 Primer programa
Nuestro primer programa se limita a mostrar una lnea de texto en pantalla: Hola.java
public class Hola { public static void main(String [] Args) { System.out.println("Soy pequen....mmame!"); } }

Vamos a ir analizando el programa lnea a lnea: public class Hola { En esta primera lnea se indica el nombre de la clase que estamos definiendo. public class indica que el fichero contiene una clase que se va a poder utilizar desde otras. A estas palabras reservadas les sigue el nombre que queremos poner a la clase, en este caso Hola. Aunque no es obligatorio, es una norma habitual en Java escribir siempre el nombre de una clase con un identificador que comience por una letra mayscula. Adems, cada clase debe, (casi) obligatoriamente, formar parte de un fichero con el mismo nombre que la clase y con extensin .java. Aunque ms adelante veremos que la cosa puede llegar a ser un poco ms complicada, conviene en principio que recordemos la siguiente correspondencia: Cada clase se almacena en un fichero que lleva su nombre (y extensin .java). Cada fichero .java contiene una nica clase pblica, cuyo nombre corresponde con el del fichero (sin la extensin). Aviso: Las maysculas s importan en Java! Si despus de escribir la clase Hola la utilizamos escribiendo hola en otro lugar, el compilador dar error indicando que el identificador no ha sido definido. Aunque en los temas posteriores veremos con detalle los conceptos de clases y paquetes no est de ms que veamos una primera (incompleta y burda) aproximacin:

Tema 1: Aspectos imperativos del lenguaje


Clases Las clases representan conjuntos de objetos que quedan caracterizados por unas caractersticas (atributos) y un comportamiento (dado por sus mtodos) determinados. Observacin (para los que sepan C++): En C++ las clases se dividen en dos ficheros, el fichero de cabecera (extensin .h) y el fichero de implementacin (extensin .cpp). En Java la cabecera y la implementacin forman un nico fichero con extensin .java Paquetes La unidad de cdigo de ms alto nivel en Java es el paquete. Cada paquete agrupa una o ms clases lgicamente relacionadas. Es habitual que las clases que forman un programa se agrupen en varios paquetes. Normalmente para cada paquete se crear un directorio o carpeta (con el nombre coincidente con el paquete) que contendr todas las clases (ficheros .java) del paquete. A diferencia de las clases es "tradicin" poner a los paquetes nombres que empiecen por la letra minscula. Cuando la aplicacin es muy complicada interesa ampliar la jerarqua, y hacer paquetes que contienen otros paquetes y as repetidas veces hasta llegar a los paquetes ms simples que slo contienen clases. Aunque nosotros no haremos esto en nuestros ejemplos al ser stos demasiado simples, conviene conocer esta posibilidad por las clases del API de Java que utilizaremos s estn organizadas en paquetes y subpaquetes. Observacin: Si no asignamos una clase a un paquete particular, Java la asigna a un paquete genrico por defecto. Este es el caso de la clase Hola. Tras la declaracin del nombre de clase viene el smbolo { que indica que comienza la declaracin de los componentes de la clase. La declaracin de la clase se dar por terminada cuando se encuentre el smbolo } correspondiente a este { inicial. public static void main(String [] Args) { As comienza la declaracin del mtodo main, nico componente de la clase Hola.El mtodo main siempre debe ser declarado con la misma cabecera:
public static void main(String [] Args) {

Podemos explicar brevemente cada una de las partes de esta declaracin: public Esta palabra significa que el mtodo puede utilizarse desde fuera de la clase. Pero...tendra sentido escribir un mtodo que no pudiera utilizarse fuera de la clase? S, cuando se trata de mtodos auxiliares que sern utilizados desde otros mtodos de la clase pero no queremos (por seguridad o por esttica) que puedan ser "vistos" fuera de la clase. static La palabra static significa que para utilizar este mtodo no necesitamos declarar un objeto de la clase. Veremos que en general para utilizar una clase es necesario tener un objeto de dicha clase (una variable de ese tipo, dicho con otras palabras) como ocurra con el objeto lneas de la clase Vector, pero el mtodo main es un mtodo especial ya que es el punto de comienzo de la aplicacin. void Todos los mtodos deben devolver un resultado de algn tipo. En la cabecera hay

Tema 1: Aspectos imperativos del lenguaje


que indicar dicho tipo. Sin embargo algunos mtodos, como este realmente no necesitan devolver ningn valor. En este caso se declaran como de tipo void. String[] args Los mtodos pueden recibir argumentos, es decir valores que se le pasan como en el caso de las funciones matemticas seno y coseno, que tienen como argumento el valor del que queremos calcular el seno o el coseno. En el caso de main este argumento es una lista (representada en Java por []) de cadenas de caracteres (String en Java). Estas cadenas de caracteres se utilizan para que el usuario pueda pasar informacin al programa al inicio. En Java, igual que en C y C++ se utilizan las llaves ({ }) para agrupar cdigo, en este caso el cuerpo del mtodo. Este cuerpo est formado por una nica instruccin: System.out.println("Soy pequen....mmame!"); Instruccin que, como todas en Java, terminan en ;. En este caso se llama al mtodo println que escribe por pantalla una cadena de caracteres. El mtodo pertenece al objeto out definido en la clase System que siempre puede usarse sin necesidad de utilizar una declaracin import. Pregunta 1.a Llevados por la emocin decidimos escribir un programa un poco ms grande, al que llamamos "Crece.java":
public class crece { public static void main(String [] Args) System.out.println("Ya ocupo "); System.out.println("dos lneas "); } } {

Sin embargo al intentar compilarlo nos da el siguiente error:


Crece.java:1: class crece is public, should be declared in a file crece.java class crece { ^ 1 error

qu significa?

Aunque el programa Hola.java es correcto lo habitual es escribir comentarios que expliquen el cdigo: Hola.java
/** * Primera clase en Java. * @version 1.0, 24/12/04 * @author Rafa Caballero */ public class Hola {

Tema 1: Aspectos imperativos del lenguaje


/** * Mtodo principal. Escribe por pantalla una lnea de texto * @param Args Argumentos pasados por lnea de comandos. No utilizados */ public static void main(String [] Args) { /* Mostramos una lnea por pantalla en modo texto. Ms adelante aprenderemos a hacerlo mediante una ventana grfica. */ System.out.println("Soy pequen....mmame!"); } } // fin de la clase

Este cdigo hace exactamente lo mismo que el programa inicial slo que incluye comentarios. Los comentarios no alteran el funcionamiento del programa, se incluyen para que ste sea ms comprensible y para generar documentacin automtica. Java incluye 3 tipos de comentarios: 1. Comenzando con // . En este caso el compilador ignora todo lo que va desde // hasta el final de lnea. 2. Comenzando con /* y terminando con */. Estos comentarios pueden ocupar mltiples lneas. 3. Comenzando con /** y terminando con */. Igual que el anterior, slo que estos comentarios pueden ser utilizados por la herramienta javadoc para generar documentacin sobre la clase.

2 Variables (y constantes)
2.1 Qu es una variable? 2.2 Declaracin de variables 2.3 Operacin de asignacin 2.4 Constantes

2.1 Qu es una variable?


Nos podemos imaginar la variable como una "caja" (unas direcciones de memoria) con un nombre y un valor: | | | 'b' | (10325-10326) | ____ | x

Tema 1: Aspectos imperativos del lenguaje


En esta figura, x es el nombre de una variable que contiene la letra 'b' y que se "aloja" en las direcciones de memoria (10325-10326). En los lenguajes llamados "tipados" como Java, las variables tienen, adems, un tipo. El tipo de la variable determina el conjunto de variables que sta puede tomar, as como las operaciones que se le pueden aplican. En el ejemplo anterior el tipo de la variable x sera carcter, o como se escribe en Java, char. Por tanto una variable en Java tiene: Un nombre, que fija el programador. Un tipo, que tambin fija el programador. Un valor, que va variando a voluntad del programador. Unas direcciones de memoria, en las que se almacena la variable, y que no son decididas por el programador. Normalmente nos olvidaremos de las direcciones de memoria, al no tener control sobre ellas, pero es importante saber que andan por ah para entender ciertas particularidades del lenguaje que veremos ms adelante.

2.2 Declaracin de variables


La forma general de una declaracin de variables es: tipoVariable nombreVariable =valorInicial; La inicializacin =valorInicial es opcional. Si se hace el valor valorInicial debe ser del mismo tipo (o un tipo compatible) con tipoVariable. El nombre de la variable puede ser cualquier identificador (igual que el nombre de un mtodo o una clase). Observacin: Los identificadores son secuencias de letras, nmeros y pueden contener smbolos como '$', '_' o '#', pero siempre deben empezar por una letra. A diferencia de otros lenguajes, los identificadores en Java pueden contener y letras acentuadas. Las normas de "buena educacin" indican que una variable siempre debe empezar por minscula (salvo en ocasiones si se trata de una constante, en cuyo caso se suele escribir en maysculas). Por ejemplo, sabiendo que en Java los nmeros enteros corresponden con el tipo int y los caracteres con el tipo char, podemos escribir:
int ao = 2005; int suma=0; int nmero; char letra;

Java tambin permite que varias variables del mismo tipo se declaren separadas por comas:
int nmero,b=3,c=4,suma=0,d; char letra;

Un ltimo aspecto a mencionar es que en Java las declaraciones de una variable se pueden hacer en cualquier lugar:

Tema 1: Aspectos imperativos del lenguaje


public class Principal { public static void main(String[] args) { int a=5; System.out.println("El valor de a es: "+a); int r = 25; // r se declara aqu System.out.println("El valor de r es: "+r); } // main }

El operador + sirve aqu para concatenar el contenido de la variable al final de la cadena de caracteres.

2.3 Operacin de asignacin


La operacin de asignacin para todos los tipos definidos en Java. La forma general de esta operacin es: nombreVariable = expresin; En Java (como en C y C++) la asignacin no es una instruccin sino una expresin. Observacin: Una expresin es una secuencia de smbolos que puede ser reducida en tiempo de ejecucin a un valor. En el caso de la asignacin ese valor es el que contiene la variable de la parte izquierda:
public class Principal { public static void main(String[] args) { int a,b; a = (b=5)+1; System.out.println(a); System.out.println(b); } // main }

Pregunta 1.b Qu escribir el programa? En particular esto permite la llamada asignacin mltiple:
public class Principal { public static void main(String[] args) { int a,b,c; a = b = c = 1; System.out.println(a); System.out.println(b); System.out.println(c); } // main

Tema 1: Aspectos imperativos del lenguaje


}

Pregunta 1.c Qu escribir el programa? A menudo y por comodidad utilizaremos esta asignacin mltiple. Observacin: La igualdad es una operacin que asocia por la derecha (ver tabla C).

2.4 Constantes
Las constantes son variables que no pueden modificarse. En Java se declaran anteponiendo la palabra reservada final a la declaracin de la variable: final tipoVariable nombreVariable = valorInicial; Ej.:
final char AMAYSCULA = 'a'; final double N = 299792.495;

Es necesario incluir la inicializacin junto con la declaracin, porque la operacin de asignacin no est permitida ms que en la declaracin:
final double PI = 3.141592; double a; a = PI +1; // esto es vlido PI = a +1; //NOOOO!!!!

3 Entrada/Salida en modo texto


3.1 Salida en modo texto 3.2 Entrada en modo texto

3.1 Salida en modo texto


La salida de datos en modo texto se puede hacer en Java fcilmente a travs del mtodo println() de System.out. Ya hemos visto que una instruccin como
System.out.println("El que sabe no habla, el que habla no sabe");

Hace que aparezca por pantalla la secuencia de caracteres escrita entre comillas. En lugar de escribir la secuencia de caracteres directamente, tambin nos puede interesar almacenarla primero en una variable. El tipo de las secuencias de caracteres en Java se llama String. El siguiente cdigo declara una variable de este tipo y muestra su contenido por pantalla:
String s = "Nocturno y dulce revuelo";

Tema 1: Aspectos imperativos del lenguaje


System.out.println(s);

Es importante observar aqu que el nombre de la variable no va entre comillas; si hubiramos escrito System.out.println("s"); en lugar de la frase el cdigo mostrara por pantalla simplemente s. println() es tan flexible que nos permite igualmente escribir enteros, caracteres o nmeros reales. Por ejemplo
System.out.println(124); System.out.println('a'); System.out.println(1.618033);

muestra por pantalla:


124 a 1.618033

Tambin podemos combinar diferentes tipos utilizando +:


public class Prueba { public static void main(String[] args) { String s1 = "Entonces, quedamos a las "; int hora1 = 11; String s2 ="?"; String s3 = "No, mejor a las "; double hora2 = 11.45; System.out.println(s1+hora1+s2); System.out.println(s3+hora2+". Vale"+s2); } // main }

Pregunta 1.d Qu escribir el programa? Para acabar, decir que se puede usar print en lugar de println si se quiere que no se introduzca un salto de lnea tras escribir.

3.2 Entrada en modo texto


Hemos visto que la salida de datos es muy sencilla. En cambio, lograr que un programa en Java recoja los datos de entrada introducidos por el usuario es un poco ms complicado. Veamos un ejemplo: Lign.java
// para leer de teclado necesitamos la clase Scanner import java.util.Scanner; public class Lign { public static void main(String[] args) { // sc se usar para leer los datos

Tema 1: Aspectos imperativos del lenguaje


Scanner sc = new Scanner(System.in); // preguntar la edad System.out.print("Cuntos aos tienes? // leer un entero int edad = sc.nextInt(); System.out.println("...pues aparentas "+(edad-3)); } // main } ");

Una salida de este programa:


Cuntos aos tienes? ...pues aparentas 19 22

Este ejemplo incluye muchas novedades: import java.util.Scanner; Para leer de teclado se debe utilizar un objeto de la clase Scanner. Esta clase no es de las incluidas de forma automtica y por eso debe incluirse mediante la palabra clave import. Si la clase est definida en otro paquete se escribe el nombre "cualificado", precedido por el nombre del paquete. En este caso la clase Scanner es parte del paquete util que es a su vez parte de la clase java. Si se desean incluir varias clases se incluirn varias sentencias import:
import java.util.Scanner; import java.util.Vector;

Si se quieren incluir varias (o todas) clases del mismo paquete se puede usar el simbolo *:
import java.util.*; // importa Scanner, Vector y muchas ms

Para ver qu clases contiene cada paquete conviene consultar la ayuda de Java. Scanner sc = new Scanner(System.in); Esta instruccin declara e inicializa un objeto sc de tipo Scanner. En los captulos posteriores veremos los objetos en detalle, pero aqu tenemos un primer ejemplo de como se crea un objeto mediante new. El parmetro System.in indica de dnde se leer, en este caso de la entrada estndar pero igualmente se podra leer, por ejemplo de un fichero de texto de nombre "datos.txt":
Scanner sc = new Scanner(new File("datos.txt"));

int edad = sc.nextInt(); La llamada al mtodo nextInt(); devuelve el siguiente entero que se puede leer del objeto de tipo Scanner. Adems de enteros se pueden leer valores de otros tipos. Para leer una lnea completa se usar el mtodo nextLine(); que devuelve un valor de tipo String:
import java.util.Scanner; public class Principal { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("Cmo te llamas? "); String nombre = sc.nextLine(); // leer una cadena de caracteres System.out.println("Es un placer conocerte "+nombre); } // main

Tema 1: Aspectos imperativos del lenguaje


}

Pregunta 1.e Qu escribir el programa?

Observacin: A menudo en el terminal de texto las letras acentuadas, la y otros smbolos del alfabeto espaol no se muestran adecuadamente. Esto se solucionar ms adelante, cuando introduzcamos los programas con entrada/salida grfica.

4 Tipos Primitivos
4.1 Qu es un tipo? 4.2 Tipos Primitivos 4.3 Tipos enumerados 4.4 Conversiones de tipo

4.1 Qu es un tipo?
En principio se tiende a pensar en un tipo como un conjunto de valores, por ejemplo el tipo int estara formado por el conjunto de nmeros enteros aceptados por el lenguaje Java. Sin embargo esta visin es demasiado restrictiva. Si nos limitamos a usar los valores podemos hacer pocas cosas. Los valores slo son tiles cuando se combinan con las operaciones adecuadas. Por ello emplearemos la siguiente definicin: tipo = Valores + operaciones que manejan esos valores As el tipo int est formado por los valores enteros admitidos por el lenguaje Java junto con las operaciones +,-,*,/,=, .... Observacin: Hay veces que se usa el mismo smbolo para operaciones anlogas entre diferentes tipos. Por ejemplo, + representa la suma tanto de nmeros enteros como reales. Sin embargo, debemos recordar que se trata de dos operaciones diferentes, aunque estn representadas por el mismo smbolo. Se dice en este caso que el smbolo (por ejemplo +) est sobrecargado.

4.2 Tipos Primitivos


En Java existen 8 tipos primitivos predefinidos. Vamos a ver los valores que componen cada uno de ellos y las operaciones que admiten: Lgicos Valores

Tema 1: Aspectos imperativos del lenguaje


Los nicos valores de este tipo son las constantes true y false. Se utilizan principalmente en el control del programa: para decidir qu instrucciones se van a ejecutar o no dependiendo de condiciones, para fijar la condicin de repeticin de un bucle, etc. Operaciones

! : operador unario not; !true es false y !false es true exprb1 && exprb2 : true si los dos son true, false en otro caso exprb1 || exprb2 : true si alguno de los dos es true, false en otro caso a == b : true si a es igual a b, false en otro caso (no confundir con la asig. '=') a != b: true si a es distinto de b, false si son iguales.

Ejemplo
// operaciones entre booleanos boolean b1,b2; int x=5, y=x+3; b1= true && (x == y); // y = x; b2 = !b1 || (x != y); // System.out.println(b1); System.out.println(b2);

Pregunta 1.f Qu escribir este fragmento de programa? Los valores lgicos se pueden leer de teclado utilizando el mtodo nextBoolean(); de la clase Scanner:
Scanner sc = new Scanner(System.in); boolean b = sc.nextBoolean();

Enteros Hay 4 (sub)tipos de enteros: byte, short, int y long. La diferencia entre ellos es el rango de valores que admiten, y que se puede consultar en la tabla B al final del tema. El ms usado es el tipo int, pero las operaciones que vamos a ver son vlidas para todos ellos. Valores Los nmeros enteros se pueden escribir :

En decimal: -123, 666, 1024, 0 En octal: dgitos entre 0 y 6 comenzando siempre por un 0: 0612 En hexadecimal: dgitos y letras entre 'a' y 'f' (maysculas o minsculas, no importa) precedidas por 0x: 0xffff, 0x1A, 0xFabada.

Si se quiere indicar que un valor es de tipo long se aade tras el ltimo dgito una letra L (minscula o mayscula, no importa). Operaciones

Tema 1: Aspectos imperativos del lenguaje


Las operaciones aritmticas usuales: +,-,*, / (divisin entera) y % (resto de la divisin entera). Operadores de incremento (++) y decremento (--), que producen un nuevo valor entero. Ejemplo:
int x = 0; x = 5*8+1; x++; // es lo mismo que poner x=x+1

Operadores de relacin: >, <, <=, >=, == (comparacin, no confundir con la asignacin = ) y != (distinto). El resultado es un valor de tipo boolean, es decir true o false Ejemplo

import java.util.Scanner; // para leer de teclado public class Principal { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n1 = sc.nextInt(), n2=sc.nextInt(); boolean b1 = ((n2-n1) % 2) == 0; n1++; boolean b2 = n1 == n2; System.out.print(b1+" "); System.out.println(b2); } // main }

Pregunta 1.g 1. Qu escribir el programa cuando los valores de entrada son 9 y 11? 2. En qu casos escribir el programa false true? 3. En qu casos escribir el programa true true?

Operadores de asignacin: =, +=, -=, *=, /=, %=.

Tema 1: Aspectos imperativos del lenguaje


Observacin: Una asignacin de la forma var op= exp es equivalente a var = var op exp.

Ejemplo
public class Principal { public static void main(String[] args) { int x,y; x=y=2; x += 5; y *= x+1; System.out.println(x); System.out.println(y); } // main }

Pregunta 1.h Qu escribir el programa?

Observacin: La operacin potencia se hace mediante el mtodo pow(base,potencia) de la clase Math que veremos ms adelante.

Operaciones entre bits: & (AND), | (OR), ^ (XOR), >> (desplazamiento a la derecha), >> (desplazamiento a la derecha). Operan sobre los nmeros representados en binario. No demasiado utilizadas, por lo que no nos detenemos a explicarlas. Si alguien siente curiosidad puede probar el siguiente programa: Ejemplo:
public class Principal { public static void main(String[] args) { int x,y; x=4; // en binario 000...0100 y=1; // en binario 000...0001

Tema 1: Aspectos imperativos del lenguaje


// el 1 se mueve dos posiciones a la izq. Se introducen 0s por la izq. int a = x>>2; // el 1 se mueve dos posiciones a la der. Se introducen 0s por la der. int b = y<<3; int r = a | b; // OR de los dos nmeros en binario System.out.println(a); // escribe 1 (rep. en binario: 00....001) System.out.println(b); // escribe 8 (rep. en binario: 00..01000) System.out.println(r); // escribe 9 (rep. en binario: 00..01001) } // main }

Nmeros Reales Nmeros reales: float y double. Los literales que tienen un punto decimal son, por defecto, de tipo double, aunque si por el contexto se necesita indicar que un valor es de este tipo se puede escribir seguido de la letra d o D. Los literales del tipo float van seguidos de una F o f. Ej.: 123.45f En memoria tienen una longitud de 32 (float) y 64 (double) bits, respectivamente. Valores Los nmeros reales deben incluir bien un punto decimal '.' o una letra 'e' minscula (notacin exponencial): 5., .54, 1.33, -4e2, 5e-8. Por defecto estos valores son double, pero si se quiere indicar explcitamente se puede aadir inmediatamente tras el nmero una 'f' o 'F' o bien 'd' o 'D' (float o double). Operaciones Las operaciones son las mismas que en el caso de los nmeros enteros con la nica de que ahora '/' representa la divisin con decimales. Pueden leerse de teclado utilizando los mtodos nextDouble(),nextFloat() de la clase Scanner. Caracteres Valores {....'a','b',....,'z', '#', '$', '', '', .....'[', '@',.....} Los caracteres corresponden a la tabla Unicode, ms extensa que la tabla ASCII usada por otros lenguajes: la tabla ASCII extendida tiene 256 caracteres mientras que la tabla Unicode est compuesta por 65536 caracteres, incluyendo Kanji, cirlico, etc. A cada carcter le corresponde un cdigo nico entre 0 y 65535, cdigo que se puede ver forzando la conversin del carcter a entero (que se hace automticamente): Ejemplo
char c='?'; int codigoUnicode = c; System.out.println(codigoUnicode); // escribe el valor 936

Tema 1: Aspectos imperativos del lenguaje


Un carcter se puede representar de tres formas:

Entre comillas simples: 'a', '', '%', '?'. Escribiendo entre comillas su cdigo Unicode en hexadecimal (4 dgitos): '\u0fa0'. Algunos caracteres especiales no imprimibles se escriben con \ seguido de un carcter. Como '\n', que representa el fin de lnea, o '\t' que representa el tabulador.

Operaciones Sobre un carcter se pueden aplicar las operaciones vlidas para los enteros, que actuarn sobre el cdigo Unicode del carcter. Es importante saber que en la tabla Unicode los cdigos de la 'A', 'B', 'C' ... van consecutivos, y que lo mismo sucede con 'a', 'b', 'c', ..., y con '0',...,'9'.

4.3 Tipos enumerados


Adems de estos tipos bsicos, el usuario tambin puede definir tipos enumerados, que desde el punto de vista del lenguaje tambin se tratan como tipos bsicos, aunque en realidad se traduzcan por objetos internamente. Vamos a introducirlos brevemente. Los tipos enumerados son una novedad en Java 1.5, y permiten al usuario definir tipos formados por un nmero finito de valores. En un primer vistazo, los tipos enumerados se parecen mucho a los tipos enumerados de otros lenguajes de "la familia" como C, C++ y C#. Por ejemplo, se puede declarar un tipo que sirva para representar las estaciones del ao. Las variables de este tipo slo podrn tomar cuatro valores: PRIMAVERA, VERANO, OTOO, e INVIERNO: EjEnumerados.java
public class EjEnumerados { // declaramos as el tipo enumerado public enum Estacin {PRIMAVERA, VERANO, OTOO, INVIERNO}; public static void main(String[] args) { Estacin mia; // declaramos una variable del tipo Estacin mia = Estacin.PRIMAVERA; // le damos un valor System.out.println("Mi estacin preferida es: "+mia); } }

Como se ve los valores de tipo enumerado se pueden escribir por pantalla, lo que supone una mejora con respecto a C y C++.

4.4 Conversiones de tipo


En una asignacin, el tipo del lado derecho no tiene que ser necesariamente el mismo que el de la variable; basta con que sea un tipo compatible:

Tema 1: Aspectos imperativos del lenguaje


Ejemplo:
double a=5; int b=6; a = 5.4; System.out.println(a); a = b; System.out.println(a);

Todas estas operaciones son correctas. En cambio si hacemos:


double a=5; int b=6; b = 5.4; System.out.println(b); b = a; System.out.println(b);

Obtenemos un error de tipo en tiempo de compilacin. Idea: Recordando la imagen de las variables como "cajas", podemos imaginarnos que a cajas diferentes corresponden cajas de distintos tamaos. As un valor real (double) debe ser una caja en la que debe caber tanto un real como un entero, ya que los enteros son tambin nmeros reales, pero no al revs. Sin embargo, tambin es posible realizar conversiones de tipo explcita de un tipo "mayor" a un tipo "menor" (con la inevitable prdida de precisin), escribiendo (tipoMenor) expresinDeTipoMayor Como por ejemplo:
double a=5.99999; int b; b = (int)5.8; System.out.println(b); b = (int)a; System.out.println(b);

Pregunta 1.i Qu escribir este fragmento de programa?

Tema 1: Aspectos imperativos del lenguaje


Observacin: A la operacin de conversin entre tipos se le suele llamar en terminologa de lenguajes de programacin cast.

Aviso: Un error comn es pensar que al hacer un cast entre tipos numricos los valores se "redondean" al valor ms cercano del tipo destino, pero en realidad se truncan, es decir se pierde su parte decimal. Por supuesto hay tipos incompatibles entre los que no hay posible conversin. Por ejemplo si intentamos compilar:
public class Principal { public enum Estacin {PRIMAVERA, VERANO, OTOO, INVIERNO}; public static void main(String[] args) { Estacin mia; mia = Estacin.PRIMAVERA; int a = (int) mia; } }

obtendremos un error: inconvertible types.

5 Estructuras de Control
5.1 Instruccin de seleccin if 5.2 El operador ? 5.3 Instruccin de seleccin mltiple switch 5.4 Bucle while 5.5 Bucle for 5.6 Bucle do ... while

5.1 Instruccin de seleccin if


Sintaxis:

if (expresin booleana) Instruccin1 [else Instruccin2]

Tema 1: Aspectos imperativos del lenguaje


Notas:

La parte else es opcional. Tanto Instruccin1 como Instruccin2 deben ser, o bien una instruccin simple acabada en ; o bien una instruccin compuesta entre llaves { ... }.

Ejemplo:
import java.util.Scanner; public class Principal { // muestra el mayor de entre dos enteros ledos de teclado public static void main(String[] args) { Scanner sc = new Scanner(System.in); int x=sc.nextInt(), y=sc.nextInt(); if (x>y) System.out.println(x); else System.out.println(y); } // main }

Ejemplo:
import java.util.Scanner; public class Principal { // lee dos enteros de teclado y los muestra ordenados de menor a mayor public static void main(String[] args) { Scanner sc = new Scanner(System.in); int x=sc.nextInt(), y=sc.nextInt(); int mximo, mnimo; if (x>y) { mximo = x; mnimo = y; } else { mximo = y; mnimo = x; } System.out.println(mnimo+" "+mximo);

Tema 1: Aspectos imperativos del lenguaje


} // main }

Ejemplo: Mximo de 3 valores


import java.util.Scanner; public class Principal { // calcula el mayor de 3 enteros public static void main(String[] args) { Scanner sc = new Scanner(System.in); int m, x=sc.nextInt(), y=sc.nextInt(), z=sc.nextInt(); // queremos que m tome el mayor de los valores entre x, y , z if (x>y) // el mayor es x o z if (x>z) m = x; else m = z; else // el mayor es y o z if (y>z) m = y; else m = z; System.out.println( "El mayor es"+ m); } // main }

Ejemplo: If sin parte else.


import java.util.Scanner; public class Principal { // lee dos enteros de teclado y los ordena de mayor a menor public static void main(String[] args) { // leemos los valores a comparar Scanner sc = new Scanner(System.in); int x=sc.nextInt(), y=sc.nextInt(); // si x>y no hacemos nada, pero si x<=y intercambiamos los valores if (x<=y) { // intercambiar x con y. Pregunta 1.j: escribir el cdigo ...... } // mostramos los valores ordenados System.out.println(x+" "+y);

Tema 1: Aspectos imperativos del lenguaje


} }

Pregunta 1.k Cmo cambiar el comportamiento del programa anterior cambiamos la instruccin System.out.println(x+" "+y); por System.out.println(x+y);?

5.2 El operador ?
En Java (y en C++ y C) la instruccin condicional if se puede escribir en forma de expresin, utilizando el smbolo ? para separar la condicin de la parte if y el smbolo : antes de la parte else, como muestra el siguiente ejemplo: Ejemplo:
Scanner sc = new Scanner(System.in); int x=sc.nextInt(), y=sc.nextInt(); int z; // queremos que z tome el mayor de los valores entre x e y z = x > y ? x : y; // tambin if x>y then z=x else z=y System.out.println("El mayor es: "+z);

5.3 Instruccin de seleccin mltiple switch


Esta instruccin se utiliza cuando queremos distinguir entre distintos valores (ms de 2, sino se utiliza if) que puede tomar una misma expresin. Es similar a la expresin case de Pascal. Sintaxis:

switch(expr) { case valor1: ... // instrucciones break; case valor2: ... // instrucciones break; ... ... // otros casos ... default: // instrucciones }
La expresin se evala y se ejecutan las instrucciones que corresponden al valor. Si ninguno de los casos se cumple se ejecutan las rdenes de la parte default (que es opcional).

Tema 1: Aspectos imperativos del lenguaje


Ejemplo:
int mes; Scanner sc = new Scanner(System.in); System.out.print("Introduce un valor entre 1 y 12: "); mes = sc.nextInt(); switch(mes) { case 1: System.out.println("Enero"); break; case 2: System.out.println("Febrero"); break; case 3: System.out.println("Marzo"); break; case 4: System.out.println("Abril"); break; case 5: System.out.println("Mayo"); break; case 6: System.out.println("Junio"); break; case 7: System.out.println("Julio"); break; case 8: System.out.println("Agosto"); break; case 9: System.out.println("Septiembre"); break; case 10: System.out.println("Octubre"); break; case 11: System.out.println("Noviembre"); break; case 12: System.out.println("Diciembre"); break; default: // en otro caso ... System.out.println("Ese valor no corresponde a ningn mes!!!"); } // switch

Aviso: Si no se introduce el break se ejecutan las instrucciones del caso siguiente.

Ejemplo:

Tema 1: Aspectos imperativos del lenguaje


int mes=2; switch(mes) { case 1: System.out.println("Enero"); break; case 2: System.out.println("Febrero"); case 3: System.out.println("Marzo"); break; ..... // el programa escribir: // Febrero // Marzo

Esto es til, en ocasiones, para agrupar casos: Ejemplo:


Scanner sc = new Scanner(System.in); int mes, ao; int dasMes; System.out.print("Mes (entre 1 y 12): "); mes = sc.nextInt(); System.out.print("Ao"); ao = sc.nextInt(); // clculo de los das que tiene el mes: switch(mes) { case 4: case 6: case 8: case 10: dasMes = 30; break; case 2: if ( ((ao % 4 == 0) && (ao % 100 != 0)) || (ao % 400 == 0) ) dasMes = 29; else dasMes = 28; break; default: // en otro caso 31 dasMes = 31; } // switch

5.4 Bucle while


Esta instruccin repetitiva (bucle), tiene la siguiente sintaxis:

while (expresin booleana) Instruccin

Tema 1: Aspectos imperativos del lenguaje


La instruccin se repite mientras la condicin se evale a true. En particular, si la primera vez ya no se cumple, la instruccin se ejecutar 0 veces. Ejemplo: Comprobar si un nmero es primo.
import java.util.Scanner; public class Principal { // comprueba si un nmero dado es primo public static void main(String[] args) { // leemos el valor del que se quiere saber si es primo Scanner sc = new Scanner(System.in); int x=sc.nextInt();; // utilizamos una variable que indica si puede ser primo boolean primo = x >1 ? true : false ; // otra variable para almacenar un posible divisor int i=2; while (i<x && primo) { if (x % i == 0) primo = false; // i divide a x else i++; // para comprobar el siguiente } // mostramos el resultado if (primo) System.out.println(x+" es primo"); else System.out.println(x+" no es primo"); } }

Aviso: Un error habitual es olvidar modificar las variables que se encuentran en la condicin del bucle. Esto da lugar a programas que no terminan.

Pregunta 1.l Cmo se podra mejorar la condicin del bucle para que ste diera el menor nmero de iteraciones ("vueltas") posible?

Pregunta 1.m Sustituye la instruccin "if" por otra (u otras) que slo usen el operador "?" y que produzcan el mismo resultado

Tema 1: Aspectos imperativos del lenguaje


5.5 Bucle for
Su sintaxis es:

for (expresin1; condicin_booleana; expresin2) Instruccin


Descripcin: 1. Primero se ejecuta la expresin1 2. Se comprueba la condicin booleana. Si es true se continua por el paso 3, y en caso contrario fin del bucle. 3. Ejecutar la Instruccin (que puede ser una instruccin compuesta). 4. Se ejecuta la expresin2 y se va al paso 2.

Observacin: La expresin1 suele contener la inicializacin de las variables que intervienen en el bucle. La expresin2 suele contener las instrucciones necesarias para actualizar parte de dichas variables. Ejemplo:
// contando del 1 al 10 int i; for (i=1; i<=10; i++) System.out.print(i); // escribir i

Ejemplo: Programa que escribe todos los divisores de un nmero dado


import java.util.Scanner; public class Principal { // divisores de uno dado public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("Introduzca el nmero: "); int n=sc.nextInt();; System.out.print("Factores de "+n+": "); for (int i = 1; i<=n; i++) if (n % i == 0) // i divide a n System.out.print(i+" "); System.out.println(); } }

Ejemplo de ejecucin del programa:

Tema 1: Aspectos imperativos del lenguaje


Introduzca el nmero: 2005 Factores de 2005: 1 5 401 2005

Cundo usar while y cundo for? En general se utiliza for cuando el nmero de iteraciones se puede determinar antes de comenzar, es decir no depende de valores que se obtienen en el bucle, y while en otro caso.

5.6 Bucle do...while


Similar al bucle while, pero con la particularidad de que se repite al menos una vez. Su sintaxis es:

do Instruccin1 while condicinBooleana


Ejemplo: Preguntando al usuario que si quiere grabar antes de salir
import java.util.Scanner; public class Principal { // preguntando al usuario que se quiere salir public static void main(String[] args) { Scanner sc = new Scanner(System.in); String respuesta; do { System.out.println("Grabar los datos antes de salir?"); respuesta = sc.nextLine(); } while (!respuesta.equals("si") && !respuesta.equals("no")); if (respuesta.equals("si")) .... // grabar } }

Observacin: Los valores de tipo String no se deben comparar con == porque String no es un tipo primitivo. Para ver si un String es igual a otro se usa el mtodo equals, que compara objetos tal y como ilustra el ejemplo.

Tema 1: Aspectos imperativos del lenguaje

Tabla A: Palabras Reservadas


Se llaman palabras reservadas a aquellas ocupadas por la sintaxis del lenguaje y que no puede utilizar el usuario para sus propsitos. Por ejemplo, no podemos llamar a una variable for o return, al ser esta una palabra reservada del lenguaje. La lista de palabras reservadas en el lenguaje es: abstract do break byte case catch char class default else false final float if implements private protected return short static strictfp super switch instanceof public interface long new null package this throw throws transient true try void volatile while

boolean double import extends int

finally native

continue for

synchronized enum

Ya hemos visto algunas, y al final del curso conoceremos casi todas.

Tabla B: Rango de los tipos primitivos


Aqu tenemos una lista con todos los tipos primitivos y el rango de valores que pueden tomar. Tipo byte short int long float double char Descripcin Entero con signo Entero con signo Entero con signo Entero con signo Real con signo Real de doble precisin Carcter Unicode -128 a 127 -32768 a 32767 -2147483648 a 214783647 -922117036854775808 a +922117036854775808 1.40239846e-45 a 3.40282347e+38 4.94065645841246544e-324 a 1.79769313486231570e+308 \u0000 a \uFFFF Rango

Tema 1: Aspectos imperativos del lenguaje


boolean Valor lgico true o false

Tabla C: Asociatividad de los Operadores


Asociatividad Operador Izq. a Der. Izq. a Der. Izq. a Der. Izq. a Der. Izq. a Der. Izq. a Der. Izq. a Der. Izq. a Der. Izq. a Der. Izq. a Der. Der. a Izq. Der. a Izq. Der. a Izq. Der. a Izq. *, /, % +, <<, >>, >>> <, >, <=, >=, instanceof ==, !=, & ^ | && || ?: ++, --, +, -, ~, !, (tipo de dato) =, *=, /=, %=, +=, -= <<=, >>=, >>>=, &=, ^=, !=

Tema 2: Utlizacin de Objetos

Tema 2: Utilizando objetos


1.- Qu es un objeto? 2.- Los objetos como instancias de clases 3.- Ejemplos: Las clases Math y String 4.- Arrays 5.- Envoltura de tipos primitivos 6.- La clase Vector

1.- Qu es un objeto?
1.1 Concepto de objeto 1.2 Acceso a los componentes de un objeto 1.3 Mtodos 1.4 Los dos puntos de vista

1.1 Concepto de objeto


El concepto bsico de la programacin orientada a objetos es, por supuesto, el de objeto. Desde un punto de vista informal un objeto es cualquier "ente". Algunos ejemplos de objetos: Mi bicicleta Un rectngulo de lados paralelos a los ejes de coordenadas El edificio de ciencias fsicas de la U.C.M. Una agenda de telfonos Bertoldo Pedralbes de la Dehesa. En programacin se intenta recoger esta idea. Para ello se distinguen dos partes de un objeto: Sus propiedades o atributos Las acciones que puede realizar Las caractersticas se representarn mediante un conjunto de variables, mientras que el comportamiento lo determinarn los mtodos (funciones en el caso de Java). Aunque no sea una definicin precisa podemos decir entonces que:

Definicin: Un objeto es una agrupacin de mtodos y atributos.

Tema 2: Utlizacin de Objetos


Ejemplos: Un Rectngulo Mi Bicicleta Atributos string color="Azul" int velocidad=20 int marcha=2 int girosPorMinuto=120 Mtodos void frena() void cambiaMarcha(int nuevaMarcha) void cambiaGPM(int nuevoGPM) int valorVelocidad() Atributos int x=10 int y=20 int lx=100 int ly=200 Mtodos void mueve(int nuevaX, int nuevaY) int getX() int getY() int getLx() int getLy() int rea() Atributos String Nombre="Bertoldo Pedralbes de la Dehesa" int edad=23 Mtodos void trabaja() void duerme() void prestameUnosEurosAnda(int cantidad) Bertoldo

El conjunto de atributos de un objeto identifica su estado, que puede variar en el tiempo. Aunque al frenar la velocidad de mi bicicleta vare, o Bertoldo cumpla un ao ms, o movamos el rectngulo a otra posicin no se consideran objetos diferentes (un Budista Zen no estara de acuerdo). Por tanto el conjunto de atributos y mtodos es siempre el mismo, pero no el estado (contenido de los atributos), que ir cambiando a lo largo de la vida del objeto. Los objetos se representan en los programas mediante variables del tipo (clase) adecuados.

1.2 Acceso a los componentes de un objeto

Tema 2: Utlizacin de Objetos


Para acceder a los componentes de un objeto se utiliza el operador '.'. Por ejemplo si mi bicicleta est representada en el programa mediante una variable de nombre miBicicleta, puedo indicar que he cambiado de marcha escribiendo
miBicicleta.cambiaMarcha(1);

De igual manera se podra acceder a los atributos si estos se declaran como public pero salvo excepciones esto no se hace as. La razn es que pudiramos podramos llevar al objeto a un estado inconsistente.

Ejemplo 1: En el caso de la bicicleta podemos pensar que la velocidad se calcula a partir de la marcha que est seleccionada y del nmero de giros por minuto. Permitir que se cambie la velocidad arbitrariamente incumplira esta relacin y dara lugar a valores inconsistentes.

Ejemplo 2: Igualmente podemos pensar que la bicicleta tiene un nmero de marchas limitado. A travs del mtodo cambiaMarcha() podemos controlar que no se sobrepase este lmite: por ejemplo se puede mostrar un mensaje de error si se intenta superar el mximo, o simplemente ignorar la peticin; pero dejar que el usuario del objeto cambie la marcha directamente puede dar lugar a estados del objeto no permitidos, y por tanto a errores en el programa difciles de detectar.

A la posibilidad de ocultar partes del objeto del exterior se la conoce como encapsulacin. Para consultar y modificar los atributos se deben utilizar los mtodos del objeto.

1.3 Mtodos
En C, Pascal, Fortran y otros lenguajes similares las variables se pasan a los procedimientos, funciones, etc. que las utilizan. En los lenguajes orientados a objetos, los mtodos expresan acciones que los objetos pueden llevar a cabo.

Observacin: En programacin orientada a objetos se les pide a los objetos que efecten acciones llamando a sus mtodos.

Ejemplos: Considera la siguiente instruccin:

Tema 2: Utlizacin de Objetos


ventana.setVisible(true);

Decir que la instruccin significa mostrar "ventana" no sera correcto; sera mejor decir que la instruccin le pide a "ventana" que se muestre. Nos fijamos ahora en la siguiente instruccin:
miBicicleta.cambiaMarcha(1);

Le pedimos a la bicicleta que cambie de marcha. Puede ser que la bicicleta no nos haga caso; por ejemplo si esta en la marcha 3 y necesita que se disminuya de una en una. Si es posible acceder a la peticin el mtodo modificar el estado del objeto, cambiando los atributos marcha y velocidad. Por ltimo:
bertoldo.prestameUnosEurosAnda(100);

le pedira 100 euros a Bertoldo.

1.4 Los dos puntos de vista


La encapsulacin de los objetos crea una barrera, un muro:

Esta divisin genera dos puntos de vista, segn al lado de la barrera en el que nos situemos: El usuario del objeto. Ve el objeto desde fuera. Dado que los atributos no se pueden modificar, no importan. Slo se fija en los mtodos a los que s puede acceder.

Tema 2: Utlizacin de Objetos

Ejemplo: Al utilizar el objeto miBicicleta nos da igual si existe un atributo velocidad o si sta se calcula a travs de otros atributos cuanto hace falta; lo nico que importa es saber que existe un mtodo valorVelocidad() para obtener el valor de la velocidad, no cmo se las apaa el objeto para conseguirlo.

El diseador de la clase a la que pertenece el objeto. Se puede imaginar que se encuentra "dentro" del objeto, pudiendo acceder a sus atributos y modificarlos libremente, as como usar los mtodos. Debe pensar en los mtodos que debe proporcionar al usuario del objeto.

Tema 2: Utlizacin de Objetos

Ejemplo: Al disear el objeto miBicicleta hay que tomar decisiones tales como debe incluirse un atributo velocidad? debe ser un nmero entero o real? debe proporcionarse al usuario un mtodo para acceder al atributo, caso de incluirse?

Los dos puntos de vista pueden corresponder a la misma persona en diferentes momentos: nosotros seremos usuarios de los objetos que hemos diseado previamente. Esta dualidad (casi esquizofrenia) debe tenerse presente en todo momento.

Observacin : Java permite encapsular los atributos pero no obliga a hacerlo; deja la decisin al programador. En (raras) ocasiones se puede decidir que algn atributo (generalmente un atributo constante) no est encapsulado. Otras veces (ms frecuentemente) decidiremos que algunos mtodos estn encapsulados porque son internos a la clase y conceptualmente no deben ser visibles para el usuario.

Observacin : Para indicar que un atributo, mtodo o clase es accesible para el usuario (es decir no est encapsulado) se escribe precedido por la palabra public. Cuando s est encapsulado se

Tema 2: Utlizacin de Objetos


puede preceder por private, protected o por ninguna palabra, segn el nivel de "encapsulamiento" que deseemos (esto lo estudiaremos en detalle ms adelante).

Observacin : Para distinguir mejor estos dos puntos de vista en el este captulo nos vamos a concentrar slo en el punto de vista del usuario de objetos. En el siguiente captulo nos centraremos en el de diseador.

2.- Los objetos como instancias de clases


2.1 Concepto de clase 2.2 Qu necesitamos saber de una clase? 2.3 Ms sobre la inicializacin de objetos 2.4 Referencias en Java 2.5 Ejercicio

2.1 Concepto de clase


Java es un lenguaje con tipos. Eso significa que todas las variables deben pertenecer a algn tipo. Los tipos a los que pertenecen los objetos se denominan clases.

Definicin: Una clase es una nocin abstracta. Define los atributos y mtodos comunes a un conjunto de objetos.

Por tanto en lugar de disear cada objeto por separado se escribe una clase que contendr la "idea" comn de todos los objetos del mismo tipo. Ejemplos:
miBicicleta podra ser un objeto de clase Bicicleta:

Tema 2: Utlizacin de Objetos


Bicicleta miBicicleta;

ventana ser un objeto de la clase predefinida Frame :


Frame ventana;

Por ltimo, bertoldo podra ser un objeto de clase Persona:


Persona bertoldo;

Observacin: Hay ciertas clases para las que no tiene sentido declarar objetos. Un ejemplo es la clase Math que veremos posteriormente. A estas clase se las llama estticas.

2.2 Qu necesitamos saber de una clase?


Para utilizar una clase ya definida debemos conocer cierta informacin bsica. Como ejemplos (esperemos que ilustrativos) vamos a utilizar la clase Scanner, a la que aadiremos una supuesta clase para representar una partcula movindose en el plano con velocidad constante cuyo fichero de ayuda es:
Overview Package Class Tree Deprecated Index Help
PREV CLASS NEXT CLASS SUMMARY: NESTED | FIELD | CONSTR | METHOD FRAMES NO FRAMES All Classes DETAIL: FIELD | CONSTR | METHOD

mecanica.movimiento

Class Particula
java.lang.Object mecanica.movimiento.Particula

public class Particula extends java.lang.Object

Field Summary
private vx

Tema 2: Utlizacin de Objetos


double Velocidad en x de la partcula private vy double Velocidad en y de la partcula private x double Coordenada x de la partcula private y double Coordenada y de la partcula

Constructor Summary
Particula()

construye una nueva partcula en la pos. (0,0) y con velocidad (0,0)


Particula(double xIni, double yIni, double vxIni, double vyIni)

construye una nueva partcula en la posicin (xIni,yIni) con velocidad (vxIni,vyIni)

Method Summary
double getVx()

velocidad en x de la partcula
double getVy()

velocidad en y de la partcula
double getX()

coordenada x de la partcula
double getY()

coordenada y de la partcula
double mduloVelocidad()

Mdulo del vector velocidad de la prticula.


void posicin(double t)

modifica la posicin de la partcula suponiendo que se mueve a la velocidad actual durante t segundos y que parte de la posicin actual.

Tema 2: Utlizacin de Objetos


boolean puedenChocar(Particula p)

Indica si sta partcula puede chocar con la partcula p para algn tiempo t para algn t puede ser positivo, negativo o 0, es decir si las dos trayectorias se cruzan o si por el contrario son paralelas
void setVx(double nuevaVx)

modifica la velocidad en x de la partcula


void setVy(double nuevaVy)

modifica la velocidad en y de la partcula


void setX(double nuevaX)

modifica la posicin en x de la partcula


void setY(double nuevaY)

modifica la posicin en y de la partcula Methods inherited from class java.lang.Object


clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Overview Package Class Tree Deprecated Index Help


PREV CLASS NEXT CLASS SUMMARY: NESTED | FIELD | CONSTR | METHOD FRAMES NO FRAMES All Classes DETAIL: FIELD | CONSTR | METHOD

Vamos a ver cmo aprovechar esta informacin para definir y manejar objetos de la clase: Paquete: Lo primero que debemos conocer es el paquete al que pertenece la clase para importarla. La nica excepcin son las clases que pertenecen al paquete del sistema java.lang que estn ya importadas por defecto. A este paquete pertenecen, entre otras, las clases System, String y Math, lo que explica que nunca tengamos que importarlas. Como hemos visto la clase Scanner pertence al paquete java.util, y vemos que la clase Particula pertenece a un paquete mecanica.movimiento. Por tanto una clase Principal que utilice estas dos clases comenzar:
import java.util.Scanner; import mecanica.movimiento.Particula; public class Principal {

Tema 2: Utlizacin de Objetos


Observacin: El orden relativo entre las distintas instrucciones import es irrelevante en Java. Lo importante es que estn antes de la definicin de la clase.

Atributos pblicos: En ocasiones las clases disponen de atributos pblicos, en particular de constantes. Veremos ejemplos cuando estudiemos la construccin de interfaces grficos. Como vemos en la seccin Field Summary, la clase Particula tiene 4 atributos de tipo double: x,y,vx,vy. Las coordenadas (x,y) indican la posicin de la partcula, mientras que (vx,vy) indican su velocidad. Sin embargo se trata de atributos privados, por lo que no podemos acceder a ellos directamente, slo a travs de las constructoras y mtodos. Constructoras: Se trata de un tipo especial de mtodos que sirven para crear e inicializar objetos de una clase. Reciben como parmetro valores que permiten inicializar el objeto y su nombre coincide con el de la clase. Siempre se usan precedidos por la palabra reservada new. Ya hemos visto un primer ejemplo con la clase Scanner
Scanner sc = new Scanner(System.in);

En este caso la constructora recibe como parmetro el fichero del que se va a leer. Supongamos que nos dicen que la clase Partcula tiene las siguientes constructoras: Particula(): Constructora por defecto, crea una partcula situada en el origen de coordenadas y con velocidad (0,0). Partcula(double xIni, double yIni, double vxIni, double vyIni): Construye una partcula situada en el punto (xIni,yIni) origen de coordenadas y con velocidad (0,0). Entonces las siguientes declaraciones e inicializaciones de son vlidas:
Particula p1 = new Particula(); Particula p2 = new Particula(10,10,-5.5,8.2); p1

es por tanto la partcula situada en el punto (0,0) y con velocidad (0,0), mientras que p2 est situada sobre el punto (10,10) y se mueve con velocidad -5.5 en x y 8.2 en y. Tanto p1 como p2 son objetos de la clase Particula.

Observacin: En Java el programador se encarga de crear objetos, pero no de destruirlos. Esto lo hace Java automticamente cuando detecta que el objeto ya no puede ser utilizado. A este mecanismo se le llama recogida automtica de basura. Si en algn caso interesa forzar a Java a liberar un objeto podemos usar el mtodo System.gc().

Tema 2: Utlizacin de Objetos


Mtodos: Los mtodos son el medio habitual de interaccin con un objeto. Entre otros, es normal encontrar mtodos de consulta y mtodos de actualizacin. Mtodos de consulta u observadores: No modifican el estado del objeto (sus atributos). Su propsito es ofrecer informacin acerca del objeto. Cuando Por ejemplo en la clase Particula tenemos los mtodos de consulta getX(),getY(),getVx(), getVy(), mduloVelocidad y puedenChocar. Un ejemplo de utilizacin de estos mtodos:
import mecanica.movimiento.Particula; public class Principal { public static void main(String[] args) { Particula p1 = new Particula(); Particula p2 = new Particula(10,10,-3,4); System.out.println(p1.mduloVelocidad()); System.out.println(p2.mduloVelocidad()); System.out.println(p2.puedenChocar(p1)); } }

Pregunta 2.a Qu escribir el programa?

Pregunta 2.b Aunque la clase Particula no hubiese ningn mtodo mduloVelocidad() nosotros, como usuarios de la clase, podramos calcular el mdulo apoyndonos en el resto de los mtodos. Demustralo completando el siguiente ejemplo:
import mecanica.movimiento.Particula; public class Principal { public static void main(String[] args) { Particula p; // por aqu se le da el valor a p // no importa cmo ni qu valor .........

Tema 2: Utlizacin de Objetos


System.out.print("Mdulo de la velocidad: "); // escribir a continuacin el mdulo de la velocidad de p // pero si usar el mtodo mduloVelocidad } }

Ayuda: Para calcular la raz cuadrada de un nmero real x se utiliza en Java una llamada de la forma Math.sqrt(x).

Mtodos modificadores: Cambian los atributos del objeto. En la clase Particula los mtodos setX, setY, setVx, setVy y posicin son modificadores. Un ejemplo de utilizacin de estos mtodos:
import mecanica.movimiento.Particula; public class Principal { public static void main(String[] args) { Particula p = new Particula(10,10, 2,0); // la partcula se mueve durante 20 segundos p.posicin(20); System.out.println("x: "+p.getX()+" y: "+p.getY()); } }

Pregunta 2.c Qu escribir el programa?

Observacin: La divisin entre mtodos observadores y mtodos modificadores es slo conceptual: algn mtodo puede ser las dos cosas o no encajar bien en ninguna de las dos.

Tema 2: Utlizacin de Objetos


2.3 Ms sobre la inicializacin de objetos
En este apartado vamos a usar como ejemplo una clase para representar rectngulos con los lados paralelos a los ejes de coordenadas:
Overview Package Class Tree Deprecated Index Help
PREV CLASS NEXT CLASS SUMMARY: NESTED | FIELD | CONSTR | METHOD FRAMES NO FRAMES All Classes DETAIL: FIELD | CONSTR | METHOD

figuras

Class Rectangulo
java.lang.Object figuras.Rectangulo

public class Rectangulo extends java.lang.Object

Clase que representa un rectngulo con lados paralelos a los ejes de coordenadas

Field Summary
private lx int ancho (lx) y alto (ly) del rectngulo private ly int ancho (lx) y alto (ly) del rectngulo private x int esquina superior izquierda del rectngulo private y int esquina superior izquierda del rectngulo

Constructor Summary

Tema 2: Utlizacin de Objetos


Rectangulo(int valorX, int valorY, int valorLx, int valorLy)

construye un rectngulo a partir de los valores iniciales de sus atributos

Method Summary
int rea()

devuelve el rea del rectngulo


int getLx() int getLy() int getX() int getY() void mueve(int nuevaX, int nuevaY)

cambia la esquina sup. izquierda del rectngulo Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Overview Package Class Tree Deprecated Index Help


PREV CLASS NEXT CLASS SUMMARY: NESTED | FIELD | CONSTR | METHOD FRAMES NO FRAMES All Classes DETAIL: FIELD | CONSTR | METHOD

La idea abstracta de clase se concreta al definir un objeto particular. Como hemos visto las definiciones de los objetos se hacen igual que las de los tipos simples:
nombreDeTipo nombreDeVariable;

Como por ejemplo:


int i; // un entero char c; // un carcter; Rectngulo a; // Un rectngulo

Tema 2: Utlizacin de Objetos


Rectngulo b; // Otro rectngulo Frame v; // una ventana

Muy Importante: El objeto tras ser declarado no est listo para ser usado. Antes necesita
ser inicializado.

Hay dos formas de inicializar un objeto: Mediante el operador new() . Por ejemplo:
a = new Rectngulo(10,10,20,20) v = new Frame("Una ventana");

En este caso se crea una nueva variable de tipo Rectngulo. Los valores entre parntesis corresponden a los argumentos de la csntructora declarada en la clase (en este caso son los valores iniciales de los atributos). Mediante la asignacin de una variable del mismo tipo que ha sido previamente inicializada.
b = a;

Observacin: Un mismo objeto puede ser inicializado varias veces a lo largo de un programa. Lo nico que hay que tener en cuenta es que al inicializarse se pierden los valores anteriores de sus atributos.

2.4 Referencias en Java


En realidad las variables de tipo objeto no contienen objetos, sino referencias a objetos. Una forma de imaginarlo es que la variable contiene una "flecha" que nos permite acceder a un objeto. Por tanto las variables tipo objeto son en esto completamente diferentes a las variables de tipos bsicos, que s contienen un valor en lugar de una referencia:

Tema 2: Utlizacin de Objetos

Aunque casi siempre hablaremos de la variable que contiene la referencia al objeto como si fuera el propio objeto, interesa recordar que se trata de conceptos diferentes. Esto es especialmente importante cuando se realiza una asignacin entre variables de tipo objeto. Veamos el siguiente programa:

Principal.java
import figuras.Rectngulo; public class Principal { public static void main(String[] args) { int a,b; a = -5; b = a; b = 10; System.out.println("a: "+a); Rectngulo r,s; r = new Rectngulo(0,0,50,80); s = r; s.mueve(30,20); System.out.println("r.x: "+r.getX()+" r.y: "+r.getY()); } }

Est claro que este programa comenzar escribiendo a: -5 , ya que la asignacin b=10 no modifica el valor de a, que nunca deja de ser -5. Sin embargo la segunda parte del programa ya no es tan inmediata, al ser r,s referencias a objetos. Tras la declaracin Rectngulo r,s; las dos referencias estn an sin inicializar y contienen un valor especial llamado null.

Tema 2: Utlizacin de Objetos


Tras la instruccin r = new Rectngulo(0,0,50,80); se crea un nuevo rectngulo y r es una referencia a l. s contina sin estar inicializado.

La instruccin s = r; inicializa s con el valor de r. Pero en este punto hay que recordar que r no contiene ningn objeto, sino una referencia a un objeto, y es la referencia lo que se copia a s:

De esta forma, a pesar de tener dos variables de tipo rectngulo inicializadas tenemos un nico objeto y no dos. En realidad se puede decir que tras la asignacin s y r son la misma variable. La instruccin s.mueve(30,20); llama al mtodo mueve del objeto referenciado por s, que modifica sus atributos x e y:

Tema 2: Utlizacin de Objetos

Al quedar modificado el objeto referenciado por s queda igualmente el referenciado por r, ya que son el mismo. Dicho de manera poco rigurosa pero que puede aclarar:

Al modificar s estamos modificando r


Por tanto es lgico que la siguiente lnea, que pregunta por los valores x e y de r escriba por pantalla:
r.x: 30 r.y: 20

Aviso: El concepto de referencia es fundamental en Java. Muchos errores de programacin en este lenguaje provienen de olvidar que las variables tipo objeto son en realidad referencias a objetos.

Aviso: Si comparamos dos objetos con == estamos comparando si son referencias al mismo objeto. Para saber si se trata realmente de dos objetos con los mismos atributos debemos usar el mtodo equals de cualquiera de los dos objetos. Este mtodo siempre est definido.

Tema 2: Utlizacin de Objetos


2.5 Ejercicio
Examina el siguiente programa, indica qu instrucciones son incorrectas (por errores por sintaxis o porque harn que el programa no funciones correctamente) y por qu. Despus considera el programa que resulta tras eliminar las instrucciones incorrectas, e indica los valores que van tomando los valores a cada paso del programa.

Principal.java

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34

import figuras.Rectngulo; public class Principal { public static void main(String[] args) { rec1 = new Rectngulo(3,4,5,6); Rectngulo a = new Rectngulo(0,0,5,10); Rectngulo b = new Rectngulo(0,0,20,30); Rectngulo c = b = a; Rectngulo d; System.out.println("c.x: "+c.x+ " b.x: "+b.x+ " a.x: "+a.x); System.out.println("c.x: "+c.getX()+ " b.x: "+b.getX()+ " a.x: "+a.getX()); d.mueve(80,80); d = a; d.mueve(80,80); System.out.println("a.x: "+a.getX()+ " a.y: "+a.getY()); System.out.println("d.x: "+d.getX()+ " d.y: "+d.getY()); d = new Rectngulo(0,0,0,0); System.out.println("a.x: "+a.getX()+ " a.y: "+a.getY()); System.out.println("d.x: "+d.getX()+ " d.y: "+d.getY()); } }

Pregunta 2.d Qu escribir el programa?

Tema 2: Utlizacin de Objetos

3.- Ejemplos: Math y String


3.1 La clase Math 3.2 La clase String Vamos a presentar ahora dos clases que forman parte del lenguaje Java. Nos servirn de ejemplo de los conceptos aprendidos en los puntos anteriores, adems de tener inters en s mismas porque presentan algunas formalidades. De todas formas la descripcin que vamos a hacer no es ni mucho menos exhaustiva; para una visin completa de las clases tendremos que consultar la documentacin de Java.

3.1 La clase Math


Esta es una clase sin constructoras y por tanto no pueden declararse objetos de tipo Math. Todos sus mtodos son estticos, lo que significa que se deben escribir precedidos por el nombre de la clase. Tambin contiene 2 constantes estticas declaradas como:
final static double E = ....; final static double PI = .....;

El siguiente ejemplo da un repaso a algunos de sus mtodos.


Matemticas.java

public class Matemticas { public static void main(String [] args) { double x = Math.PI/2; int a = -3; // valor absoluto System.out.println(Math.abs(x));// 1.5707963267948966 System.out.println(Math.abs(a));// 3 // redondeo al entero (largo) mas proximo System.out.println(Math.round(3.8));// 4 // redondeo al entero mas proximo repr. como double System.out.println(Math.rint(3.8));// 4.0 // exp(x) y log(x): e^x y ln x respect.

Tema 2: Utlizacin de Objetos


System.out.println(Math.log(Math.exp(5))); // // raz cuadrada System.out.println(Math.sqrt(2)); // 1.4142135623730951 // potencia System.out.println(Math.pow(0.5,0.3));//0.8122523963562356 // de grados a radianes System.out.println(Math.toRadians(180));//3.141592653589793 // de radianes a grados System.out.println(Math.toDegrees(Math.PI/2.0)); // 90.0 // trigonomtricas: sin, cos, tan (en radianes) System.out.println(Math.sin(Math.PI));//1.2246467991473532E-16 // trigonomtricas inversas: asin,acos,atan System.out.println(Math.toDegrees(Math.atan(1))); // 45.0 // atan tambin puede darse en coordenadas rectangulares System.out.println(Math.atan2(0,10)); // // max y min System.out.println(Math.max(5.8,-1.6)); // 5.8 // generacin de un nm. aleatorio mayor o igual a 0 // y menor que 1 System.out.println(Math.random()); // 0.4918316988782816 } }

3.2 La clase String


3.2.1 La clase String 3.2.2 La clase StringBuffer

Estas son las clases para representar secuencias de caracteres. Las 2 clases forman parte del paquete java.lang un paquete que es importado en todas las clases sin necesidad de hacerlo explcitamente.

3.2.1 La clase String Se llaman strings a las secuencias de caracteres. Es un tipo muy importante que ya hemos estado utilizando, por ejemplo al escribir System.out.println("hola"), el valor "hola" es una constante de tipo String. En Java se definen dos clases diferentes para manipular cadenas de caracteres: la clase String y la clase StringBuffer. La diferencia es que una vez creado un objeto de tipo String no puede modificar su contenido. En cambio la clase

Tema 2: Utlizacin de Objetos


StringBuffer s permite modificar sus caracteres, longitud, etc. Vamos a explicar las caractersticas de la clase por medio de un ejemplo
EjemploString.java

public class EjemploString { public static void main(String [] args) { // constructoras String s1 = new String("Nadie emprende"); String s2 = new String(); s2 = "este camino"; String s3 = "salvo el crepsculo de otoo"; System.out.println(s1); System.out.println(s2); System.out.println(s3); // longitud de un String (un entero) System.out.println(s2.length()); // 11 // carcter en una posicin determinada. // se comienza a contar desde 0 System.out.println(s1.charAt(0)); // N System.out.println(s1.charAt(1)); // a System.out.println(s3.charAt(s3.length()-1)); // ? System.out.println(s2.charAt(s2.length())); // ? // ----- COMPARACIN ------// esta igualdad pregunta que si son el mismo objeto String a="una cadena"; String b="una cadena"; System.out.println( a==b); // true !!!! // as se pregunta que si tienen la misma cadena System.out.println(a.equals(b)); // true System.out.println(a.equals("Una Cadena")); // ? // igual pero sin tener en cuenta las mayusculas/minusculas System.out.println(a.equalsIgnoreCase("Una Cadena"));// ? // -- BSQUEDA --// posicin que ocupa la primera aparicin del carcter System.out.println(s1.indexOf('e')); // 4 // posicin que ocupa la primera aparicin del carcter // empezando a mirar desde la posicin indicada System.out.println(s1.indexOf('e',5)); // ? // posicin que ocupa la ultima aparicin del carcter System.out.println(s1.lastIndexOf('e')); // 13 // posicin que ocupa la ultima aparicin del carcter // acabando de mirar en la posicin dada

Tema 2: Utlizacin de Objetos


System.out.println(s1.lastIndexOf('e',12)); //? // --- SUBCADENAS --// subcadena empezando desde el carcter 8 System.out.println(s1.substring(8)); // prende // subcadena empezando desde una posicin y // terminando en la posicin indicada-1 String s4 = "abracadabra"; System.out.println(s4.substring(2,5)); // ? // --- CONCATENACIN --// con el mtodo concat System.out.println(s1.concat(s2)); // con el operador + System.out.println(s1+" "+s2+" "+s3); // como son strings, no han quedado modificadas: System.out.println(s1); System.out.println(s2); System.out.println(s3);

} }

Observacin: El smbolo de concatenacin + puede utilizarse tambin con tipos numricos, como por ejemplo:
String s = "Un euro son " + 166.386 + " ex-pesetas";

3.2.2 La clase StringBuffer

Aunque a menudo no es necesario (el tipo String se puede utilizar para construir otros Strings) la clase StringBuffer incluye operaciones especficas para modificar su contenido. La clase BufferString incluye todos los mtodos que hemos visto para String (y que no repetimos en el ejemplo), con excepcin de los mtodos de concatenacin y las constructoras, que son diferentes:
EjemploStringBuffer.java

Tema 2: Utlizacin de Objetos


public class EjemploStringBuffer { public static void main(String [] args) { // -- CONSTRUCTORAS -// a partir de un String StringBuffer b1 = new StringBuffer("Urbano y dulce revuelo"); String s = "inmanencia de la nada"; StringBuffer b2 = new StringBuffer(s); // pero lo siguiente no es vlido // StringBuffer b3 = "as no se puede!"; // espacio para 20 caracteres inicialmente StringBuffer b3 = new StringBuffer(20); // si no se pone nada se incluye inicialmente espacio para 16 caracteres StringBuffer b4 = new StringBuffer(); System.out.println(b1); System.out.println(b2); System.out.println(b3); System.out.println(b4); // aadir caracteres b4.append("Programacin "); b4.append("en Java "); // eliminar caracteres, desde la primera posicin // hasta la ltima-1 b4.delete(3,8); // insertar caracteres tras la posicin indicada b4.insert(3,"fana"); System.out.println(b4); // eliminamos lo que tiene b1 b1.delete(0,b1.length()); // reverse invierte los caracteres System.out.println( (new StringBuffer("soidemersol")).reverse() ); // relaciones con los string String s2 = "alienacin" StringBuffer b5 = new StringBuffer(); // // // // esto no se puede b5 = s2; y esto tampoco s2 = b5;

// pero esto s s2 = b5.toString();

Tema 2: Utlizacin de Objetos


System.out.println(s2+b5.toString()); } }

Observacin: Suele llamarse toString() al mtodo utilizado para convertir un objeto en String. Java hace que todos las clases incluyendo dicho mtodo sean compatibles con el tipo String.

4.- Arrays
4.1 Introduccin 4.2 Declaracin e Inicializacin de arrays 4.3 Acceso a los elementos de un array 4.4 Arrays multidimensionales

4.1 Introduccin
Los arrays, o matrices se sitan a medio camino entre los tipos simples y las clases. Una definicin inicial sera la siguiente: Un array es una coleccin, ordenada secuencialmente, de elementos del mismo tipo.

Al tipo de los elementos del array se le llama tipo base, y puede ser bien un tipo simple o el nombre de una clase. La posicin que ocupa cada elemento se llama ndice del elemento.

Observacin: Como es habitual en Java, el ndice del primer elemento ser el 0. Por tanto un array de n elementos estar definido para valores ndice entre 0 y n-1.

Ejemplo: Array de 4 Strings. 0 1 2 3

"rase" "que" "se" "era"

Tema 2: Utlizacin de Objetos


Se dice que el ndice del String "que" es 1, o que la posicin 1 del array est ocupada por el String "que".

4.2 Declaracin e Inicializacin de arrays


La declaracin de un array tiene dos posibles sintaxis: tipoBase nombreVariable[]; // las dos formas son vlidas y tienen el mismo significado tipoBase []nombreVariable;

Ejemplos:
Particula []puntos; // array de partculas String []palabras; // array de strings boolean []lgicos; // array de valores booleanos

Observacin: A diferencia de otros lenguajes, el tamao del array no se indica en la declaracin. Dicho valor se fijar en la creacin del array.

Importante: Igual que sucede con los objetos, los arrays no pueden ser utilizados hasta que hayan sido inicializados (pueden imaginarse como referencias).

Hay 3 formas de inicializar un array: 1. Dar valores al declarar la variable Este mtodo se utiliza cuando los valores se conocen de antemano. El tamao queda fijado implcitamente por el nmero de elementos en la lista de inicializacin. tipoBase []nombreVariable = {valor1, ..., valorn}; Ejemplos:

Tema 2: Utlizacin de Objetos


Particula []puntos = {new Particula(), new Particula(1,2,10.0,20.0), new Particula(6.5,7.5,-1.0,3.5)}; String boolean []palabras = {"Como", "te", "ves", "me", "vi,", "como", "me", "ves", "te", "vers."}; []lgicos = {true, true, false};

2. Con el operador new Igual que se hace con los objetos, pero indicando el tamao del array, pero siguiendo la sintaxis: nombreVariableArray = new tipoBase[tamaoArray];

Ejemplos:
// se puede inicializar a la vez que se crea Particula []partculas = new Particula[5]; // o despus Particula []msPartculas; msPartculas = new Particula[100]; // se puede hacer new varias veces, como ocurre con los objetos // pero recordar al hacerlo se pierde el valor anterior particulas = new Particula[10];

3. Asignndole otro array ya inicializado Igual que hemos visto en el caso de los objetos Ejemplos:
Particula []partculas = {new Particula(3.5,2.4,-1.0,-1.0), new Particula(), new Particula()};

// o despus Particula []msPartculas = partculas; msPartculas = new Particula[100];

4.3 Acceso a los elementos de un array


Una array se puede ver como una coleccin de variables del tipo base. Para acceder a la variable que ocupa una posicin determinada se utiliza la sintaxis:

Tema 2: Utlizacin de Objetos


variableArray[posicin];

Las operaciones que se pueden hacer con la variable as obtenida son todas las que permita su tipo, que es el tipo base. Ejemplo: Usamos la clase Complejo que representa un nmero complejo de la forma x+yi, con constructora Complejo(double x, double y), mtodos de consulta valorX(), valorY(), toString() (que devuelve un String de la forma x+yi) y mtodos de modificacin
ponX(double), ponY(double)

Complejo

[]puntos = {new Complejo(3.5,2.4), new Complejo(1,2), new Complejo(6,7)};

puntos[0].ponX(3); System.out.println(puntos[0]); Complejo c = new Complejo(10,10); puntos[2] = c; c.ponX(11); System.out.println(puntos[2].valorX()); puntos[2].ponX(puntos[2].valorX()+1)); System.out.println(c); puntos = new Complejo[10]; System.out.println(puntos[3]);

Pregunta 2.e Qu escribir el programa?

Importante: Si tratamos de acceder a una posicin fuera del lmite del array obtendremos una excepcin ArrayIndexOutofBoundsException.

Tema 2: Utlizacin de Objetos


Para conocer el tamao de un array se puede acceder al atributo length, que se puede ver como una variable public y final (i.e. constante, no se puede modificar directamente, slo creando una nuevo array): Ejemplos:

int i; Complejo

[]puntos = {new Complejo(3.5,2.4), new Complejo(1,2), new Complejo(6,7)};

// mostrar todos los elementos del array for (i=0; i<puntos.length; i++) System.out.println(puntos[i]); puntos = new Complejo[10]; for (i=0; i<puntos.length; i++) puntos[i] = new Complejo(i,i); // mostrar todos los elementos del array for (i=0; i<puntos.length; i++) System.out.println(puntos[i]); // esto NO se puede hacer, dara error al compilar // puntos.length++;

Pregunta 2.f Qu escribir el programa?

Observacin: Para recorrer los arrays se suelen utilizar bucles for.

4.4 Arrays multidimensionales


Como hemos visto los arrays que se crean en Java son unidimensionales. Para tener arrays de

Tema 2: Utlizacin de Objetos


varias dimensiones la nica solucin ser utilizar arrays de arrays, tal y como muestra el siguiente ejemplo:
Principal.java

import complejos.Complejo; public class Principal { public static void main(String[] args) { // array de 3 por 2 complejos Complejo matriz[][] = { {new Complejo(1,1), new Complejo(2,2)}, {new Complejo(3,3), new Complejo(4,4)}, {new Complejo(5,5), new Complejo(6,6)}}; muestra(matriz); System.out.println(matriz[3][1]); // otra matriz de 3 por 2 Complejo otra[][] = new Complejo[3][2]; // escribir cdigo para que el contenido de la matriz sean los nmeros // 0+0i 0+1i // 1+0i 1+1i // 2+0i 2+1i .... .... .... .... muestra(otra); Complejo rara[][] = new Complejo[5][]; // 5 filas for (f=0; f<rara.length; f++) { // la fila f tendr f columnas con los numeros 0+0i....(f-1)+0i rara[f] = new Complejo[f]; for (c=0; c<rara[f].length; c++) rara[f][c] = new Complejo(c,0); } muestra(rara); } // main

public static void muestra(Complejo [][]t) { int fila, columna; for (fila=0; fila<t.length; fila++) { for (columna=0; columna<t[fila].length; columna++) System.out.print(t[fila][columna]+" "); System.out.println(""); } // for fila } // muestra

Tema 2: Utlizacin de Objetos


} // Principal

La salida de este programa ser:


1.0 3.0 5.0 3.0 0.0 1.0 2.0 0.0 0.0 0.0 0.0 + + + + + + + + + + + 1.0i 3.0i 5.0i 3.0i 0.0i 0.0i 0.0i 2.0 + 2.0i 4.0 + 4.0i 6.0 + 6.0i 0.0 + 1.0i 1.0 + 1.0i 2.0 + 1.0i

0.0i 0.0i 1.0 + 0.0i 0.0i 1.0 + 0.0i 2.0 + 0.0i 0.0i 1.0 + 0.0i 2.0 + 0.0i 3.0 + 0.0i

5.- Envoltura de tipos primitivos


5.1 Introduccin 5.2 Enteros 5.3 Caracteres 5.4 Reales 5.5 Lgicos 5.6 Boxing y Unboxing

5.1 Introduccin
Vamos a ver en este apartado un conjunto de clases que se utilizan para representar los tipos primitivos como clases. Cada objeto de una de estas clases tendr un slo atributo: el valor de tipo primitivo que el objeto "envuelve". Estos tipos resultan tiles por dos razones: Utilizar mtodos especficos de cada tipo (casi siempre estticos). Convertir los tipos simples en objetos cuando resulte necesario. En relacin con el segundo punto slo es necesario saber que: Todas las clases "envoltura" tienen una constructora con un parmetro; el valor de tipo simple que queremos "envolver".

Tema 2: Utlizacin de Objetos


Todas los objetos de tipo "envoltura" tienen un mtodo que permite acceder para consulta al valor simple que "envuelven".

Estos dos puntos se ven claramente en el siguiente ejemplo:

Principal.java

public class Principal { public static void main(String[] args) { Integer a = new Integer(3); // "envolvemos" el 3 System.out.println(a.intValue()); // "desenvolvemos" el 3 Character c = new Character('v'); System.out.println(c.charValue()); Double d = new Double(1.717225); System.out.println(d.doubleValue()); Boolean b = new Boolean(true); System.out.println(b.booleanValue()); } }

Aunque la utilidad de envolver un tipo simple no se ver hasta que tratemos los vectores, en el siguiente punto. Las siguientes secciones muestran algunos de los principales mtodos estticos incluidos en las clases envoltura.

5.2 Enteros
Vemos los mtodos principales de la clase Integer mediante un ejemplo:

Ejemplo
import java.io.*; // para BufferReader public class Principal { public static void main(String[] args) { int a = 19123; // cambios de base String aEnBinario = Integer.toBinaryString(a); String aEnOctal = Integer.toOctalString(a); String aEnHexadecimal = Integer.toHexString(a); // con toString se puede convertir a una base cualquiera

Tema 2: Utlizacin de Objetos


String aEnBase11 = Integer.toString(a,12); System.out.println(aEnBinario); // 100101010110011 System.out.println(aEnOctal); // 45263 System.out.println(aEnHexadecimal); // 4ab3 System.out.println(aEnBase11); // b097 } // main } // Principal

Observacin: Existen tambin las clases Byte, Short y Long, anlogas a la clase Integer

5.3 Caracteres
Dentro de la clase Character pueden interesarnos los siguientes mtodos:

static boolean isDigit(char c); // true si c es un dgito, false e.o.c. static boolean isLetter(char c); // true si c es una letra (minscula o mayscula), false e.o.c. static boolean isLetterorDigit(char c); static boolean isLowerCase(char c); // true si es minscula, false e.o.c. static boolean isUpperCase(char c); // true si es mayscula, false e.o.c. static char toLowerCase(char c); // convierte el carcter en minscula, o lo deja tal cual si no es una letra static char toUpperCase(char c); // convierte el carcter en mayscula, o lo deja tal cual si no es una letra

5.4 Reales
Dentro de la clase Double pueden interesarnos los siguientes mtodos:

static String toString(double d); static Double valueOf(String s) ;

5.5 Lgicos
Esta clase no contiene mtodos de inters.

5.6 Boxing
Desde la versin 1.5 de Java la conversin entre tipos envoltura y su correspondiente tipo bsico se hace automticamente como muestra el siguiente ejemplo:
Integer i = 5; // esto daba error en la versin 1.4 Integer j = new Integer(6); int x = j; // esto tambin daba error en la versin 1.4

Tema 2: Utlizacin de Objetos


A la conversin del valor primitivo en un tipo envoltura se le llama boxing y al contrario unboxing.

6.- La clase Vector


6.1 Introduccin 6.2 Vectores genricos 6.3 Mtodos de la clase vector

6.1 Introduccin
Los arrays son muy tiles, pero tienen algunas desventajas:

No se puede variar su tamao dinmicamente. En particular no se pueden eliminar elementos ni insertar nuevos elementos.

Para superar estos inconvenientes, cuando resulte necesario, existe en java la clase Vector del paquete java.util.

Observacin: Los vectores son un ejemplo de coleccin. Adems de vectores Java permite otro tipo de colecciones como conjuntos (set) pilas (stack) o colas (queue) .

6.2 Vectores genricos


Desde la versin 1.5 (publicada en Septiembre de 2004), Java incluye los llamados tipos genricos. El uso de tipos genricos permite que las clases dependan de un parmetro que corresponde a un tipo. El valor del tipo se especifica al declarar objetos de la clase. El tipo Vector, convertido en genrico, pasndose a llamar Vector<T> por lo que ahora debemos indicar el tipo de los componentes del vector al declararlo:
Vector<Particula> v = new Vector<Particula>();

Observacin: En Java 1.5 tambin se puede declarar un vector sin especificar su tipo: Vector v = new Vector() pero se obtiene un aviso del compilador con la etiqueta warning.

Tema 2: Utlizacin de Objetos


El parmetro genrico debe ser un nombre de clase y no un tipo primitivo. Una declaracin como
Vector<int> v2 = new Vector<int>();

dar un error de compilacin. Para declarar vectores (o en general cualquier clase genrica) que almacene valores de tipos primitivos se utilizan los tipos envoltura vistos en el punto anterior. Por ejemplo, el vector anterior se declara:
Vector<Integer> v = new Vector<Integer>();

6.3 Mtodos de la clase vector


A continuacin vemos los mtodos ms importantes de esta clase por medio de un ejemplo: Principal.java
import java.util.Vector; // Esto es necesario public class Principal { public static void main(String[] args) { //----------------------------------------------------------// 1 constructoras // 1.a Constructora por defecto; vector vaco, con incremento de 10 en 10 Vector<Complejo> v1 = new Vector<Complejo>(); // 1.b Constructora con la capacidad inicial; // cuando se llene el vector se duplicar su tamao automticamente Vector<String> v2 = new Vector<String>(5); // 1.c Constructora que incluye tanto la capacidad inicial como el incr. Vector<Integer> v3 = new Vector<Integer>(9,1); // -----------------------------------------------------------// 2 mtodos de modificacin Complejo c = new Complejo(4,5); // aadir un elemento al final del vector v1.addElement(c); v1.addElement(new Complejo(1,2)); v1.addElement(new Complejo(3,4)); v2.addElement("rigodn"); v2.addElement("pon pon!");

Tema 2: Utlizacin de Objetos


v3.addElement(6); // el mtodo vector tiene un mtodo toString System.out.println(v1); // [4.0 + 5.0i, 1.0 + 2.0i,3.0 +4.0i ] // cambiar un elemento por otro. La posicin debe ser vlida // menor que el tamao actual del vector v1.setElementAt(c,2); c.ponX(1); System.out.println(v1); // [1.0 + 5.0i, 1.0+2.0i, 1.0 + 5.0i] // insert un elemento en una posicin indicada, desplazando // el resto para "hacer hueco" v1.insertElementAt(new Complejo(-1,-2), 2); System.out.println(v1); // [1.0 + 5.0i, 1.0+2.0i, -1.0-2.0i, 1.0 + 5.0i] // el contrario del anterior v1.removeElementAt(0); System.out.println(v1); // [1.0+2.0i,-1.0-2.0i, 1.0 + 5.0i] // para eliminar todos los elementos a la vez v1.removeAllElements(); System.out.println(v1); // [] // -----------------------------------------------------------// 3 mtodos de consulta // primero aadimos algunos elementos a v3 // aadir un elemento al final del vector v3.addElement(4); v3.addElement(5); v3.addElement(new Integer(6)); v3.addElement(7); // nm de elementos de un vector (igual que para String) System.out.println(v1.size()); // 0 System.out.println(v2.size()); // 2 System.out.println(v3.size()); // 5 // capacidad del vector (no se utiliza casi nunca porque el vector // crece automticamente) System.out.println(v1.capacity()); // 10 System.out.println(v2.capacity()); // 5 System.out.println(v3.capacity()); // 9 // buscar la posicin de un elemento; -1 si no est System.out.println(v2.indexOf("rigodn")); // 0 // buscar la posicin de un elemento; a partir de la pos. indicada; // -1 si no est System.out.println(v2.indexOf("rigodn",2)); // -1 // ver si un elemento est en el vector (true o false)

Tema 2: Utlizacin de Objetos


System.out.println(v2.contains("rigodn")); // true // elemento en una posicin determinada (que debe ser vlida) System.out.println(v3.elementAt(2)); // 5 } // main } // Principal

Observacin: Internamente el vector es en realidad una clase con un atributo tipo array. Cuando le pedimos que cambie su tamao se declara un nuevo array, copiando la informacin que haga falta del antiguo al nuevo.

Tema 3: Definicin de Clases


1.- Definicin de atributos 2.- Mtodos y tipos de mtodos 3.- Variables

1.- Definicin de atributos


1.1 Declaracin de atributos 1.2 Inicializacin de atributos: constructoras 1.3 La variable this

1.1 Declaracin de atributos


Los atributos son las variables que identifican a un objeto. Se deben elegir como atributos nicamente aquellos datos que permitan identificar al objeto y distinguir dos objetos de la misma clase. No deben incluirse como atributos variables auxiliares ni innecesarias, que deben representarse como variables locales en los mtodos que las necesiten. Los atributos se declaran dentro de la clase pero fuera de todos los mtodos, precedidos (generalmente) por la palabra private, para protegerlos del acceso desde otras clases.

Ejemplos: Para representar una clase Complejo representando un nmero complejo sobre el plano necesitamos dos atributos de tipo real (para la parte real e imaginaria). La clase comenzar as:
public class Complejo { private double x; // parte real private double y; // parte imaginaria ..... }

Para representar los datos una persona puede interesarnos:


public class Persona { private String nombre,apellidos,domicilio; private int edad; private double altura; ..... }

Tema 3: Definicin de Clases


Para representar un juego de las 3 en raya necesitaremos representar el tablero con las fichas adems de saber en cada momento a cual de los dos jugadores corresponde jugar:
// clase para representar el juego de las tres en raya public class TresEnRaya { // tipos auxiliares para representar los jugadores y los valores de la casilla private enum Jugadores {JUGADOR1,JUGADOR2}; private enum Casilla {VACA,FICHAJUG1,FICHAJUG2}; // tablero private Casilla tablero[][]; // jugador que tiene el turno private Jugadores jugConTurno; ..... }

1.2 Inicializacin de atributos: constructoras


Aunque Java da un valor por defecto (0 en caso de los nmeros, null para los objetos), en el caso de los objetos nos puede interesar que al crearse se les d unos valores diferentes de forma automtica, o realizar algn otro tipo de tareas. Esto se realiza con un tipo especial de mtodos, las constructoras, con la siguiente estructura: public nombreClase(tipo1 arg1, ...., tipon argn) { .... }

Observacin: Las constructoras tienen 3 caractersticas que las distinguen del resto de los mtodos: Se llaman igual que la clase. No tienen tipo de salida (ni siquiera void). Slo se llaman una vez por objeto, cuando ste se cre con new. No pueden llamarse explcitamente (sin new).

A la hora de disear una clase es muy importante definir de qu constructoras dispondr la clase

Tema 3: Definicin de Clases


Observacin: Aunque no incluyamos ninguna constructora, toda clase tiene una constructora sin argumentos por defecto.

Ejemplo:

En la clase Complejo podemos pensar en dos constructoras: una sin argumentos que construye el complejo 0+0i, y otra que recibe los dos valores
public class Complejo { private double x; // parte real private double y; // parte imaginaria // constructoras public Complejo() {x=y=0;} public Complejo(double laX, double laY) { x = laX; y = laY; } }

Aviso: Una vez incluida una constructora con argumentos, la constructora sin argumentos deja de existir, por lo que si queremos seguir usndola hay que incluirla explcitamente, como en el ejemplo anterior.

Ejemplos de declaracin de variables de tipo complejo:


Complejo c1 = new Complejo(); // c1 es el 0+0i Complejo c2 = new Complejo(1,-3); // c2 es 1-3i

Para representar los datos una persona pueden interesarnos:


public class Persona { private String nombre,apellidos,domicilio; private int edad; private double altura; // constructoras public Persona(String elNombre, String losApellidos) { nombre = elNombre; apellidos=losApellidos; }

Tema 3: Definicin de Clases


public Persona(String elNombre, String losApellidos, int laEdad) { nombre = elNombre; apellidos=losApellidos; edad=laEdad; } }

Ejemplos de uso:
Persona p1 = new Persona("Bertoldo","Gonslvez de la Cuaderna"); Persona p2 = new Persona("Casilda", "Bronciales", 22);

Sin embargo hay que recordar que una instruccin como:


Persona annima=new Persona();

dara error de compilacin al no tener la clase Persona ninguna constructora sin parmetros.

En el juego de las 3 en raya hacemos que la constructora por defecto construya el tablero, con todas sus casillas vacas y fije el turno para el jugador 1:

// clase para representar el juego de las tres en raya public class TresEnRaya { // tipos auxiliares para representar los jugadores y los valores de la casilla private enum Jugadores {JUGADOR1,JUGADOR2}; private enum Casilla {VACA,FICHAJUG1,FICHAJUG2}; // tablero private Casilla tablero[][]; // jugador que tiene el turno private Jugadores jugConTurno; // constructora public TresEnRaya() { // creamos el array tablero = new Casilla[3][3]; // lo inicializamos for (int i=0;i<3;i++) for (int j=0; j<3; j++) tablero[i][j] = Casilla.VACA; // fijamos el turno jugConTurno = Jugadores.JUGADOR1; } }

Tema 3: Definicin de Clases


Pregunta 3.a Cmo se inicializar un objeto de la clase TresEnRaya? Mustralo con un ejemplo

1.3 La variable this


En todas las clases existe implicitamente (i.e. declarado por el sistema, no por el usuario) un atributo privado de nombre this. Se trata de un atributo cuyo tipo es el la propia clase en la que est definido, y que contiene una referencia al propio objeto. Podemos imaginarlo as:

Gracias a this el objeto puede referirse a si mismo como si de un objeto ms se tratara. Iremos viendo su utilidad poco a poco, pero podemos empezar por una de sus aplicaciones ms comunes (aunque no la ms interesante): permitir acceder a los atributos del objeto desde mtodos cuyas variables locales lo hacen invisible. Veamos un ejemplo:

public class Rara { private int x;

Tema 3: Definicin de Clases


public Rara() { int x = 20; // esta es otra variable x int y = X*x; // damos al atributo x el valor de y this.x = y; } } En el cuerpo de esta constructora de esta clase se "mezclan" dos valores x:
El atributo x La variable local x

Entonces, en la instruccin y=x*x; de cul de las dos x se est hablando? La norma general en Java es que en caso de duda tiene preferencia la variable definida en un mbito ms prximo (esto se explicar con detalle despus), por lo que se trata de la variable local. Para referirnos a la x atributo utilizamos la expresin this.x indicando de esta forma la x que es parte de este objeto (y que slo puede ser un atributo, nunca una variable local).

Observacin: A raz de esto surge una pregunta por qu no da el compilador error en this.x si x es una variable privada?. La respuesta es que Java permite a los objetos de una clase dada acceder a los componentes privados de otros objetos de la misma clase.

El ejemplo anterior puede parecer forzado; no sera mejor simplemente evitar la repeticin de nombres? Aunque esto es posible, a veces resulta ms cmodo utilizar nombres repetidos. Un caso tpico son los nombres de los argumentos que contienen los valores iniciales de los atributos, como en el siguiente ejemplo:
public class Complejo { private double x; // parte real private double y; // parte imaginaria // constructoras public Complejo() {x=y=0;} public Complejo(double x, double y) { this.x = x; this.y = y; } }

Tema 3: Definicin de Clases


En este ejemplo la expresin this.x=x; asigna al atributo x (parte izquierda de la igualdad) el valor pasado como parmetro en la variable x (parte derecha de la igualdad). Haremos esto muy a menudo.

Observacin: Algunos autores recomiendan escribir siempre la palabra this delante del nombre de un atributo, aunque no haya posibles ambigedades.

Pregunta 3.b Qu valor tomar el atributo x tras crearse un objeto de la clase cuyo cdigo se muestra a continuacin?
public class Rarsima { private int x; public Rarsima() { x = 5; int x = 6; x = this.x + x; this.x += x; } }

2.- Mtodos y tipos de mtodos


2.1 Estructura de un mtodo en Java 2.2 Valor de salida de una funcin 2.3 Objetos como valores de salida 2.4 Los mtodos toString, equals y clone 2.5 Modificacin de argumentos dentro de un mtodo 2.6 Mtodos estticos 2.7 Sobrecarga En este apartado vamos a estudiar los mtodos, cmo devuelven valores y los tipos de mtodos que podemos distinguir.

2.1 Estructura de un mtodo en Java


La declaracin de un mtodo tiene siempre la siguiente estructura

Tema 3: Definicin de Clases


cabeceraDelMtodo { cuerpoDelMtodo }

La declaracin de la cabecera de un mtodo general perteneciente a una clase sera: tipoAcceso static abstract final native synchronized tipoSalida nombreMtodo(tipo1 arg1, ...., tipon argn) throws listaExcepciones

Las palabras en itlica son opcionales, mientras que las que estn en negrita son obligatorias. Normalmente la declaracin se simplificar a algo como: public tipoSalida nombre(tipo1 arg1, ...., tipon argn) (public es uno de los tipos de acceso). En los siguientes apartados y en captulos posteriores veremos muchas de las palabras opcionales con su significado. De momento, algunas observaciones: Si la lista de argumentos es vaca no se pone nada entre parntesis:
public double valorX() { return x; }

Es obligatorio que la funcin tenga un tipo de salida. Si no queremos que la funcin devuelva nada, o bien queremos que lo haga a travs de sus argumentos usaremos el tipo especial void como valor de salida. void es un tipo que no contiene ninguna constante, un tipo sin valores.
public void saluda() { System.out.println("Qu tal?"); return; // no es necesario, pero puede ponerse }

Tanto el tipo de salida como los tipos de los argumentos pueden referirse tanto a tipos simples como a objetos (i.e. a referencias a objetos). En la lista de argumentos slo se incluyen los nombres de los argumentos de llamada y su tipo, sin ningn calificador (ni var ni const ni &, ni nada). En los siguientes apartados veremos por qu.

Tema 3: Definicin de Clases


2.2 Valor de salida de una funcin
Como acabamos de decir todos los mtodos han de tener un valor de salida (el resultado de evaluar la funcin). Este valor se devuelve mediante la palabra reservada return seguida del valor deseado (que puede ser una expresin).
public double xAlCuadrado() { return x*x; }

Importante: El tipo de la expresin que se escribe tras return tiene que ser el mismo que el indicado como tipo de salida de la funcin en la cabecera.

Una excepcin es el caso de una funcin de tipo void, en la que no hace falta poner la palabra return:
public void cuentoCorto() { System.out.println("Nadie quera decirle a qu hora pasara el tren."); System.out.println("Le vean tan cargado de maletas que les daba pena"); System.out.println("explicarle que all no haba habido nunca"); System.out.println("ni vas ni estacin"); }

Aunque en este caso tambin puede escribirse, pero sin ninguna expresin al lado:
public void beso() { System.out.println("Un beso de amor aparta el tiempo"); return; }

Pregunta 3.c Qu escribir una llamada al siguiente mtodo?


public void incompleto() { System.out.println("Las palabras ms importantes..."); return; System.out.println("nunca llegan a pronunciarse"); }

Tema 3: Definicin de Clases


2.3 Objetos como valores de salida
En este apartado y en los siguientes vamos a utilizar la siguiente clase-ejemplo sencilla, que representa un nmero complejo: Complejo.java

package complejos; public class Complejo { // atributos, representan el nmero x+yi private double x,y; // constructoras public Complejo() { x=y=0;} public Complejo(double x, double y) {this.x=x; this.y=y;} // mtodos public void ponX(double nuevaX) { x = nuevaX;} public void ponY(double nuevaY) { y = nuevaY;} public double valorX() { return x; } public double valorY() { return y; } public double mdulo() { return Math.sqrt(x*x + y*y); }

public String toString() { return x+"+"+y+"i";} }

Supongamos que queremos incluir un mtodo en la clase Complejo que permita calcular el conjugado. Tenemos 3 posibilidades:

a) Declarar el mtodo de tipo void. El estado del objeto quedar modificado.


public class Complejo { private double x,y: // x es la parte real, y la imaginaria // por aqu iran los otros mtodos de la clase .... .... // convierte el nmero complejo en su conjugado public void conjugadoV1() { y = -y; } }

Tema 3: Definicin de Clases


Pregunta 3.d Qu escribir el siguiente programa? Principal.java
import complejos.Complejo; class Principal { public static void main(String [] args) { Complejo c = new Complejo(); c.ponX(3): c.ponY(4); c.conjugadoV1(); System.out.println(c.valorY()); } }

b) Declarar el mtodo de tipo Complejo, y hacer que el objeto no quede modificado, sino que
devuelva un nuevo objeto con su conjugado.
public class Complejo { private double x,y: // x es la parte real, y la imaginaria // por aqu iran los otros mtodos de la clase .... .... // crear un nuevo nmero complejo, conjugado del actual // el actual no vara public Complejo conjugadoV2() { Complejo nuevo = new Complejo(); nuevo.ponX(x); nuevo.ponY(-y); return nuevo; } }

Pregunta 3.e Qu escribir el siguiente programa? Principal.java


import complejos.Complejo; public class Principal { public static void main(String [] args) { Complejo c = new Complejo(); Complejo d; c.ponX(3): c.ponY(4); d = c.conjugadoV2();

Tema 3: Definicin de Clases


System.out.println(c.valorY()); System.out.println(d.valorY()); } }

c) Declarar el mtodo de tipo Complejo, y hacer que el objeto quede modificado, y se devuelva a si
mismo como resultado:
package complejos; public class Complejo { private double x,y: // x es la parte real, y la imaginaria // por aqu iran los otros mtodos de la clase .... .... // crear un nuevo nmero complejo, conjugado del actual // el actual no vara public Complejo conjugadoV3() { y = -y; return this; } }

Pregunta 3.f Qu escribir el siguiente programa? Principal.java


import complejos.Complejo; public class Principal { public static void main(String [] args) { Complejo c = new Complejo(); Complejo d; c.ponX(3): c.ponY(4); d = c.conjugadoV3(); System.out.println(c.valorY()); System.out.println(d.valorY()); c.ponX(-3); System.out.println(c.valorX()); System.out.println(d.valorX()); d.conjugadoV3(); System.out.println(c.valorY()); System.out.println(d.valorY()); } }

Tema 3: Definicin de Clases

2.4 Los mtodos toString, equals y clone


Se trata de mtodos especiales que debe incluir toda clase. Cada uno tiene un propsito diferente. toString Mtodo sin argumentos que debe devolver un valor de tipo String. Es utilizado cuando hay que convertir un objeto en un valor de tipo String. Por ejemplo, si pasamos un objeto al mtodo System.out.println, ste usar el mtodo toString para obtener la cadena de caracteres a mostrar. Ejemplo: Supongamos que en la clase Complejo aadimos la siguiente definicin del mtodo toString():
public String toString() { return x+"+"+y+"i";}

Entonces podemos probar un programa como el siguiente:


import complejos.Complejo; public class Principal { public static void main(String[] args) { Complejo c = new Complejo(3,4); System.out.println(c); // es lo mismo que escribir System.out.println(c.toString()); } }

que escribir por pantalla 3.0+4.0i

Aviso: Un error comn es pensar que toString tiene que escribir algo por pantalla. Slo tiene que devolver un valor de tipo String

Aviso: Si no definimos un mtodo toString el sistema incluye uno por defecto, que se encargar de devolver una cadena de caracteres representando la referencia contenida en el

Tema 3: Definicin de Clases


tipo objeto. Por ejemplo, si no inclumos ningn mtodo toString en la clase Complejo, el programa anterior escribir algo similar a:
complejos.Complejo@10b62c9

equals Como vimos en el tema anterior no se debe usar el operador == para comparar objetos, ya que esta operacin slo comparar las referencias a dichos objetos, devolviendo true si se trata de dos referencias al mismo objeto, o false en caso contrario. Por ejemplo un programa como:
import complejos.Complejo; public class Principal { public static void main(String[] args) { Complejo c1 = new Complejo(3,4); Complejo c2 = new Complejo(3,4); System.out.println(c1==c2); } }

escribir false porque c1 y c2 se trata de dos referencias a objetos diferentes. Si lo que deseamos es saber si los dos objetos contienen el mismo nmero complejo se debe utilizar el mtodo equals, que debe ser definido de la forma adecuada en la cada clase. En el caso particular de la clase Complejo, un posible mtodo equals sera:
public boolean equals(Complejo c) { return this.x == c.x && this.y==c.y; }

Una vez definido este mtodo podremos escribir:


import complejos.Complejo; public class Principal { public static void main(String[] args) { Complejo c1 = new Complejo(3,4); Complejo c2 = new Complejo(3,4); System.out.println(c1.equals(c2)); } }

que escribir ahora true como esperbamos.

Tema 3: Definicin de Clases


Aviso: Igual que ocurri a con toString, el sistema incluye un mtodo equals por defecto, pero su comportamiento es el de == por lo que siempre conviene que escribamos nuestro propio mtodo en cada clase.

Aviso: Siendo precisos, la definicin de equals del ejemplo para la clase Complejo no es del todo correcta: Java pide que equals sea capaz de comparar un objeto con cualquier otro, sea o no de su misma clase, mientras que el cdigo que hemos escrito slo permite comparaciones con otro nmero complejo. En captulos posteriores mejoraremos la deficin para que el mtodo admita objetos de otros tipos (en cuyo caso devolver true ).

clone Tambin hemos visto en el captulo precedente que una expresin de la forma c1=c2; con c1, c2 objetosm no hace que c2 sea una copia de c1, sino una nueva referencia a c1. Para conseguir crear nuevos objetos que sean copias de objetos ya existentes debemos definir y utilizar el mtodo clone. Una posible definicin de clone para la clase Complejo sera:
public Complejo clone() { return new Complejo(this.x,this.y); }

Una vez definido este mtodo podemos crear copias de objetos ya existentes:
import complejos.Complejo; public class Principal { public static void main(String[] args) { Complejo c1 = new Complejo(3,4); Complejo c2 = c1.clone(); c2.ponX(7.0); System.out.println(c1); System.out.println(c2); } }

Pregunta 3.g Qu escribir el programa anterior? Qu escribira si en lugar de Complejo c2


= c1.clone(); pusiramos Complejo c2 = c1;?

Tema 3: Definicin de Clases

2.5 Modificacin de argumentos dentro de un mtodo


En Java, como en la mayora de los lenguajes, el valor que se pasa como argumento es copiado a la variable que se escribe en la cabecera del mtodo.

Observacin: se puede pensar que las variables que aparecen en la cabecera son variables locales a la funcin, con la particularidad de que reciben sus valores desde fuera, mediante los valores de llamada.

Los argumentos de tipos bsicos no quedan modificados aunque se modifiquen en un mtodo, no importa si de la propia clase o de una clase diferente:

Tonto.java

public class Tonto { public static void main(String [] args) { int x=5; incrementa(x); System.out.println(x); } public static void incrementa(int a) { a =a+1; } }

Pregunta 3.h Qu escribir el programa anterior?

Para lograr que se incremente la variable se podra hacer:


Inc.java

Tema 3: Definicin de Clases


public class Inc { public static void main(String [] args) { int x=5; x = incrementa(x); System.out.println(x); } public static int incrementa(int a) { a =a+1; return a; } }

En el caso de los objetos se procede de igual forma; se copia el contenido de la variable a la variable local declarada en la cabecera del mtodo. Sin embargo hay una diferencia muy importante:

Observacin: como hemos visto las variables de tipos no bsico no contienen en realidad los objetos, sino referencias a los objetos. La copia a la variable de un mtodo ser de la referencia, no del objeto, y por tanto podremos modificar el objeto.

Esto se observa en el siguiente ejemplo:


Intercambio.java

import complejos.Complejo; public class Intercambio { public static void main(String [] args) { Complejo c = new Complejo(); c.ponX(3); c.ponY(2); intercambia(c); System.out.println(c.valorX()); System.out.println(c.valorY()); } public static void intercambia(Complejo c) { // 2 variables locales con las partes reales e imaginarias de c double x = c.valorX(); double y = c.valorY(); // ponemos en x el valor y, y viceversa c.ponX(y); c.ponY(x);

Tema 3: Definicin de Clases


} }

Pregunta 3.i Qu escribir el programa anterior?

Y an un ejemplo ms:
Raro.java

import complejos.Complejo; public class Raro { public static void main(String [] args) { Complejo c = new Complejo(); c.ponX(3); c.ponY(2); ponACeroV1(c); System.out.println(c.valorX()); System.out.println(c.valorY()); ponACeroV2(c); System.out.println(c.valorX()); System.out.println(c.valorY()); } public static void ponACeroV1(Complejo c) { Complejo a = new Complejo(); a.ponX(0); a.ponY(0); c = a; } public static void ponACeroV2(Complejo c) { c.ponX(0); c.ponY(0); } }

Pregunta 3.j Qu escribir el programa anterior?

Tema 3: Definicin de Clases

Observacin: Cuando un objeto se queda sin referencias que lo apunten es destruido por el sistema y su memoria liberada. Es lo que en Java se llama recogida automtica de basura.

El siguiente programa trata de ilustrar esta idea:


Basura.java import complejos.Complejo; public class Basura { public static void main(String [] args) { Complejo a; a = new Complejo(); a.ponX(1); a.ponY(1); Complejo b = new Complejo(); b.ponX(3); b.ponY(2); Complejo c = a; a = b; b = c; a = new Complejo(); a.ponX(2); a.ponY(2); } }

1 2 3 4 5 6 7 8 9 10 11 12

Pregunta 3.k Indica qu valor toman las variables en cada fase del programa y cundo se crea y se puede destruir cada objeto.

Al igual que sucede con los objetos, los arrays se pasan por referencia a los mtodos. Por tanto si un mtodo modifica el contenido de un array ste queda modificado tambin fuera del mtodo.

Tema 3: Definicin de Clases


Principal.java
import complejos.Complejo; public class Principal { public static void main(String[] args) { int i; Complejo []puntos = { new Complejo(1,2), new Complejo(6,7)};

muestra(puntos); incrementaXs(puntos); muestra(puntos); Complejo []puntos2 = {new Complejo(1,2), new Complejo(6,7)}; muestra(puntos2); tresCeros(puntos2); muestra(puntos2); } // main public static void muestra(Complejo []t) { for (int j=0; j<t.length; j++) System.out.println(t[j]); } public static void incrementaXs(Complejo []t) { for (int j=0; j<t.length; j++) t[j].ponX( t[j].valorX()+1); } public static void tresCeros(Complejo []t) { t = new Complejo[3]; for (int j=0; j<t.length; j++) t[j] = new Complejo(0,0); muestra(t); } }

Pregunta 3.l Qu escribir el programa anterior?

Tema 3: Definicin de Clases


2.6 Mtodos estticos
En una primera aproximacin podemos dividir los mtodos en 4 grupos: Mtodos que inicializan el objeto o constructoras. Mtodos que permiten consultar el estado del objeto. Mtodos que permiten modificar el estado del objeto. Mtodos que independientes del estado del objeto o estticos. Hasta ahora hemos visto constructoras, as como mtodos para consultar y para modificar el estado del objeto. Vamos a estudiar ahora los mtodos estticos. Los mtodos estticos, son mtodos cuyo resultado o efecto es independiente de los atributos que pueda tener un objeto de esta clase, y por tanto del objeto en s. A menudo se encuentran en clases sin atributos, y con todos los dems metodos tambin estticos.
Operaciones.java package operaciones; public class Operaciones { public static int cuadrado(int x) { return x*x; } public static int cubo(int x) { return x*x*x; } }

Los mtodos estticos pueden utilizarse sin declarar ningn objeto, directamente como parte de la clase:
Principal.java import operaciones.Operaciones; public class Principal { public static void main(String [] args) { int a,b; // esto estara mal si "cuadrado" no fuera esttico porque "Operaciones" // no es un objeto sino una clase. a = Operaciones.cuadrado(3); b = Operaciones.cubo(4); System.out.println(a); System.out.println(b); } }

Tema 3: Definicin de Clases

Observacin: El uso de mtodos estticos "rompe" la filosofa de Java y slo deben usarse en casos muy especiales. S se utilizan bastante las constantes estticas.

2.7 Sobrecarga
Algunas clase (como Complejo) tienen dos o ms constructoras, todas con el mismo nombre (el de la clase) pero con distinto nmero de argumentos. Esto no es especfico de las constructoras, sino que se puede hacer con cualquier mtodo, como por ejemplo:
Incrementos.java package operaciones; public class Incrementos { private int x; public Incrementos(int laX) { x = laX; } public int f(int a) { return a+x; } public int f(int a, int b) { return a+b+x; } }

A la hora de utilizar un mtodo u otro el sistema se fija en el nmero y tipo de los parmetros y en el valor de salida:
Principal.java import operaciones.Incrementos; public class Principal { public static void main(String [] args) { Incrementos v = new Incrementos(3); System.out.println(v.f(1)); System.out.println(v.f(2,3));

Tema 3: Definicin de Clases


A esta posibilidad se la conoce con el nombre de sobrecarga, y a menudo se considera una de las caractersticas tpicas de la programacin orientada a objetos.

3.- Variables dentro de objetos


3.1 mbitos 3.2 Constantes y variables estticas

3.1mbitos
Se llama mbito a la regin de cdigo en la que una variable est definida. Inicialmente distinguimos 3 mbitos para las variables en Java: Atributos, globales a toda la clase. Variables locales de un mtodo. Parmetros de un mtodo. Veamos cada uno por separado:

Atributos Los atributos se declaran al comienzo de la clase (normalmente) y duran todo el tiempo que "vive" el objeto. Son visibles por todos los mtodos del programa siempre y cuando stos no tengan un parmetro o variable local que los oculte. Pueden inicializarse en la declaracin para darles un valor diferente del valor por defecto:
public class .... { private Complejo c= new Complejo(1.1,2); private int a = 2; public int f(int x) { return x+a+c.valorX(); } }

Variables locales

Slo existen desde que se declaran hasta que el mtodo se acaba:


public class .... { public int f(int x) { int a=5; a = a + x; return a; }

Tema 3: Definicin de Clases


public void g() { System.out.println(f(2)); System.put.println(f(3)); } }

Pregunta 3.m Qu escribir una llamada a la funcin g()?

Parmetros de un mtodo: Siguen las mismas normas que para las variables locales, con la diferencia de que no se pueden inicializar; se inicializan automticamente con el valor que se les pasa como argumento.

Ejemplo:
public class .... { private int x=3; public void f(int x) { System.out.println(x+1) } public void g() { f(x); } }

Pregunta 3.n Qu escribir una llamada a la funcin g()?

3.2 Constantes y variables estticas


A menudo interesa incluir en las clases constantes que sean visibles para el usuario de la clase. Dichas constantes no dependen normalmente de los atributos del objeto en particular, y sern por tanto estticas. Adems deben ser pblicas para que puedan ser utilizadas. Por ejemplo supongamos que queremos incluir en la clase Complejo una constante con el nmero imaginario i. Podramos entonces escribir:

Tema 3: Definicin de Clases


Complejo.java package complejos; public class Complejo { private double x,y; public static final Complejo i = new Complejo(0,1); // por aqu iran los mtodos que hemos declarado hasta ahora. .... }

y utilizar esta constante como parte de la clase:


ConComplejos.java import complejos.Complejo; class ConComplejos { public static void main(String args[]) { System.out.println(Complejo.i.mdulo()); } }

Pregunta 3.o Qu escribir el programa anterior?

Tema 4: Todo sobre Objetos


1.-Herencia en Java 2.- Clases Abstractas 3.- Interfaces 4.- Tipos de acceso 5.- Manejo de excepciones en Java Apndice A: Multitarea en Java (PDF)

1.- Herencia en Java


1.1 Introduccin 1.2 Atributos de tipo objeto 1.3 Herencia 1.4 La decisin 1.5 Redefinicin de mtodos 1.6 Polimorfismo 1.7 Madre no hay ms que una 1.8 Clases finales

1.1 Introduccin
Supongamos que deseamos escribir una clase para representar puntos con color (pixels). El punto de color vendr determinado por:

Dos valores tipo double x, y representando las coordenadas del punto. Un valor de tipo Color (una clase de Java para representar colores).

Supongamos tambin que queremos aprovechar que ya tenemos hecha la clase Complejo, lo que nos permite para manejar y actualizar los valores de las coordenadas x,y, es decir queremos reutilizar el cdigo de la clase. La primera posibilidad que se nos puede ocurrir es copiar el cdigo necesario a la clase nueva Importante: Un principio fundamental de ingeniera del software es nunca duplicar cdigo: cada vez que aada, modifique o corrija algo del cdigo original tendremos que hacer lo mismo con la copia. Todos los lenguajes modernos incluyen mecanismos para resolver esta situacin reutilizando el cdigo que hemos escrito. Vamos a estudiar dos posibles soluciones:

Tema 4: Todo sobre Objetos


Hacer que la clase Pixel tenga un Complejo como atributo. Utilizar herencia. Las dos alternativas son posibles, y dependiendo de lo que pretendamos de nuestra clase elegiremos la que ms convenga. Vamos a estudiar las dos por separado.

1.2 Atributos tipo objeto


En una primera aproximacin se podra escribir algo as como:
Pixel.java

import java.awt.Color; public class Pixel { private Complejo punto; private Color color; // constructoras public Pixel () { punto = new Complejo(0,0); color = Color.black; } public Pixel(double x, double y, Color color) { punto = new Complejo(x,y); this.color = color; } public Color valorColor() { return color; } public void ponColor(Color color) { this.color = color; } }

Y con esta clase escribir un programa principal:


Principal.java

import java.awt.Color; public class Principal { public static void main(String[] args) { Pixel pix = new Pixel(4,5,Color.red); pix.ponColor(Color.blue);

Tema 4: Todo sobre Objetos


System.out.println(pix.valorColor()); System.out.println(pix.valorX()); } }

Pregunta 4.a En este programa hay algo mal; qu es? Por tanto si incluimos el objeto como un atributo perdemos el acceso directo a sus mtodos. Para recuperarlo hay que escribir mtodos intermedios de acceso:
Pixel.java

import java.awt.Color; public class Pixel { private Complejo punto; private Color color; // constructoras public Pixel () { punto = new Complejo(0,0); color = Color.black; } public Pixel(double x, double y, Color color) { punto = new Complejo(x,y); this.color = color; } public Color valorColor() { return color; } public void ponColor(Color color) { this.color = color; } public double valorX() { return punto.valorX(); } public void ponX(double nuevaX) { punto.ponX(nuevaX); } ..... }

Como se ve esta tcnica resulta incmoda, al obligarnos a incluir las funciones que hacen de "intermediarias" con el atributo. Sin embargo puede ser til cuando se trata de ocultar algunos de los mtodos.

Tema 4: Todo sobre Objetos


Ejemplo: Si decidimos que el punto no puede cambiar sus coordenadas, slo su color, entonces esta opcin resulta adecuada. Sin embargo, si nuestro concepto es ms bien que la clase Pixel debe tener incluida todos los mtodos de la clase Complejo, entonces deberamos recurrir a la herencia.

1.3 Herencia
Empezamos con una definicin informal de herencia: Definicin: Decimos que una clase B hereda de una clase A cuando todos los objetos de B son tambin objetos de A. En este caso, diremos que B es la clase hija o subclase, o clase derivada, y A la clase madre o superclase.

Ejemplo:

Est definicin "filosfica" nos debe guiar durante el diseo de subclases, y tambin para comprender las particularidades de la herencia. En Java se indica que B es subclase de A mediante la palabra reservada extends: public class B extends A { .....

El comportamiento de una clase derivada queda explicado de manera general por la siguiente observacin: Observacin: Los mtodos (o atributos) pblicos de una clase A son automticamente convertidos en mtodos (o atributos) pblicos (ms adelante detallaremos qu sucede con los mtodos o atributos privados o con otro tipo de modificador de acceso).

Tema 4: Todo sobre Objetos


Por tanto podemos escribir una nueva versin de la clase Pixel as:
Pixel.java

import java.awt.Color; public class Pixel extends Complejo { private Color color; // constructoras public Pixel () { ponX(0); ponY(0); color = Color.black; } public Pixel (double laX, double laY, Color elColor) { ponX(laX); ponY(laY); color = elColor; } public Color valorColor() { return color; } public void ponColor(Color color) { this.color = color; } }

Y ahora podemos escribir el programa:


Principal.java

import java.awt.Color; public class Principal { public static void main(String[] args) { Pixel pix = new Pixel(4,5,Color.red); pix.ponColor(Color.blue); System.out.println(pix.valorColor()); System.out.println(pix.valorX()); // esto funciona! } }

Que escribir por pantalla:

Tema 4: Todo sobre Objetos


java.awt.Color[r=0,g=0,b=255] 4.0

Aclaracin: La lnea java.awt.Color[r=0,g=0,b=255] es el resultado de llamar al mtodo toString de la clase Color, que escribe los colores como combinaciones de rojo (r), verde (g), y azul (b), con valores entre y 255). De esta forma hemos aprovechado el cdigo de la clase Complejo. Ms an, si mejoramos esta clase mejoraremos tambin, automticamente, la clase Pixel. Observacin: La idea bsica de la reutilizacin es: "definir una vez, utilizar muchas". La programacin orientada a objetos naci teniendo en cuenta este concepto.

1.4 La decisin
Para elegir una u otra opcin (incluir uno o ms atributos de la clase inicial o heredar de ella) se debe contestar a la pregunta: Es todo objeto de tipo B un objeto de tipo A? A veces resulta sencillo contestar a la pregunta; por ejemplo un pixel es un punto, y por tanto un nmero complejo. Igualmente si queremos representar la clase recta e identificamos la recta por sus puntos inicial o final es obvio que una recta no es un punto, y que para definirla no usaremos herencia:
public class Recta { private Complejo puntoInicial, puntoFinal; ....

Otras veces la cosa no est tan clara: Un moto es una bicicleta? En ocasiones puede llegarse a la conclusin de que ninguna de las dos soluciones es la adecuada y que lo que hay que hacer es una clase nueva. O incluso puede ser que creamos conveniente utilizar las dos. Ejemplo: Supongamos que las coordenadas del pixel son las del origen de la pantalla (que es siempre la 0,0), pero que tambin tenemos que tener en cuenta dnde se haya situado el origen de coordenadas terico:

Tema 4: Todo sobre Objetos

y que el pixel debe "saber" siempre donde est dicho centro terico. Entonces podemos escribir una clase como la siguiente:
PixelCentro.java

import java.awt.Color; public class PixelCentro extends Complejo { private Color color; private Complejo centro; public PixelCentro(double x, double y, Color color) { ponX(x); ponY(y); this.color = color; // inicializamos el centro a (0,0) centro = new Complejo(); } public void ponCentro(Complejo centro) { this.centro = centro; } public Complejo valorCentro() { return centro; } public void ponColor(Color color) { this.color = color; } public Color valorColor() { return color; } }

Y un programa principal como:


Principal.java

import java.awt.Color;

Tema 4: Todo sobre Objetos


public class Principal { public static void main(String[] args) { PixelCentro pixel = new PixelCentro(25,75,Color.blue); Complejo centro = new Complejo(50,50); pixel.ponCentro(centro); System.out.println(pixel.valorCentro()); System.out.println(pixel.valorColor()); System.out.println(pixel.valorX()); System.out.println(pixel.valorY()); } }

Si suponemos que ya habamos definido la clase Pixel podemos utilizar herencia y definir:
PixelCentro.java import java.awt.Color; public class PixelCentro extends Pixel { private Complejo centro; public PixelCentro(double x, double y, Color color) { ponX(x); ponY(y); ponColor(color); // inicializamos el centro a (0,0) centro = new Complejo(); } public void ponCentro(Complejo centro) { this.centro = centro; } public Complejo valorCentro() { return centro; } }

A partir de aqu suponemos PixelCentro definida de esta forma. Los siguientes puntos tratan de las caractersticas de las clases derivadas.

1.5 Redefinicin de mtodos


Como hemos visto una subclase 'hereda' los mtodos de su clase madre. Sin embargo en ocasiones el comportamiento de alguno de los mtodos pierde validez en la clase hija. Ejemplo:

Tema 4: Todo sobre Objetos


Supongamos que en la clase PixelCentro queremos que el mdulo se calcule con respecto al centro terico, no respecto al origen de coordenadas de la pantalla:

Sin embargo, el mtodo mdulo heredado de Complejo no tiene el comportamiento deseado, porque un cdigo como:
PixelCentro pixel = new PixelCentro(51,50,Color.blue); Complejo centro = new Complejo(50,50); pixel.ponCentro(centro); System.out.println(pixel.mdulo());

Escribe 71.42... y no 1 nos gustara. En este caso la solucin es redefinir en PixelCentro la funcin mdulo: PixelCentro.java
import java.awt.Color; public class PixelCentro extends Pixel { Complejo centro; ... public double mdulo() { return Math.sqrt( Math.pow(valorX()centro.valorX(),2)+Math.pow(valorY()-centro.valorY(),2)); }

Y ahora el cdigo anterior s escribe en pantalla 1.0. Observacin: La clase derivada puede modificar los mtodos de su superclase. En otras ocasiones no queremos cambiar sino "aumentar" el comportamiento del mtodo de la superclase. Por ejemplo:
Pixel pixel = new Pixel(51,50,Color.blue); System.out.println(pixel);

Tema 4: Todo sobre Objetos


Para mostrar por pantalla pixel el sistema busca, como dijimos, una funcin toString(). Esta funcin existe, ya que la clase Pixel la ha heredado de Complejo, donde la definimos (al presentar los Strings) como:
public class Complejo { .... public String toString(){ return x+" + "+ y+"i"; } ....

y por tanto se muestra por pantalla 51.0 + 50.0i. Esto no est mal, pero nos gustara que tambin se mostrara el color. Podemos entonces redefinir toString en la clase Pixel pero reutilizando el cdigo toString de la clase Complejo. Esto se hace as:
public class Pixel extends Complejo { ... public String toString() { return super.toString()+" Color: "+valorColor(); } ..... }

Ahora el cdigo anterior escribir 51.0 + 50.0i Color: java.awt.Color[r=0,g=0,b=255]. Aviso: Se puede utilizar super para acceder a los mtodos de la clase madre, pero no super.super para acceder a los de la "abuela".

Aviso: Las constructoras no se heredan. La palabra reservada super tambin se utiliza para llamar a la constructora de la clase madre desde la constructora de la clase derivada. Debe incluirse como primera lnea de la constructora en la clase derivada. Vemoslo con un ejemplo:
public class Pixel extends Complejo { private Color color; ... public Pixel(double x, double y, Color color) { super(x,y); this.color = color; } ....

1.6 Polimorfismo

Tema 4: Todo sobre Objetos


Polimorfismo: todos los objetos de una clase derivada pueden utilizarse en el mismo contexto que los objetos de la clase madre. Todo objeto de una clase derivada puede por tanto convertirse en un objeto de la clase madre. Sin embargo los mtodos reescritos se conservan tal y como estn definidos en la clase derivada Vamos a verlo con un ejemplo: Principal.java
import java.awt.Color; public class Principal { public static void main(String[] args) { PixelCentro pixel = new PixelCentro(10,10,Color.blue); Complejo c = new Complejo(5,5); pixel.ponCentro(new Complejo(9,9)); // 5 + 5i System.out.println(c); // 10.0 + 10.0i Color: java.awt.Color[r=0,g=0,b=0] System.out.println(pixel); System.out.println(suma(pixel,c)); // 15+15i System.out.println(sumaMdulos(pixel,c)); // 8.485281374238571 //y esto que har? lo muestra como pixel: // 10.0 + 10.0i Color: java.awt.Color[r=0,g=0,b=0] System.out.println((Complejo)pixel); muestraComplejo(c); muestraComplejo(pixel); } static Complejo suma(Complejo c1, Complejo c2) { double xsuma = c1.valorX()+c2.valorX(); double ysuma = c1.valorY()+c2.valorY(); return new Complejo(xsuma,ysuma); } static double sumaMdulos(Complejo c1, Complejo c2) {

Tema 4: Todo sobre Objetos


return c1.mdulo()+c2.mdulo(); } static void muestraComplejo(Complejo c) { System.out.println(c); } }

1.7 Madre no hay ms que una


Dicho con otras palabras: En Java todas las clases heredan de una y slo de una clase Todos heredan de una clase Todas las clases heredan de alguna clase; si no lo hacen explcitamente (con {\em extends}) lo hacen implcitamente de la clase Object. Observacin: Cuando nosotros escribimos: public class Turur { ....

Java entiende: public class Turur extends Object{ ....

Observacin: Debido al polimorfismo, todos los objetos pueden verse como miembros de la clase Object. La clase Object contiene algunos mtodos interesantes: String toString() : Ya hemos hablado anteriormente de este mtodo, que devuelve la representacin como String de un objeto, y que habitualmente redefinimos en las clases que definimos. Object clone() : Devuelve una copia del objeto en el que estamos. Class getClass() : Devuelve informacin acerca de la clase del objeto en el que estamos. La clase Class (!!) se define en Java para representar informacin acerca de las clases y

Tema 4: Todo sobre Objetos


permitir lo que se suele llamar meta-programacin. public boolean equals(Object obj): Se utiliza para comparar objetos. Se recomienda redefinirlo al hacer una clase, porque el comportamiento por defecto, es el del operador ==, que no es a menudo el deseado: Aviso: El operador == (y por tanto el mtodo equals heredado de Object) devuelve si los dos valores comparados corresponden a referencias al mismo objeto.

true

Por ejemplo, el programa:


import complejos.Complejo; public class Principal { public static void main(String[] args) { Complejo c1 = new Complejo(3,5); Complejo c2 = new Complejo(3,5); System.out.println(c1==c2 ? "Iguales" : "Diferentes"); System.out.println(c1.equals(c2) ? "Iguales" : "Diferentes"); } }

escribir dos veces por pantalla la palabra Diferentes (suponiendo que no hemos redefinido el mtodo equals). Para solucionar esto (nos gustara que nos dijera que c1 y c2 son el mismo nmero complejo) debemos redefinir equals. Para hacerlo de forma correcta, Java nos pide que sigamos (entre otros) los siguientes principios:

equals debe ser un mtodo reflexivo: debe verificarse x.equals(x)==true para todo x!=null equals debe ser un mtodo simtrico: debe verificarse x.equals(y)== y.equals(x) para todo x!=null, y!=null equals debe ser un mtodo transitivo: dados x,y,z distintos de nullsi se cumple x.equals(y)==true y y.equals(z)==true debe cumplirse x.equals(z)==true. Para todo x!=null debe cumplirse x.equals(null)==false

A menudo a estas reglas (completadas con algunas ms que no escribimos por ser ms complicadas, pero que pueden encontrarse en la ayuda de Java), se las conoce como el contrato para equals. Es interesante observar que las 3 primeras especifican que la relacin binaria R definida como
x R y <==> x.equals(y)==true

es una relacin de equivalencia. Siguiendo estas ideas podemos escribir un mtodo equals para la clase complejo de la siguiente forma:
public class Complejo { .... // redefinicin de equals public boolean equals(Object obj) { boolean salida = false;

Tema 4: Todo sobre Objetos


if (obj != null && (obj.getClass().equals(this.getClass()))) { Complejo c = (Complejo)obj; salida = (valorX() == c.valorX()) && (valorY() == c.valorY()); } return salida; }

El if garantiza que el objeto con el que estamos comparando no es null y que pertenece a la misma clase que el objeto en el que nos encontramos (para esto utilizamos el mtodo equals de la clase Class). Ahora el programa:
import complejos.Complejo; public class Principal { public static void main(String[] args) { Complejo c1 = new Complejo(3,5); Complejo c2 = new Complejo(3,5); System.out.println(c1==c2 ? "Iguales" : "Diferentes"); System.out.println(c1.equals(c2) ? "Iguales" : "Diferentes"); } }

Escribe:
Diferentes Iguales

Por lo que equals funciona ahora como deseamos. Es importante recordar lo siguiente: Aviso: Nunca usar == para comparar objetos, utilizar en su lugar equals.

En Java todas las clases heredan de una y slo de una La herencia mltiple (heredar de ms de una clase a la vez) plantea una gran cantidad de problemas tericos (en caso de colisin de quin son los mtodos, problemas de polimorfismo, etc.), aunque en ocasiones puede darse. Es lo que se conoce como el problema del diamante (por la forma del grfico). Imaginemos por ejemplo que tenemos:

Tema 4: Todo sobre Objetos

Y definimos: Animal.java
public class Animal { public void saluda() { } }

Rana.java
public class Rana extends Animal{ String tipo="Anfibio"; public void saluda() { System.out.println("Croack!"); } }

Dinosaurio.java
public class Dinosaurio extends Animal{ String tipo="Reptil"; public void saluda() { System.out.println("Hola, soy un dinosaurio, mucho gusto"); } }

Ranosaurio.java

Tema 4: Todo sobre Objetos


// Esto no se puede hacer en Java!!! public class Ranosaurio extends Rana, Dinosaurio{ public void String valorTipo() { return tipo; // var. de la clase antecesora } }

Principal.java
public class Principal { public static void main(String[] args) { Animal a = new Animal(); Rana gustavo = new Rana(); Dinosaurio dino = new Dinosaurio(); Ranosaurio jurix = new Ranosaurio(); a.saluda(); gustavo.saluda(); dino.saluda(); jurix.saluda(); System.out.println(jurix.valorTipo()); } }

Si se pudiera escribir y compilar, este programa se planteara el problema de cual de las dos clases de las que se hereda tiene prioridad en caso de conflicto. Aunque no se pueda tener herencia mltiple directamente, Java permite simularla por medio de interfaces. Estas dos propiedades (existencia y unicidad de la superclase) hacen que la estructura de clases de Java tenga forma de rbol:

Tema 4: Todo sobre Objetos

1.8 Clases Finales


Definicin: Se dice que una clase es final cuando no admite subclases, es decir, no es posible heredar de ella Esto se puede hacer porque no queremos que nadie "utilice" nuestra clase. La principal razn es la seguridad: si tenemos una clase que realiza tareas "peligrosas" (ej.: puede borrar ficheros), alguien puede hacer una subclase reescribiendo los mtodos que quiera, y luego, debido al polimorfismo, utilizar el resto de la aplicacin con propsitos diferentes de los originales (e.j.: instalar un virus). Por ejemplo, en Java la clase String es final, as que una declaracin como:
public class MiString extends String { ...

dar error al compilar. Una clase se declara final escribiendo:


final public class LoQueSea { ...

Una posibilidad menos "extrema" es no declarar la clase como final y hacer "finales" los mtodos que queremos proteger de una posible redefinicin por parte de sus subclases.

Tema 4: Todo sobre Objetos


2.- Clases Abstractas
La idea de una clase abstracta es, bajo cierto punto de vista, la contraria de la de una clase final: de las clases abstractas hay que heredar necesariamente; en otro caso no pueden ser utilizadas. Definicin: Una clase es abstracta cuando tiene algn mtodo (o mtodos) sin definir. Por tanto no es posible declarar objetos de una clase abstracta. Sern las clases derivadas las que completen esos mtodos y de las que podremos definir objetos. Una clase abstracta sirve de base para otras clases, pero ella misma no puede ser instanciada (declarar objetos de su tipo). Esto se hace porque la implementacin de alguno de los mtodos depende de cada caso concreto y no se puede hacer en general. Vamos a verlo con un ejemplo. Supongamos que decidimos escribir una clase PolgonoRegular. De cada polgono nos interesa: 1. El nmero de lados. 2. La longitud de un lado. Adems queremos incluir mtodos para determinar el permetro y el rea del polgono en cada caso. El permetro es fcil de determinar, pero lo del rea no es tan fcil (alguien se acuerda?). Si suponemos que no somos capaces de determinar el rea podemos escribir la siguiente clase abstracta: PolgonoRegular.java
public abstract class PolgonoRegular { protected int nmLados; protected double lado; // longitud de un lado public PolgonoRegular(int nmLados, double lado) { this.nmLados = nmLados; this.lado = lado; } public double permetro() { return nmLados*lado; } // este mtodo lo tiene que hacer cada clase derivada; // depende de cada polgono regular public abstract double rea(); }

La palabra clase abstract indica que la clase contiene mtodos abstractos, es decir mtodos an no definidos. La clase est por tanto, incompleta, y no podemos declarar objetos de tipo PolgonoRegular:

Tema 4: Todo sobre Objetos


Principal.java
public class Principal { public static void main(String[] args) { PolgonoRegular c = new PolgonoRegular(7,3.0); // Error!!! clase abstracta System.out.println(c.rea()); } }

Observacin: Las clases finales lo son por decisin del programador, pero las abstractas lo son porque el programador no es capaz de implementar alguno de los mtodos, pero an as cree que debe existir. S podemos, en cambio, hacer clases derivadas como la siguiente: Cuadrado.java
public class Cuadrado extends PolgonoRegular { public Cuadrado(double lado) { super(4,lado); } public double rea() { return lado * lado; } }

con su correspondiente programa principal: Principal.java


public class Principal { public static void main(String[] args) { Cuadrado c = new Cuadrado(3.0); System.out.println(c.rea()); System.out.println(c.permetro()); } }

Aviso: La subclase de una clase abstracta debe incluir todos los mtodos declarados como abstractos (o ser ella misma abstracta).

Tema 4: Todo sobre Objetos


Puede parecer que las clases abstractas son intiles para qu definir una clase que no se puede usar sino a travs de otras? Sin embargo son tiles para conseguir un buen diseo de una aplicacin; en la clase abstracta incluimos cdigo que ser comn a todo un conjunto de clases (las que derivarn de ellas) y adems indicamos qu mtodos deben escribir las clases hijas para completarlas.

3.-Interfaces
Los interfaces no son clases sino "plantillas": Definicin: Un interfaz indica un conjunto de mtodos que deben implementarse para realizar una tarea determinada o cumplir unas propiedades. El cuerpo de los mtodos no se especifica y debe ser desarrollado en la clase que implementa el interfaz. Como se ve la idea es similar a la de la clase abstracta, pero llevada al extremo, porque todo es abstracto: un interfaz slo puede tener atributos constantes, y no puede incluir el cdigo de ningn mtodo. Ser la clase que implementa (en los interfaces no se habla herencia sino de implementacin) se encargar de aadir el cdigo necesario. Para decir que una clase A implementa una interfaz B escribiremos: public class A implements B { ..... }

Aviso: La clase que implementa un interfaz debe incluir una definicin para todos los mtodos del interfaz.

Aviso: Al definir un interfaz no se puede incluir cdigo para ningn mtodo. Pueden existir atributos, pero tiene que estar definidos como static final. Combinando la utilizacin de la herencia y de los interfaces pdoemos simular la herencia mltiple. Ejemplo: Supongamos que tenemos un interfaz para los objetos que son capaces de 'pintarse' a s mismos.
Pintador.java

import java.awt.Graphic; // Graphic sirve para dibujar en un objeto public interface Pintador {

Tema 4: Todo sobre Objetos


// g es el objeto que nos permite dibujar la figura // (x,y) debe ser la coordenadas de la esquina inferior izquierda public void pinta(Graphics g,int x,int y, Color color); // para borrar la figura public void borra(Graphics g, int x,int y); }

Ahora podemos hacer que la clase Cuadrado herede de PolgonoRegular y a la vez implemente Pintador:
Cuadrado.java

import java.awt.*; public class Cuadrado extends PolgonoRegular implements Pintador { public Cuadrado(double lado) { super(4,lado); // constructora de PolgonoRegular } public double rea() { return lado * lado; } public void pinta(Graphics g,int x, int y,Color color) { g.setColor(color); g.fillRect(x,y,(int)lado,(int)lado); } public void borra(Graphics g, int x, int y) { g.clearRect(x,y,(int)lado,(int)lado); } }

Para probar la nueva versin de la clase podemos escribir un programa principal (que utiliza los componentes grficos que veremosen el siguiente captulo) Principal.java
import java.awt.*; public class Principal { public static void main(String[] args) { Cuadrado c1 = new Cuadrado(40); // hacemos una ventana para pintar los cuadrados Frame ventana = new Frame("Ventana con cuadrados"); ventana.setLayout(new FlowLayout()); // le aadimos una etiqueta Label l = new Label(" "); l.setBackground(Color.yellow); ventana.add(l); ventana.setSize(300,200);

Tema 4: Todo sobre Objetos


ventana.setVisible(true); // esto an no puede entenderse del todo...paciencia Graphics g = ventana.getGraphics(); // esto funciona por ser Cuadrado un PolgonoRegular muestrarea(l,c1); // ...y esto porque Cuadrado dibuja(g,c1); } public static void dibuja(Graphics g, Pintador p) { p.pinta(g,30,30,Color.pink); p.pinta(g,200,90,Color.orange); p.pinta(g,20,100,Color.green); p.borra(g,50,40); p.pinta(g,75,120,Color.blue); } public static void muestrarea(Label etiq, PolgonoRegular r) { etiq.setText(" "+r.rea()); } } implementa Pintador

El resultado es el siguiente:

Este programa demuestra la ''doble naturaleza'' de Cuadrado: Por un lado hereda de PolgonoRegular, y por otro implementa el interfaz pintador. De esta forma hemos conseguido algo similar a la herencia mltiple.

4.- Tipos de acceso


Una pregunta interesante es: Qu mtodos y atributos de la clase padre pueden ser utilizadas en la clase hija?

En ocasiones nos interesa proteger algunos mtodos o atributos para que las clases hijas no puedan acceder a ellos y alteren el comportamiento de la clase. Esto tiene que ver con los modos de acceso que repasamos ahora brevemente y en general (no slo para la herencia). En Java hay 4 modos de acceso a mtodos y atributos: acceso private, acceso

Tema 4: Todo sobre Objetos


predeterminado (no se pone ninguna palabra para sealarlo), acceso protected y acceso public. La siguiente tabla define los mbitos de visibilidad segn el modificador. Acceso private (predeterminado) protected public Por tanto si un atributo se declara como private en una clase A, las subclases de A no podrn tener acceso a l. Para que una hija pueda acceder a un atributo ste debe ser declarado como protected. Ni los atributos protected ni los private son visibles desde fuera de la clase, por lo que ambas posibilidades respetan el principio de encapsulacin. Clase Subclase Paquete Resto

5.- Manejo de excepciones en Java


5.1 Introduccin 5.2 Tratamiento de Excepciones 5.3 La clase Exception

5.1 Introduccin
La utilizacin de excepciones es el mecanismo utilizado por Java (y C++) para tratar situaciones inesperadas que pueden ocurrir durante la ejecucin de programa: errores en la apertura de ficheros, divisiones por 0, etc. Ejemplo:
int dividendo, divisor,cociente; // por aqu se les da valores a dividendo y divisor .... try { cociente = dividendo/divisor; } catch (ArithmeticException e) { System.out.println("Error: Division por 0"); cociente = 0; } // en cualquier caso el programa contina por aqu .....

En otros lenguajes (y en Java, si se quiere) se utiliza la sentencia if para esto mismo:

Tema 4: Todo sobre Objetos


int dividendo, divisor,cociente; // por aqu se les da valores a dividendo y divisor divisor = 0; dividendo = 6; if (divisor != 0) cociente = dividendo/divisor; else { System.out.println("Error: Division por 0"); cociente = 0; } // el programa contina por aqu .....

El uso de excepciones permite manejar los errores de forma ms flexible y precisa. Adems, el uso de if no resuelve todas las situaciones.

5.2 Tratamiento de excepciones


El tratamiento de una (posible) excepcin sigue la sintaxis siguiente: try { ... // cdigo que puede generar una excepcin } catch (TipoExcepcin variable) { // cdigo para tratar la excepcin }

Observaciones: La variable slo es visible en el bloque catch y se suele utilizar (aunque no siempre) para conocer informacin ms concreta acerca de la situacin excepcional que ha ocurrido. La idea es que la excepcin provocada dentro del cdigo try se captura dentro del bloque catch. Las sentencias try pueden anidarse:
try { bloque1 // cdigo que puede generar una excepcin

try { bloque2 } catch (TipoExcepcin1 variable1) { bloque3 }

Tema 4: Todo sobre Objetos


bloque4 } catch (TipoExcepcin2 variable2) { // cdigo para tratar la excepcin }

En el segundo catch se pueden tratar excepciones:


Generadas en bloque1 del tipo TipoExcepcin2. Generadas en bloque2 del tipo TipoExcepcin2 pero que no son del tipo TipoExcepcin1. Generadas en bloque3 del tipo TipoExcepcin2.

En el primer catch slo se podrn tratar excepciones generadas en bloque1 del tipo TipoExcepcin1 . Importante: Si un trozo de cdigo puede generar una excepcin que no se captura en un catch el mtodo en el que est incluido debe indicar que puede lanzar dicha excepcin, para que sea tratada en un bloque ms externo mediante una declaracin throws. Ejemplo:
static String quieroGalleta(String s) throws NullPointerException{ if (s.equals("Galleta")) return "Gracias!"; else return("Quiero una galleta!!!"); }

Sin embargo lo ms habitual es tratar la excepcin en el mismo sitio donde se produce: Ejemplo:
static String quieroGalleta(String s){ String resultado = ""; try { if (s.equals("Galleta")) resultado = "Gracias!"; else resultado = "Quiero una galleta!!!"; } catch (NullPointerException e) { System.out.println("argumento sin inicializar"); } return resultado; }

O bien no tratarlo en absoluto:


static String quieroGalleta(String s){ if (s.equals("Galleta")) return "Gracias!";

Tema 4: Todo sobre Objetos


else return("Quiero una galleta!!!"); }

en este caso si se produce la excepcin el programa se "romper" y Java mostrar por pantalla la secuencia de llamadas que ha producido la excepcin:
Exception in thread "main" java.lang.NullPointerException at Principal.quieroGalleta(Principal.java:24) at Principal.main(Principal.java:19)

Informacin: Slo es obligatorio tratar (o declarar con throws las excepciones que tienen que ver con las operaciones de entrada/salida. Nosotros tambin podemos "lanzar" nuestras propias excepciones: Ejemplo:
public class Principal { public static void main(String[] args) { String s="tarta"; System.out.println(quieroGalleta(s)); } static String quieroGalleta(String s) throws IllegalArgumentException { if (s.equals("Galleta")) return "Gracias!"; else throw new IllegalArgumentException("Quiero una galleta!!!"); } }

Como no lo hemos tratado el sistema da el error:


Exception in thread "main" java.lang.IllegalArgumentException: Quiero una galleta!!! at Principal.quieroGalleta(Principal.java:15) at Principal.main(Principal.java:6)

Tambin se pueden crear nuevos tipos de excepciones, haciendo clases que hereden de la clase Exception.

5.3 La clase Exception


La clase Exception es la clase de la que heredan todas las excepciones. Slo tiene dos constructoras:

La constructora por defecto. La constructora a la que se le pasa un String: el mensaje de error que se mostrar.

Tema 4: Todo sobre Objetos


Los dos mtodos principales son:

String getMessage(): Devuelve el mensaje relativo al error printStackTrace(): muestra por pantalla el mensaje de error, junto con el nmero de lnea en el que se ha producido y la secuencia de llamadas (muy til para depurar).

La jerarqua de excepciones es: java.lang.Exception // la madre de todas las excepciones java.lang.InterruptedException // forzosamente deben estar dentro de un try. java.lang.RunTimeException // no necesitan incluirse en un try . java.lang.ArithmeticException // por ejemplo una divisin por 0 . java.lang.ArrayStoreException // intento de introducir un valor de tipo incorrecto en una matriz . java.lang.IllegalArgumentException // parmetro no vlido . java.lang.IllegalThreadStateException // la hebra no est en un estado adecuado . java.lang.NumberFormatException // p.ej. a convertir un String en entero . java.lang.IndexOutofBoundsException // acceso a una posicin no vlida... . java.lang.ArrayIndexOutofBoundsException // en un array . java.lang.StringIndexOutofBoundsException // en un String . java.lang.NegativeArraySizeException // intento de dar tamao negativo a una matriz . java.lang.NullPointerException // referencia a objeto sin inicializar (tiene null como valor) . java.io.IOException // forzosamente deben estar dentro de un try . java.io.EOFException // se ha intentado leer (o moverse) ms all del fin de fichero . java.io.FileNotFoundException // intento de acceder a un fichero inexistente . java.io.InterruptedIOException // por ejemplo si se saca el diskette mientras est leyendo . java.net.MalformedURLException // URL mal construida .

Aunque no est recomendado, se puede aprovechar el polimorfismo para declarar cualquier excepcin como de tipo Exception, asegurndonos de que el catch recoger cualquier cualquier posible excepcin: Ejemplo:
try { .... cdigo .... } catch(Exception e) { // aqu se recogen todas, sin importar su tipo e.printStackTrace(); // para mostrar el error

Tema 5: Desarrollo de aplicaciones grficas


1.- Introduccin 2.- Ventanas: la clase Frame 3.- Componentes Bsicos 4.- Eventos de teclado y de ratn 5.- Estilos 6.- Dibujando 7.- Applets 8.- Dilogos y mensajes

Apndice A: Un poquito de Swing

1.- Introduccin
1.1 AWT y Swing 1.2 Un poco de filosofa 1.3 La jerarqua Component

1.1 AWT y Swing


Una de las razones del xito de Java es la posibilidad desde las primeras versiones, de una gran cantidad de paquetes de clases destinadas al diseo de interfaces grficas. En otros lenguajes (C, C++, etc.), las libreras de componentes grficos dependan del fabricante del compilador particular que se decidiera utilizar. Esto favoreca la aparicin de dialectos del lenguaje y la falta de uniformidad en el modelo propuesto. La variedad de clases grficas y sus inmensas posibilidades de diseo hacer que un buen programador en Java no sea slo aquel que conoce los aspectos bsicos del lenguaje y su filosofa; es necesario tambin un conocimiento detallado de las clases del API (application program interface) de Java y sus posibilidades. Se pueden distinguir, principalmente, 2 grupos de clases destinadas al diseo de interfaces grficos en Java: AWT Swing La primera (Abstract Window Toolkit) es la que vamos a estudiar en este curso. El conjunto de clases Swing naci a partir de AWT, simplificando los aspectos ms engorrosos de AWT, dando mayor flexibilidad al programador para disear sus propios componentes grficos (gracias all uso de beans) e incorporando numerosos componentes nuevos. La pregunta que surge al leer esto es: Si Swing es ms sencillo, ms flexible y ms potente que AWT,

Tema 5: Desarrollo de aplicaciones grficas


por qu no limitarse a estudiar las clases de Swing?

La razn principal es que, a pesar de ser Swing ms fcil de manejar est basado en conceptos ms complejos, difciles de entender si primero no se conoce AWT; Swing contiene demasiado de AWT como para, simplemente, ignorarlo. La mayora de los autores piensa que es mejor seguir al estudiar el lenguaje la evolucin que han seguido sus diseadores. Por eso nos limitaremos aqu al estudio de AWT. Si se comprenden los conceptos de este tema pasar posteriormente a Swing no supondr ningn problema. Otro buena razn es que al ser AWT ms antiguo, los applets de internet escritos en AWT funcionan en muchos ms exploradores que los escritos con Swing. Por tanto usando AWT nos aseguramos una mayor compatibilidad. Observacin: Por cada componente en AWT, el correspondiente componente en Swing suele tener el mismo nombre pero precedido de una letra J. Por ejemplo, los botones se representan en AWT mediante objetos de la clase Button y en Swing mediante objetos de la clase JButton, las ventanas mediante las clases Frame y JFrame, y as sucesivamente.

1.2 Un poco de filosofa


El concepto bsico de la programacin grfica es el componente. Un componente es cualquier cosa que tenga un tamao una posicin, pueda pintarse en pantalla y pueda recibir eventos (es decir, pueda recibir acciones por parte del usuario). Un ejemplo tpico es un botn; el evento ms normal que puede recibir es que el usuario de la aplicacin pulse el botn. Podemos resumir los conceptos bsicos de la programacin grfica con AWT: Todos los componentes son o bien contenedores (como Frame) o bien componentes bsicos (como Button). Los componentes bsicos siempre deben formar parte de un contenedor para ser visibles. Los contenedores a su vez se pueden insertar en otros contenedores. La posicin de un componente en un contenedor depende del tamao del contenedor y de su estilo (Layout). Todo componente incluye un atributo de tipo Graphicsque se encarga de dibujarlo cuando hace falta. Si queremos dibujar en el componente tendremos que pedirle que nos "deje" su objeto de tipo Graphics. Si queremos que un componente haga algo cuando le ocurra un evento determinado debemos pasarle un objeto tipo Listener al que l avisar llegado el momento. Las idea clave de esta forma de proceder es la llamada delegacin de eventos. En una aplicacin grfica La funcin main se encargar de crear la ventana principal, donde se dispondrn los componentes y se indicar a cada componente a qu clase debe avisar cuando le suceda un evento. A partir de este momento ser el propio lenguaje el que se encargar de avisar a las clases adecuadas de la existencia de un evento como respuesta a

Tema 5: Desarrollo de aplicaciones grficas


las acciones del usuario. Esto significa que se pierde el concepto de ejecucin secuencial que hemos visto en los programas con entrada/salida de texto.

1.3 La jerarqua Component


La clase Component es una clase abstracta de la que derivan todos los componentes visuales AWT. Tiene ms de 100 mtodos de los que vamos a mencionar slo los ms habituales:
Clase Component

Mtodo String getName() void setName(String) Dimension getSize() void setSize(int ancho, int alto) void setSize(Dimension) Color getBackground Color getForeground void setForeground(Color) Font getFont() void setFont(Font) Boolean getVisible() void setVisible(Boolean) Boolean getEnabled() void setEnabled(Boolean) Graphics getGraphics() repaint() repaint(int x, int y, int width, int height) void Paint(Graphics g) void Update(Graphics g)
2 1

Descripcin Devuelve el nombre del componente Para fijar el nombre del componente Devuelve el tamao del componente Para modificar el tamao del componente Anlogo al anterior Devuelve el color de fondo del componente Devuelve el color de primer plano del componente Fija el color de primer plano del componente Devuelve el tipo de letra asociado al componente Fija el tipo de letra del componente Indica si el componente es visible Muestra/oculta el componente (til para ventanas) Indica si el componente est activo Activa/desactiva el componente (til para botones y opciones de men) Devuelve el objeto tipo Graphics que puede dibujar en el componente Llamaremos a este mtodo para pedirle al componente que se redibuje Llamaremos a este mtodo para pedirle al componente que redibuje el rectngulo indicado Redefiniremos este mtodo (usando herencia) cuando queramos dibujar algo en el componente Mtodo que por defecto borra el componente y llama a paint() cuando hay que repintar un componente. Se utiliza sobre todo

void setBackground(Color) Fija el color de fondo del componente

Tema 5: Desarrollo de aplicaciones grficas


en animaciones Point3 getLocation() Indica la posicin de la esquina superior izquierda del componente en su contenedor Mueve el componente a la posicin indicada Indica a qu contenedor pertenece el componente

void setLocation(int x, int y) Mueve el componente a la posicin indicada void setLocation(Point p) Container getParent()

Algunas observaciones sobre estos mtodos: 1. La clase Dimension de AWT sirve para almacenar el ancho y el alto de un componente. Sus mtodos ms importantes son double getWidth(), double getHeight() y sus correspondientes set. 2. La clase Font de AWT representa los tipos de letra. Es una clase compleja que no vamos a ver en profundidad. La forma ms habitual de uso es como en este ejemplo:
// Arial de 12 pts en negrita Font fuenteNegrita = new Font("Arial",Font.BOLD,12);

Las constantes de formato son: Font.PLAIN, Font.BOLD y Font.ITALIC. 3. La clase Point de AWT se utiliza para representar las coordenadas de un punto (x,y). Tiene una constructora Point(x,y) y mtodos tales como int getX(), int getY(), void setX(int x), void setY(int y) y void move(int x, int y).

El siguiente diagrama muestra esquemticamente las clases derivadas de Component:

Tema 5: Desarrollo de aplicaciones grficas

Aunque no vamos a estudiarlas todas, conviene saber para qu sirve cada una de ellas, y referirnos a la ayuda de Java cuando sea necesario: Componentes Bsicos Clase Button Canvas Choice CheckBox Label List Scrollbar TextField TextArea Rectngulo para dibujar Lista desplegable (ej: lista de pases para elegir) Casillas cuadradas para marcar (como en un test) Etiqueta: caracteres que se muestran en un contenedor Lista, similar a Choice pero constantemente desplegada Barra de desplazamiento Campo de edicin que puede utilizar el usuario para introducir datos Similar a TextField pero permite introducir texto que ocupe varias lneas Descripcin Botones con un texto (Ej: Aceptar)

Tema 5: Desarrollo de aplicaciones grficas


Contenedore s Clase Panel Applet Window Frame Dialog FileDialog Descripcin Contenedor bsico que necesita formar parte de una ventana (o pgina) Panel preparado para formar parte de una pgina HTML Una ventana sin ttulo ni casillas para minimizar,cerrar,etc. Una ventana normal, con ttulo Ventana que se muestra sobre la ventana actual (Ej.: la tpica ventana para preguntar "Est seguro de ...." y dos botones de Aceptar y Cancelar) Similar al anterior, pero especializado para la seleccin de ficheros (se suele utilizar en las opciones de "Abrir" o "Grabar como" )

2.- Ventanas: la clase Frame


2.1 Abriendo las ventanas 2.2 Cerrando las ventanas 2.3 Ejemplo 2.4 Utilizacin de la herencia

2.1 Abriendo las ventanas


La clase Frame representa en AWT una ventana tal y como estamos acostumbrados a verlas en un entorno grfico. Dado que el resto de los componentes formarn parte de una ventana, parece lgico que comencemos por ella. Aviso: No es posible explicar en un espacio limitado todas las caractersticas de un componente visual complejo como Frame, o como el resto de los estudiados en este tema. Por tanto nos limitaremos a los aspectos bsicos, pero avisando de que en la ayuda de Java se pueden encontrar mtodos, constructoras, etc. no discutidos aqu. Para crear e inicializar una ventana AWT (Frame) vamos a seguir los siguientes pasos: Crear la variable tipo Frame Para eso utilizaremos alguna de las constructoras de la clase, que son:

Frame(): Constructora sin parmetros; crea una ventana sin ttulo Frame(String): Crea una ventana con el ttulo que se le indica Por ejemplo:
Frame ventana = new Frame("Ventana de prueba");

Tema 5: Desarrollo de aplicaciones grficas


Tamao y posicin iniciales El tamao se fija con el mtodo void setSize(int, int) y la posicin con setLocation(int,int). Ambos pertenecen a la clase Component. Ejemplo:
ventana.setSize(300, 100); ventana.setLocation(100,50);

Hay que observar que el tamao y la posicin dependen de la configuracin de la pantalla. Para conocer el tamao en pixels de la pantalla podemos utilizar el mtodo Toolkit.getDefaultToolkit().getScreenSize();, que devuelve un objeto de tipo Dimension. Por ejemplo, para que la ventana aparezca centrada y ocupe un tercio de la pantalla tanto en ancho como en alto podemos escribir:
Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); // calculamos el tamao de la ventana a partir del ancho de la pantalla int ancho=d.width/3; int alto=d.height/3; ventana.setSize(ancho, alto); ventana.setLocation(d.width/2-ancho/2,d.height/2-alto/2);

Otras inicializaciones (opcional) Tambin podemos fijar los colores, el tipo de letra, el ttulo (con void setTitle(String)) o el icono que mostrar la ventana al minimizarse (con void setImage(Image)). Por ejemplo:
ventana.setBackground(new Color(20,140,10)); ventana.setForeground(Color.blue); Font fuente = new Font("Arial", Font.PLAIN, 20); ventana.setFont(fuente); ventana.setTitle("Ejemplo de ventana ");

Fijar el estilo (opcional) Hablaremos de los "estilos" ms adelante. De momento baste con decir que el mtodo setLayout(Layout) determina el estilo de la ventana, es decir cmo se distribuyen los componentes en la ventana. Por ejemplo:
FlowLayout estilo = new FlowLayout(); ventana.setLayout(estilo);

har que los componentes se siten uno al lado del otro, de izquierda a derecha y de arriba a abajo. Observacin: Todos los estilos (como FlowLayout) son subclases de la clase Layout y por eso pueden ser utilizados como argumentos del mtodo setLayout. Es un ejemplo de polimorfismo. Incorporar los componentes En este paso se aaden los componentes que se desee incluir en la ventana. Para eso se utiliza el mtodo void add(Component) heredado de la clase Container. Por ejemplo:
Label etiq = new Label("Te estoy mirando...");

Tema 5: Desarrollo de aplicaciones grficas


ventana.add(etiq);

Observacin: Otro ejemplo de polimorfismo: etiq es de tipo Label, pero Label hereda de Component y por eso etiq puede ser argumento del mtodo add, cuyo argumento est declarado de tipo Component.

Aviso: Es importante que no olvidemos incorporar los componentes bsicos a un contenedor; en otro caso no podrn ser visibles. Mostrar la ventana Esto se hace con el mtodo setVisible heredado de Component.
ventana.setVisible(true);

Aviso: Un error habitual es olvidar este paso con lo que la ventana no se mostrar

Observacin: La utilizacin de setVisible permite "cambiar" de una ventana a otra, haciendo visible la que estaba oculta y viceversa.

Poniendo todo el cdigo anterior junto obtenemos la siguiente ventana:

2.2 Cerrando las ventanas


Una ventana puede recibir los siguientes tipos de eventos:

WINDOW_OPENED WINDOW_CLOSING WINDOW_CLOSED WINDOW_ICONIFIED WINDOW_DEICONIFIED WINDOW_ACTIVATED WINDOW_DEACTIVATED WINDOW_GAINED_FOCUS

Tema 5: Desarrollo de aplicaciones grficas


WINDOW_LOST_FOCUS WINDOW_STATE_CHANGED

Para tener acceso a ellos debemos: Escribir una clase para atenderlos. Esta clase debe heredar de WindowAdapter o bien implementar el interfaz WindowListener Pasarle a la ventana un objeto de ese tipo a la ventana mediante el mtodo addWindowListener. La ventana llamar al mtodo adecuado correspondiente a cada evento. Los mtodos son:

void windowActivated(WindowEvent e) void windowClosed(WindowEvent e) void windowClosing(WindowEvent e) void windowDeactivated(WindowEvent e) void windowDeiconified(WindowEvent e) void windowIconified(WindowEvent e) void windowOpened(WindowEvent e)

De todos ellos el que nos interesa ahora es windowClosing que se utiliza cuando el usuario trata de cerrar la ventana. Para que al pulsar se cierre realmente tendremos que incluir una llamada a System.exit(0), que fuerza el fin de la aplicacin. La clase puede ser por ejemplo:
class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }

Y el cdigo para que la ventana utilice este mtodo:


ParaAcabar acabar = new ParaAcabar(); ventana.addWindowListener(acabar);

Observacin: Si en lugar de heredar de WindowAdapter hubiramos implementado su interfaz correspondiente (WindowListener) habramos tenido que incluir todos los mtodos anteriores en la clase, aunque slo estemos interesados en uno de ellos.

Observacin: En swing el componente correspondiente se llama JFrame, y permite indicar que se quiere salir de la aplicacin al cerrar la ventana sin necesidad de escribir un objeto escucha, simplemente con:
JFrame ventana = new ... ....

Tema 5: Desarrollo de aplicaciones grficas


ventana.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

2.3 Ejemplo
El siguiente programa rene todos los conceptos anteriores:
Principal.java import java.awt.*; import java.awt.event.*; public class Principal { public static void main(String[] args) { // objeto de tipo ventana Frame ventana = new Frame("Ventana de prueba"); // ventana cuadrada centrada en la pantalla y // ocupando un tercio de la pantalla Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); // calculamos el tamao de la ventana a partir del ancho de la pantalla int ancho=d.width/3; int alto=d.height/3; ventana.setSize(ancho, alto); ventana.setLocation(d.width/2-ancho/2,d.height/2-alto/2); // colores, ttulo y fuente ventana.setBackground(new Color(20,140,10)); ventana.setForeground(Color.blue); Font fuente = new Font("Arial", Font.PLAIN, 20); ventana.setFont(fuente); ventana.setTitle("Ejemplo de ventana "); // estilo FlowLayout estilo = new FlowLayout(); ventana.setLayout(estilo); // componentes Label etiq = new Label("Te estoy mirando..."); ventana.add(etiq); // aadimos el "listener" para cerrar la ventana ParaAcabar acabar = new ParaAcabar(); ventana.addWindowListener(acabar); // hacemos la ventana visible ventana.setVisible(true); } } // clase escucha que se ejecuta al tratar de cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) {

Tema 5: Desarrollo de aplicaciones grficas


System.exit(0); // abandonar la aplicacin } }

Es interesante observar que la clase para cerrar la ventana se encuentra, por comodidad, en el mismo fichero que la clase principal. Esto es posible porque esta clase no es pblica. Observacin: En cada fichero .java puede haber una nica clase pblica, pero tambin se permite incluir otras clases -no pblicas- que sirvan de clases auxiliares de la clase pblica.

2.4 Utilizacin de la herencia


Es muy normal separar el cdigo asociado a la ventana del main, haciendo una clase aparte que se encargue de la gestin de la ventana. Entonces la aplicacin queda compuesta de dos clases: la clase Ventana, y la clase Principal que se limita a crear la ventana y a hacerla visible. La configuracin de la ventana (colores, tamao, posicin, componentes, escuchas, etc.) se har entonces en la constructora de la clase Ventana, que se definir hija de la clase Frame:
Ventana.java

import java.awt.*; import java.awt.event.*; public class Ventana extends Frame { public Ventana() { // ventana cuadrada centrada en la pantalla y // ocupando un tercio de la pantalla Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); // calculamos el tamao de la ventana a partir del ancho de la pantalla int ancho=d.width/3; int alto=d.height/3; setSize(ancho, alto); setLocation(d.width/2-ancho/2,d.height/2-alto/2); // colores, ttulo y fuente setBackground(new Color(20,140,10)); setForeground(Color.blue); Font fuente = new Font("Arial", Font.PLAIN, 20); setFont(fuente); setTitle("Ejemplo de ventana "); // estilo FlowLayout estilo = new FlowLayout(); setLayout(estilo); // componentes Label etiq = new Label("Te estoy mirando..."); add(etiq);

Tema 5: Desarrollo de aplicaciones grficas


// aadimos el "listener" para cerrar la ventana ParaAcabar acabar = new ParaAcabar(); addWindowListener(acabar); } } // clase escucha que se ejecuta al tratar de cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); // abandonar la aplicacin } }

De esta forma la clase ventana tiene todos los mtodos de la clase Frame ms todos los que nosotros aadamos posteriormente. La clase principal queda simplemente:
Principal.java public class Principal { public static void main(String[] args) { // objeto de tipo ventana Ventana ventana = new Ventana(); // hacemos la ventana visible ventana.setVisible(true); } }

y en el resto del captulo a menudo la omitiremos para evitar repetir el cdigo, que es independiente de la ventana.

3.- Componentes Bsicos


3.1 Etiquetas: la clase Label 3.2 Botones: la clase Button 3.3 Entrada de datos: la clase TextField 3.4 reas de texto: la clase TextArea 3.5 Marcas casillas: la clase Checkbox

3.1 Etiquetas: la clase Label


La clase Label(etiqueta) se utiliza para mostrar Strings en un componente. Constructoras Tiene 3 constructoras:

Label(): La constructora por defecto, crea una etiqueta con un String vaco.

Tema 5: Desarrollo de aplicaciones grficas


Label(String etiq): Etiq es el String a mostrar. Label(String etiq, int alineamiento): Permite indicar si la etiqueta se mostrar en el espacio reservado para ella en el component alineada a la izquierda (constante Label.LEFT), a la derecha (Label.RIGHT) o centrada (Label.CENTER).

Mtodos Aparte de los mtodos heredados de Object y Component, esta clase tiene dos mtodos importantes:

setText(String etiq): Para modificar el contenido de la etiqueta. String getText(): Devuelve el contenido actual de la etiqueta.

3.2 Botones: la clase Button


Este componente es bsico; sobre el suelen recaer las acciones del usuario y a menudo en sus escuchas asociadas se realiza la parte ms complicada del programa. La filosofa que se sigue es vlida para otros componentes que no discutimos aqu, como los mens. Constructoras Tiene 2 constructoras:

Button(): Botn con un mensaje vaco. Button(String etiq): Etiq es el String a mostrar como mensaje.

Mtodos Algunos de los mtodos ms importantes, adems de los heredados de Component, son:

void setLabel(String label) : Cambia la etiqueta del botn. String getLabel() : Devuelve la etiqueta actual. void setActionCommand(String command): Asocia un String al botn. Este String no se mostrar por pantalla, sino que se utilizar como identificador del botn. void addActionListener(ActionListener l): Para aadir una escucha que pueda reaccionar cuando se pulsa el botn. Se explica en el apartado siguiente.

Vamos a ver un primer ejemplo. En este ejemplo se separa la aplicacin en dos clases independientes: la clase con el main y la clase con la ventana: Ventana.java
package ventanas; import java.awt.*; import java.awt.event.*; public class Ventana extends Frame { Button botn;

Tema 5: Desarrollo de aplicaciones grficas


Label etiq; // constructora public Ventana() { // titulo, estilo, tamao y posicin iniciales setTitle("Ejemplo de ventana con boton (v.1) "); setLayout(new FlowLayout()); setSize(300, 100); setLocation(100,50); // le damos un poco de color a la ventana setBackground(Color.yellow); // una etiqueta etiq = new Label("Un botn:"); add(etiq); // creamos el botn botn = new Button("Plsame"); botn.setBackground(Color.blue); botn.setForeground(Color.white); // lo incorporamos a la ventana // importante: si no se hace esto no sera visible add(botn); // aadimos el "listener" para cerrar la ventana addWindowListener(new ParaAcabar()); } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { }

System.exit(0); }

En este ejemplo aparece la ventana pero al pulsar el botn todava no hace nada. En el siguiente apartado veremos como hacer que el botn "reaccione" cuando es pulsado. Eventos La idea es que no ser el propio botn sino un objeto escucha el que ser informado por Java para que acte cuando el botn sea pulsado. Para lograr esto hay que: 1. Escribir una clase adecuada a la que pertenecer el objeto escucha. Esta clase debe, en el caso de los botones, implementar el interfaz java.awt.event.ActionListener. 2. Declarar un objeto del tipo anterior (normalmente en la constructora de la ventana, a la vez que se crea el botn). 3. Asociar el objeto de tipo escucha con el botn o, dicho con la terminologa habitual de Java, registrar el objeto como escucha del botn. Esto se hace utilizando el mtodo void addActionListener(ActionListener l). El interfaz ActionListener tiene un slo mtodo: void actionPerformed(ActionEvent e), al que se invocar cuando ocurra un evento sobre el botn (normalmente que ha sido pulsado). El objeto ActionEvent nos servir para saber ms informacin acerca del evento, y normalmente se us cuando el mismo objeto de tipo ActionListener se utiliza de escucha

Tema 5: Desarrollo de aplicaciones grficas


para ms de un botn, ya que nos permite saber cul de los botones ha sido pulsado. En particular contiene 2 mtodos que pueden ser tiles.

String getActionCommand() . Object getSource(): Fuente del evento (objeto de tipo Button).

El siguiente ejemplo hace que el botn, al ser pulsado escriba por pantalla el mensaje "Gracias".
Ventana.java

package ventanas; import java.awt.*; import java.awt.event.*; public class Ventana extends Frame { Button botn; Label etiq; // constructora public Ventana() { // titulo, estilo, tamao y posicin iniciales setTitle("Ejemplo de ventana con boton (v.2) "); setLayout(new FlowLayout()); setSize(300, 100); setLocation(100,50); // le damos un poco de color a la ventana setBackground(Color.yellow); // una etiqueta etiq = new Label("Un botn:"); add(etiq); // creamos el botn botn = new Button("Plsame"); botn.setBackground(Color.blue); botn.setForeground(Color.white); // lo incorporamos a la ventana // importante: si no se hace esto no sera visible add(botn); // preparamos la escucha del boton Escucha e = new Escucha(); // la registramos botn.addActionListener(e); // aadimos la escucha para cerrar la ventana addWindowListener(new ParaAcabar()); } }

Tema 5: Desarrollo de aplicaciones grficas


// clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } // escucha del boton class Escucha implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Gracias"); } }

Ejercicio: Hacer que el botn escriba al hacer click el nmero de veces que ha sido pulsado desde que ha comenzado la aplicacin (solucin en el siguiente apartado). Interaccin con otros componentes grficos Supongamos que pretendemos que el botn cambie de color de fondo cada vez que se le pulse. Para ello podemos utilizar el mtodo setBackground y generar un color aleatorio utilizando el mtodo Math.random(). Un primer intento consiste en modificar la clase Escucha de la siguiente forma:
// escucha del boton class Escucha implements ActionListener { public void actionPerformed(ActionEvent e) { // generamos un color aleatorio Color c = new Color((int)(Math.random()*256),(int)(Math.random()*256), (int)(Math.random()*256)); // cambiamos el color del boton boton.setBackground(c); } }

Pero al compilar el cdigo anterior obtenemos un error:


C:\JCreator LE\MyProjects\gracias\ventanas\Ventana.java:67: cannot resolve symbol symbol : variable boton location: class ventanas.Escucha boton.setBackground(c); ^

La razn es que la variable boton no es visible dentro de la clase Escucha. Afortunadamente podemos obtener el botn a partir de la variable ActionEvent e de la siguiente forma:
// escucha del boton class Escucha implements ActionListener { public void actionPerformed(ActionEvent e) { Button boton = (Button) e.getSource(); // generamos un color aleatorio

Tema 5: Desarrollo de aplicaciones grficas


Color c = new Color((int)(Math.random()*256),(int)(Math.random()*256), (int)(Math.random()*256)); // cambiamos el color del boton boton.setBackground(c); } }

Esta solucin no se puede aplicar si queremos interactuar con otro componente distinto del botn. Ejemplo: Supongamos que queremos que al pulsar el botn se muestre en la etiqueta el nmero de veces que se ha pulsado el botn desde que comenz la aplicacin. En este caso no nos vale de nada la variable ActionEvent e; la etiqueta est definida en la clase ventana y debemos ''obtenerla'' de otra forma. Vamos a ver dos posibilidades: 1. Definir un atributo en la clase escucha que contendr una referencia al componente externo deseado. Este atributo se inicializar mediante la constructora. 2. En nuestro caso: 3. Ventana.java
4. 5. package ventanas; 6. 7. import java.awt.*; 8. 9. import java.awt.*; 10. import java.awt.event.*; 11. 12. public class Ventana extends Frame { 13. 14. // constructora 15. public Ventana() { 16. 17. // titulo, estilo, tamao y posicin iniciales 18. setTitle("Ejemplo de ventana con boton (v.3) "); 19. setLayout(new FlowLayout()); 20. setSize(300, 100); 21. setLocation(100,50); 22. 23. // le damos un poco de color a la ventana 24. setBackground(Color.yellow); 25. 26. // una etiqueta 27. Label etiq = new Label("An no has pulsado"); 28. add(etiq); 29. 30. // creamos el boton

Tema 5: Desarrollo de aplicaciones grficas


31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. Button boton = new Button("Plsame"); boton.setBackground(Color.blue); boton.setForeground(Color.white); // incorporamos el boton al frame // importante: si no se hace esto no sera visible add(boton); // preparamos la escucha del boton Escucha e = new Escucha(etiq); // la registramos boton.addActionListener(e); // aadimos el "listener" para cerrar la ventana addWindowListener(new ParaAcabar()); // la mostramos setVisible(true); } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } // escucha del boton class Escucha implements ActionListener { int i; // para contar las veces que se ha pulsado Label etiqueta; // etiqueta que se modificar public Escucha(Label etiqueta) { this.etiqueta = etiqueta; i=0; } public void actionPerformed(ActionEvent e) { i++; etiqueta.setText("Has pulsado "+i+" veces"); } }

80. Ahora s que el programa funcionar correctamente:

81.

Tema 5: Desarrollo de aplicaciones grficas


82. 83. Escribir la clase escucha dentro de la clase Ventana. 84. Java permite escribir una clase auxiliar dentro de la clase con la que ''colabora''. As podemos definir la clase escucha como una subclase privada de la clase Ventana, que al ser miembro de la clase tiene acceso a los atributos:
85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. package ventanas; import java.awt.*; import java.awt.*; import java.awt.event.*; public class Ventana extends Frame { private int contador; private Label etiq; private Button botn; // constructora public Ventana() { contador = 0; // titulo, estilo, tamao y posicin iniciales setTitle("Ejemplo de ventana con boton (v.3) "); setLayout(new FlowLayout()); setSize(300, 100); setLocation(100,50); // le damos un poco de color a la ventana setBackground(Color.yellow); // una etiqueta etiq = new Label("An no has pulsado"); add(etiq); // creamos el boton botn = new Button("Plsame"); botn.setBackground(Color.blue); botn.setForeground(Color.white); // incorporamos el boton al frame // importante: si no se hace esto no sera visible add(botn); // preparamos la escucha del boton Escucha e = new Escucha(); // la registramos botn.addActionListener(e); // aadimos el "listener" para cerrar la ventana addWindowListener(new ParaAcabar()); }

Tema 5: Desarrollo de aplicaciones grficas


130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. // escucha del botn private class Escucha implements ActionListener { public void actionPerformed(ActionEvent e) { contador++; etiq.setText("Has pulsado "+contador+" veces"); } } } // fin de la clase Ventana // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) {System.exit(0);} }

Esta solucin es ms sencilla; nos ahorramos la constructora, la copia de la referencia para acceder a los objetos, etc. A cambio es menos elegante y ms limitada; por ejemplo no nos permite definir la clase escucha en un fichero aparte, para poder compartirla por varias aplicaciones. Utilizando la misma escucha para varios botones Supongamos que queremos tener una etiqueta que haga de contador comenzando en 0. Incluiremos dos botones, uno para incrementar el contador y otro para decrementarlo. A la hora de establecer las escuchas hay dos posibilidades: 1. Escribir dos clases escucha, una para el botn de incrementar y otra para el de decrementar. 2. Utilizar la misma escucha para ambos. El segundo mtodo es, en este caso, ms cmodo, pero tenemos que ser capaces de distinguir dentro del mtodo actionPerformed cul de los dos botones ha sido pulsado, para as incrementar o decrementar el contador. Para esto podemos utilizar el mtodo setActionCommand de la clase Button y getActionCommand de ActionEvent, tal y como muestra el programa siguiente:
Ventana.java

package ventanas; import java.awt.*; import java.awt.*; import java.awt.event.*; public class Ventana extends Frame { // constructora public Ventana() { // titulo, estilo, tamao y posicin iniciales setTitle("contadores "); setLayout(new FlowLayout()); setSize(200, 100);

Tema 5: Desarrollo de aplicaciones grficas


setLocation(100,50); // le damos un poco de color a la ventana setBackground(Color.yellow); // las etiquetas Font fuente = new Font("Arial", Font.PLAIN, 20); Label etiq = new Label("Contador: "); etiq.setFont(fuente); add(etiq); Label etiq2 = new Label("0"); etiq2.setFont(fuente); add(etiq2); // preparamos la escucha del boton Escucha e = new Escucha(etiq2); // creamos los botones Button botonInc = new Button("Incremento"); botonInc.setActionCommand("inc"); botonInc.setBackground(Color.blue); botonInc.setForeground(Color.white); add(botonInc); botonInc.addActionListener(e); Button botonDec = new Button("Decremento"); botonDec.setActionCommand("dec"); botonDec.setBackground(Color.red); botonDec.setForeground(Color.white); add(botonDec); botonDec.addActionListener(e); // aadimos el "listener" para cerrar la ventana addWindowListener(new ParaAcabar()); } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } // escucha del boton class Escucha implements ActionListener { int contador; // para contar las veces que se ha pulsado Label etiqueta; // etiqueta que se modificar public Escucha(Label etiqueta) { this.etiqueta = etiqueta; contador=0; } public void actionPerformed(ActionEvent e) {

Tema 5: Desarrollo de aplicaciones grficas


if (e.getActionCommand().equals("inc")) contador++; else contador--; etiqueta.setText(" "+contador+" "); } }

El programa tendr el siguiente aspecto:

3.3 Entrada de datos: la clase TextField


Este componente se utiliza comnmente para leer datos de teclado. Constructoras Para TextField:

TextField(): Constructora por defecto conteniendo la cadena vaca y con 0 columnas. TextField(int columnas): Contenido vaco pero longitud prefijada inicial. TextField(String texto) Campo de texto con un valor inicial. TextField(String texto, int columnas): Las dos anteriores combinadas.

Mtodos La clase TextField coincide con las clases anteriores en la definicin de los mtodos setText(String cadena) y String getText(). Algunos otros mtodos de inters:

setEchoChar(Char c): Indica el carcter que aparece cuando se introduce un valor y se usa para introducir palabras clave. setEchoChar(0) hace que el carcter que aparece sea el carcter pulsado. setEditable(boolean): Si se pone a false no se podr escribir sobre el campo de edicin. int getSelectionStart(), int getSelectionEnd(): Para saber el trozo de texto que ha sido seleccionado por el usuario. Muy til para las acciones de "Copiar", "Cortar" y "Pegar". void setSelectionStart(int inicio), void setSelectionEnd(int fin): Para marcar una porcin de texto. En realidad setSelectionEnd(int fin) indica una posicin ms all de la ltima a marcar. Por ejemplo, para marcar los caracteres 2,3 y 4 (tercer, cuarto y quinto carcter) se utilizara: texto.setSelectionStart(2);

Tema 5: Desarrollo de aplicaciones grficas

texto.setSelectionEnd(5);

Eventos En cuanto a los eventos, la diferencia principal con la clase Button es que el mtodo ActionEvent de la clase escucha se utiliza cuando se pulsa Enter. Tambin se puede controlar cual es la tecla pulsada, como veremos al hablar de los eventos de teclado, pero estos eventos no son especficos de la clase TextField sino comunes a todos los Component. Ejemplo: Clase para representar una ventana de entrada a un sistema, con login y password:
PalabraClave.java

package claves; import java.awt.*; import java.awt.event.*; public class PalabraClave extends Frame { private Label etiq,etiq2,etiq3; private Button aceptar; private TextField login; private TextField pass; public PalabraClave() { // titulo, estilo, tamao y posicin iniciales setTitle("Entrada al Sistema"); setLayout(new FlowLayout()); // ventana centrada Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); int ancho=300, alto=200; setSize(ancho, alto); setLocation(d.width/2-ancho/2,d.height/2-alto/2); // tipo de letra Font fuente = new Font("Arial", Font.PLAIN, 18); setFont(fuente); // un poco de color setBackground(Color.cyan); // preparamos la entrada de datos etiq = new Label("Login: "); add(etiq); login = new TextField(8); add(login); etiq2 = new Label("Password:"); etiq2.setFont(fuente);

Tema 5: Desarrollo de aplicaciones grficas


add(etiq2); pass = new TextField(10); pass.setEchoChar('*'); add(pass); aceptar = new Button("Aceptar"); add(aceptar); etiq3 = new Label("Pulsa Aceptar para Continuar"); add(etiq3); // preparamos las escuchas EscuchaAceptar e = new EscuchaAceptar(); aceptar.addActionListener(e); pass.addActionListener(e); // esta vale slo para el campo de login EscuchaSiguiente pasaAlSiguiente = new EscuchaSiguiente(); login.addActionListener(pasaAlSiguiente); // aadimos la escucha para cerrar la ventana addWindowListener(new ParaAcabar()); } // escuchas como subclases privadas /////////////////////// // escucha del boton Aceptar private class EscuchaAceptar implements ActionListener { public void actionPerformed(ActionEvent e) { if (vlidos(login.getText(), pass.getText())) etiq3.setText("Datos vlidos"); else etiq3.setText("Datos no vlidos"); } private boolean vlidos(String login, String pass) { // aqu se comprueba return login.equals("Bertoldo") && pass.equals("nolose"); } } // clase escucha para el primer campo de edicin; le pasa el foco // al siguiente private class EscuchaSiguiente implements ActionListener { public void actionPerformed(ActionEvent e) { // componente sobre el que ha ocurrido el evento Component c = (Component) e.getSource(); // indicarle que pase el foco al siguiente elemento c.transferFocus(); } } ////////////////////// fin escuchas //////////////////////////////

Tema 5: Desarrollo de aplicaciones grficas


} // Ventana // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) {System.exit(0);} }

La ejecucin del programa tendr el siguiente aspecto:

3.4 reas de texto: la clase TextArea


Es similar a TextField con la diferencia de que al presentarse en pantalla permite introducir cdigo que ocupa ms de una lnea. Constructoras

TextArea(): rea de texto con una cadena vaca. Tamao de alrededor de 55 filas por 15 columnas TextArea(int filas, int columnas): Fija el nmero de filas y columnas. Si el nmero excede el tamao del TextArea se incluyen automticamente las barras de desplazamiento. TextArea(String texto): Texto inicial. TextArea(String texto, int filas, int columnas): Texto inicial con filas y columnas prefijadas. TextArea(String texto, int filas, int columnas, int barras): Aade al anterior la posibilidad de controlar la existencia de barras de desplazamiento. Los posibles valores de barras son: o SCROLLBARS_BOTH o SCROLLBARS_HORIZONTAL_ONLY o SCROLLBARS_NONE o SCROLLBARS_VERTICAL_ONLY

Mtodos y Eventos Los mtodos y eventos son como los de TextField con algunos mtodos aadidos, entre los que podemos destacar:

Tema 5: Desarrollo de aplicaciones grficas


void replaceRange(String str, int start, int end) : Cambia el texto entre las posiciones start y end por el texto str. insert(String str, int pos): Inserta el texto en la posicin indicada. append(String str): Aade el texto indicado al final.

3.5 Marcar casillas: la clase Checkbox


La clase Checkbox nos permite mostrar texto acompaado de casillas con dos estados: marcada o no marcada. Varios Checkbox pueden agruparse de forma que nos aseguremos de que slo una casilla est marcada en cada momento. Vamos a ver las dos posibilidades en dos ejemplos separados: Casillas no agrupadas En este caso basta con declarar y aadir los Checkbox independientemente. La etiqueta asociada a la casilla se puede fijar en la constructora o bien posteriormente con el mtodo setLabel(String). El estado (activada o no) se puede modificar y consultar con los mtodos setState(boolean) y getState(), respectivamente. El siguiente ejemplo muestra el uso de este componente:
Ventana.java import java.awt.*; import java.awt.event.*; public class Ventana extends Frame { // la ventana contiene 4 casillas private Checkbox casilla1,casilla2,casilla3,casilla4; // dos etiquetas Label etiq1, etiq2; // y un botn private Button aceptar; public Ventana() { // objeto de tipo ventana setTitle("Prueba de Checkbox"); setSize(380, 150); setLayout(new FlowLayout()); Font fuenteNegrita = new Font("Arial",Font.BOLD,16); setFont(fuenteNegrita) ; etiq1 = new Label("Marque sus aficiones favoritas y pulse Aceptar"); add(etiq1); // una forma de construir una casilla casilla1 = new Checkbox(); casilla1.setLabel("Deportes"); // otra forma casilla2 = new Checkbox("Lectura"); casilla3 = new Checkbox("Viajes"); casilla4 = new Checkbox("Cine"); // hacemos que la casilla Cine aparezca marcada casilla4.setState(true);

Tema 5: Desarrollo de aplicaciones grficas


add(casilla1); add(casilla2); add(casilla3); add(casilla4); aceptar = new Button("Aceptar"); add(aceptar); // escucha del botn aceptar.addActionListener(new EscuchaBotn()); // etiqueta donde se mostrar el resultado etiq2 = new Label(""); // aadimos la escucha para cerrar la ventana addWindowListener(new ParaAcabar()); } ////////////////////////////////////////////////////// // escucha del boton class EscuchaBotn implements ActionListener { public void actionPerformed(ActionEvent e) { String aficiones = "Ha elegido: "; if (casilla1.getState()) aficiones += casilla1.getLabel()+" if (casilla2.getState()) aficiones += casilla2.getLabel()+" if (casilla3.getState()) aficiones += casilla3.getLabel()+" if (casilla4.getState()) aficiones += casilla4.getLabel()+" // aadimos a la ventana un label con los objetos elegidos add(new Label(aficiones)); } } } // clase escucha que se ejecuta al tratar de cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); // abandonar la aplicacin } }

"; "; "; ";

El resultado es:

Casillas agrupadas Similar al anterior, pero agrupando las casillas por medio de un objeto tipo CheckboxGroup, para lo que se usa una tercera constructora que permite indicar el grupo al que pertenece la casilla, as como si est activa (cada grupo tendr como mximo una casilla marcada). Los mtodos de CheckboxGroup Checkbox getSelectedCheckbox() y void

Tema 5: Desarrollo de aplicaciones grficas


setSelectedCheckbox(Checkbox) sirven para obtener y cambiar, respectivamente, el Checkbox seleccionado. Ejemplo:
Ventana.java import java.awt.*; import java.awt.event.*; public class Ventana extends Frame { // grupo de 3 casillas private CheckboxGroup grupo; private Checkbox c1,c2,c3; // y una etiqueta Label etiq1; public Ventana() { setTitle("Prueba de CheckboxGroup"); setSize(300, 80); setBackground(Color.yellow); setLayout(new FlowLayout()); Font fuenteNegrita = new Font("Arial",Font.BOLD,16); setFont(fuenteNegrita) ; etiq1 = new Label("Destino:"); add(etiq1); // primero se construye el "agrupador" grupo = new CheckboxGroup(); // ahora se crean las casillas indicando que estn en el grupo c1 = new Checkbox("Madrid",grupo,false); c2 = new Checkbox("Pars",grupo,false); c3 = new Checkbox("Berln",grupo,true); // aadir las casillas a la ventana; el grupo NO se aade add(c1); add(c2); add(c3); // aadimos la escucha para cerrar la ventana addWindowListener(new ParaAcabar()); } } // clase escucha que se ejecuta al tratar de cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); // abandonar la aplicacin } }

El resultado es:

Tema 5: Desarrollo de aplicaciones grficas

4.- Eventos de teclado y de ratn


4.1 Eventos de teclado 4.2 Eventos de ratn

4.1 Eventos de teclado


Los eventos de teclado detectan la pulsacin de teclas. Cualquier componente puede registrar una escucha de teclado, al igual que una escucha para el ratn. El componente que recibe la entrada de teclado en cada momento es nico; se dice que ese componente "tiene el foco". Un componente puede pedir el foco utilizando el mtodo requestFocus(). Para detectar los eventos de teclado, un componente debe: Escribir una clase que implemente el interfaz KeyListener. Declarar un objeto de la clase anterior. Registrarlo con addKeyListener(KeyListener escucha), un mtodo de la clase Component. El interfaz KeyListener dispone de los siguientes mtodos:

void keyPressed(KeyEvent e): Tecla pulsada. void keyReleased(KeyEvent e): Se dej de pulsar la tecla. void keyTyped(KeyEvent e): La combinacin de las dos anteriores.

Por su parte, el parmetro de tipo KeyEvent contiene los siguientes mtodos que nos ayudan a identificar la tecla concreta:

char getKeyChar(): Devuelve el carcter asociado a la tecla, si es una tecla normal (imprimible). Las teclas especiales devuelven la constante CHAR_UNDEFINED. boolean isActionKey(): Devuelve true si la tecla es una tecla especial o false si es imprimible. int getKeyCode(): Devuelve una constante identificando a la tecla si es una tecla especial. Algunas de estas constantes son: VK_ACCEPT, VK_ALT, VK_ALT_GRAPH, VK_BACK_QUOTE, VK_BACK_SLASH, VK_BACK_SPACE, VK_CANCEL, VK_CAPS_LOCK, VK_CLEAR, VK_CLOSE_BRACKET, VK_CODE_INPUT, VK_COLON, VK_COMMA, VK_COMPOSE, VK_CONTROL, VK_COPY, VK_CUT, VK_DELETE, VK_DOWN, VK_END, VK_ENTER, VK_ESCAPE, VK_EURO_SIGN, VK_F1, VK_F10, VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16, VK_F17, VK_F18, VK_F19, VK_F2, VK_F20, VK_F21, VK_F22, VK_F23, VK_F24, VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_FINAL, VK_FIND, VK_HELP, VK_HOME, VK_INSERT, VK_LEFT, VK_NUM_LOCK, VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9, VK_O,

Tema 5: Desarrollo de aplicaciones grficas


VK_PAGE_DOWN, VK_PAGE_UP, VK_PASTE, VK_PAUSE, VK_PRINTSCREEN, VK_RIGHT, VK_SCROLL_LOCK, VK_SHIFT, VK_STOP, VK_TAB, VK_UNDEFINED, VK_UNDO, VK_UP. Ejemplo: Hacer que la posicin de una etiqueta cambie con las teclas de cursor. El programa tambin avisar si se pulsa la tecla Bloq. Nm.
Teclas.java

import java.awt.*; import java.awt.event.*; public class Teclas extends Frame { private Label etiq; // nico componente public Teclas() { // titulo, estilo, tamao y posicin iniciales setTitle("Teclas"); setLayout(new FlowLayout()); // ventana centrada Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); int ancho=300, alto=200; setSize(ancho, alto); setLocation(d.width/2-ancho/2,d.height/2-alto/2); // tipo de letra Font fuente = new Font("Arial", Font.PLAIN, 18); setFont(fuente); // un poco de color setBackground(Color.cyan); // preparamos la entrada de datos etiq = new Label("Pulsa 'S' para salir add(etiq); ");

// escucha de teclado para la ventana; // le pasamos como parmetro la etiqueta EscuchaTeclas e = new EscuchaTeclas(etiq); addKeyListener(e); // aadimos la escucha para cerrar la ventana addWindowListener(new ParaAcabar()); // si no hacemos esto el foco se lo queda la etiqueta!!! requestFocus(); } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter {

Tema 5: Desarrollo de aplicaciones grficas


public void windowClosing(WindowEvent e) { System.exit(0); } } // escucha de teclaro class EscuchaTeclas implements KeyListener { private Label etiq; public EscuchaTeclas(Label etiq) { this.etiq = etiq; } public void keyPressed(KeyEvent e){ if (e.isActionKey()==false && e.getKeyChar() == 'S') { System.exit(0); } else { // guardamos el cdigo de la tecla especial int tecla = e.getKeyCode(); // la posicin actual de la etiqueta Point pos = etiq.getLocation(); switch(tecla) { case KeyEvent.VK_UP: etiq.setLocation(pos.x,pos.y-1); break; case KeyEvent.VK_DOWN: etiq.setLocation(pos.x,pos.y+1); break; case KeyEvent.VK_LEFT: etiq.setLocation(pos.x-1,pos.y); break; case KeyEvent.VK_RIGHT: etiq.setLocation(pos.x+1,pos.y); break; case KeyEvent.VK_NUM_LOCK: etiq.setText("Bloque numrico"); break; default: } } } // hay que incluir estos mtodos aunque no se necesiten public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } }

4.2 Eventos de ratn

Tema 5: Desarrollo de aplicaciones grficas


Existen dos interfaces para el control del ratn, cada uno correspondiendo a un tipo de evento. MouseListener Sirve para detectar las pulsaciones del ratn y responde a los eventos del tipo MouseEvent. El interfaz consta de 5 mtodos:

void mouseClicked(MouseEvent e): Se ha pulsado el ratn. void mouseEntered(MouseEvent e): El ratn se ha situado sobre un componente (aunque no se haya pulsado). void mouseExited(MouseEvent e): El ratn abandona el componente sobre el que estaba situado. void mousePressed(MouseEvent e): Se ha pulsado un botn del ratn. void mouseReleased(MouseEvent e): Se ha soltado un botn del ratn que estaba pulsado.

La clase MouseEvent tiene entre otros mtodos:


int getX() : coordenada x del ratn. int getY() : : coordenada y del ratn. Point getPoint() : posicin del ratn. int getClickCount() : Informa sobre el nmero de pulsaciones, para distinguir el "doble-click". int getButton() : Informa sobre el botn que ha cambiado de estado. Puede devolver las constantes: BUTTON1, BUTTON2, BUTTON3.

Ejemplo: Vamos a mover un botn para que el usuario no pueda pulsarlo nunca:
CorreRaton.java

import java.awt.*; import java.awt.event.*; public class CorreRaton extends Frame { public CorreRaton() { // titulo, estilo, tamao y posicin iniciales setTitle("Botn tmido"); setLayout(new FlowLayout()); setBackground(Color.cyan); // ventana centrada Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); int ancho=300, alto=150; setSize(ancho, alto); setLocation(d.width/2-ancho/2,d.height/2-alto/2); // preparamos la entrada de datos Button botn = new Button("Plsame"); add(botn);

Tema 5: Desarrollo de aplicaciones grficas


// escucha de teclado para la ventana EscuchaRatn e = new EscuchaRatn(botn); botn.addMouseListener(e); // aadimos la escucha para cerrar la ventana addWindowListener(new ParaAcabar()); // la mostramos setVisible(true); // si no hacemos esto el foco se lo queda la etiqueta!!! requestFocus(); } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } class EscuchaRatn implements MouseListener { Button botn; // le pasamos el botn y el tamao de la pantalla public EscuchaRatn(Button botn) { this.botn = botn; } public void mouseEntered(MouseEvent e) { Point p = botn.getLocation(); if (p.x<150) p.x = 160 + ((int)(Math.random()*120)); else p.x = 20 + ((int)(Math.random()*120)); p.y = 20 + ((int) (Math.random()*100)); botn.setLocation(p); } // no olvidar incluir estos mtodos!! public void mouseClicked(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } }

MouseMotionListener

Tema 5: Desarrollo de aplicaciones grficas


Detecta los movimientos del ratn, y tambin cuando el ratn se arrastra pulsado (para marcar zonas). Este interfaz tiene dos mtodos:

void mouseMoved(MouseEvent e): El ratn se ha movido sin estar pulsado void mouseDragged(MouseEvent e): El ratn se ha movido estando pulsado.

5.- Estilos
5.1 Introduccin 5.2 Estilo FlowLayout 5.3 Estilo BorderLayout 5.4 Estilo GridLayout 5.5 Paneles

5.1 Introduccin
El estilo (o diseo) de un contenedor indica cmo se dispondrn los componentes bsicos en l. Se establece mediante el mtodo void setLayout(LayoutManager l) de la clase Container. La clase LayoutManager es la clase de la que heredan todos los estilos (layouts). Cada contenedor tiene un estilo por defecto. Por ejemplo, en el caso de Frame este es BorderLayout, y en el de Panel FlowLayout. Observacin: Aunque cada contenedor tiene un nico estilo, podemos mezclar estilos incorporando contenedores dentro de contenedores. La clase Panel est pensada con este propsito. Igual que en los puntos anteriores, aqu no vamos a ver todos los estilos de los que dispone Java (hay 21 estilos diferentes!), contentndonos con ver algunos de los ms comunes y esperando que sea suficiente para captar la "filosofa" y que a partir de stos comprender el resto sea ms sencillo.

5.2 Estilo FlowLayout


En este estilo los componentes se colocan uno al lado del otro, en la misma fila. Cuando no caben ms se cambia de fila. El orden en el que se colocan es de izquierda a derecha y de arriba a abajo. De los estilos slo nos interesarn, en general, sus constructoras, no los mtodos que contienen: Constructoras Tiene 3 constructoras:

FlowLayout(): Constructora por defecto; cada fila se alinea al centro.

Tema 5: Desarrollo de aplicaciones grficas

FlowLayout(int alineamiento): Indica si cada fila aparecer alineada al centro, a la izquierda o a la derecha. Para ello define las constantes FlowLayout.CENTER, FlowLayout.LEFT y FlowLayout.RIGHT. FlowLayout(int alineamiento, int sepH, int sepV) : Como el anterior, pero permitiendo indicar, adems, la separacin entre columnas y entre filas.

Ejemplo: Aadimos 10 botones para ver como se colocan en la ventana con FlowLayout
EstiloFlowLayout.java

import java.awt.*; import java.awt.event.*; public class EstiloFlowLayout extends Frame { public EstiloFlowLayout() { // titulo, estilo, tamao y posicin iniciales setTitle("FlowLayout"); setBackground(Color.cyan); setSize(300,200); // componentes centrados a la derecha, con una distancia entre ellos // de 20 pixels en x y 30 en y setLayout(new FlowLayout(FlowLayout.RIGHT, 20,30)); // aadimos unos botones de pega for (int i=0; i<10; i++) add(new Button(" "+i+" ")); // aadimos la escucha para cerrar la ventana addWindowListener(new ParaAcabar()); } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) {System.exit(0); } }

El resultado es:

Tema 5: Desarrollo de aplicaciones grficas

5.3 Estilo BorderLayout


Es el estilo por defecto de Frame. El estilo BorderLayout divide el contenedor en 5 reas: Norte, Sur, Este, Oeste y centro, indicadas por las 5 constantes: BorderLayout.NORTH, BorderLayout.SOUTH, BorderLayout.EAST, BorderLayout.WEST y BorderLayout.CENTER. Cada componente puede ocupar un rea nicamente; y a ser posible debe ocuparla por entero. Si se aaden dos componentes a la misma rea, slo ser visible el ltimo de ellos. El rea que ocupa el componente se indica al incorporarlo al contenedor con add. Si no se indica nada se colocar en el centro. Constructoras

BorderLayout(): Constructora por defecto. BorderLayout(int sepHorizontal, int sepVertical): Incluye la separacin en pixels entre los componentes.

Ejemplo
Ventana.java

import java.awt.*; import java.awt.event.*; public class Ventana extends Frame { public Ventana() { // titulo, estilo, tamao y posicin iniciales setTitle("BorderLayout"); setBackground(Color.cyan); setSize(300,200); // componentes centrados a la derecha, con una distancia entre ellos // de 20 pixels en x y 30 en y setLayout(new BorderLayout());

Tema 5: Desarrollo de aplicaciones grficas


// creamos 5 botones Button este = new Button("Este"); este.setBackground(Color.blue); Button oeste = new Button("Oeste"); oeste.setBackground(Color.red); Button norte = new Button("Norte"); norte.setBackground(Color.yellow); Button sur = new Button("Sur"); sur.setBackground(Color.green); Button centro = new Button("Centro"); centro.setBackground(Color.pink); // aadimos botones en cada zona add(este, BorderLayout.EAST); add(oeste, BorderLayout.WEST); add(norte, BorderLayout.NORTH); add(sur, BorderLayout.SOUTH); add(centro); // equivalente a: add(centro, BorderLayout.CENTER); // aadimos la escucha para cerrar la ventana addWindowListener(new ParaAcabar()); } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }

El resultado es:

Observacin: Casi nunca se inserta un botn directamente en un componente con estilo BorderLayout. Lo normal es introducirlos en otro componente (por ejemplo en un Panel) que a su vez se inserta en el contenedor de estilo BorderLayout.

5.4 Estilo GridLayout

Tema 5: Desarrollo de aplicaciones grficas


Es un estilo que divide el contenedor en "casillas". Permite fijar el nmero de componentes por fila y por columna. Todas las casillas sern del mismo tamao, tamao suficiente para que quepan todos los componentes. Los componentes se van colocando en la siguiente posicin libre, comenzando desde arriba a la izquierda. Constructoras

GridLayout(): Constructora por defecto: una sola fila y una sola columna; poco usada. GridLayout(int filas, int columnas): Nmero de filas y columnas. GridLayout(int filas, int columnas, int sepHorizontal, int sepVertical): Adems del tamao en filas y columnas indica la separacin horizontal y vertical entre los componentes.

Ejemplo
Grid.java

import java.awt.*; import java.awt.event.*; public class Grid extends Frame { public Grid() { // titulo, estilo, tamao y posicin iniciales setTitle("GridLayout"); setBackground(Color.yellow); setSize(250,150); // componentes en 4 filas, a 2 columnas, // 10 pixels de separacin horizontal entre componentes // y 5 pixels de separacin vertical setLayout(new GridLayout(4,2,10,5)); add(new Label("Nombre: ", Label.RIGHT)); TextField nombre = new TextField(10); add(nombre); add(new Label("Apellidos: ", Label.RIGHT)); TextField apellidos = new TextField(20); add(apellidos); add(new Label("Direccin: ", Label.RIGHT)); TextField direccin = new TextField(30); add(direccin); Button continuar = new Button("Siguiente"); add(continuar); Button abandonar = new Button("Cancelar"); add(abandonar);

Tema 5: Desarrollo de aplicaciones grficas


// faltaran todas las escuchas para que el programa haga algo real // aadimos la escucha para cerrar la ventana addWindowListener(new ParaAcabar()); } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); }

El resultado es:

5.5 Paneles
La clase Panel representa un contenedor que no puede existir por su cuenta, slo insertado en otro contenedor (como por ejemplo en un Frame(). Su estilo por defecto es FlowLayout, aunque como en todos los contenedores se puede modificar con setLayout. Se utiliza a menudo para combinar diferentes estilos en una misma ventana. Observacin: Una fase importante al desarrollar aplicaciones con interfaz grficos es la del diseo del interfaz: qu paneles compondrn cada ventana y con qu estilos.

Ejemplo: Vamos a escribir el aspecto previo que tendra una aplicacin para jugar al ajedrez; incluyendo el tablero vaco, un ttulo inicial y botones para comenzar y salir. El resultado debe ser:

Tema 5: Desarrollo de aplicaciones grficas

Antes de escribir el programa pensamos en el diseo de la ventana:

Con este diseo podemos escribir el cdigo:

Tema 5: Desarrollo de aplicaciones grficas


Tablero.java import java.awt.*; import java.awt.event.*; public class Tablero extends Frame { public Tablero() { // titulo, estilo, tamao y posicin iniciales setTitle("Tablero"); setBackground(Color.green); // ventana centrada Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); int ancho=300, alto=350; setSize(ancho, alto); setLocation(d.width/2-ancho/2,d.height/2-alto/2); // preparamos el layout de la ventana setLayout(new BorderLayout(20,20)); // ponemos la etiqueta Font fuente = new Font("Arial", Font.BOLD, 20); Label etiq = new Label("A J E D R E Z ", Label.CENTER); etiq.setFont(fuente); etiq.setForeground(new Color(100,0,50)); add(etiq, BorderLayout.NORTH); // preparamos el tablero; ser el panel central Panel tablero = new Panel(); tablero.setLayout(new GridLayout(8,8)); for (int i=1; i<=8; i++) for (int j=1; j<=8; j++) if ((i+j) % 2 == 0) { Button blanca = new Button(" "); blanca.setBackground(Color.white); blanca.setEnabled(false); tablero.add(blanca); } else { Button negra = new Button(" "); negra.setBackground(Color.black); negra.setEnabled(false); tablero.add(negra); } // lo ponemos en el centro add(tablero,BorderLayout.CENTER); // tablero para los botones Panel botones = new Panel(); Button empezar = new Button("Empezar");

Tema 5: Desarrollo de aplicaciones grficas


Button acabar = new Button("Acabar"); // no dejamos que pulsen acabar si no se est jugando acabar.setEnabled(false); botones.add(empezar); botones.add(acabar); add(botones, BorderLayout.SOUTH); // paneles para dejar margen a la izquierda y a la derecha Panel izq = new Panel(); Panel der = new Panel(); add(izq,BorderLayout.EAST); add(der,BorderLayout.WEST); // aadimos la escucha para cerrar la ventana addWindowListener(new ParaAcabar()); } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }

6.- Dibujando
6.1 Introduccin 6.2 La clase Canvas 6.3 La clase Graphics 6.4 Mostrando imgenes 6.5 Un poco de animacin

6.1 Introduccin
Cmo dibujar? Para dibujar en Java hay que conocer inicialmente los siguiente conceptos.

Los objetos capaces de dibujar son los de tipo Graphics (descritos en el punto 4.6.3). Contienen mtodos para dibujar lneas, rectngulos, imgenes ledas de un fichero (formato .gif o jpeg) etc. Todo componente grfico contiene un objeto de tipo Graphics, que es el que usa para "dibujarse" a si mismo. Todo componente grfico incluye un mtodo Graphics getGraphics()

Tema 5: Desarrollo de aplicaciones grficas


De todo esto se deduce que para dibujar podemos "pedirle prestado" su objeto Graphics() al componente en el que queramos dibujar. Ejemplo: Botn subrayado (primera versin). Ventana.java

import java.awt.*; import java.awt.event.*; public class Ventana extends Frame{ public Ventana() { // titulo, estilo, tamao y posicin iniciales setTitle("Botn con dibujo V.1"); setLayout(new FlowLayout()); Font fuente = new Font("Arial", Font.BOLD, 40); setFont(fuente); // ventana centrada Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); int ancho=200, alto=90; setSize(ancho, alto); setLocation(d.width/2-ancho/2,d.height/2-alto/2); Button botn = new Button("Aceptar"); add(botn); // aadimos el "listener" para cerrar la ventana addWindowListener(new ParaAcabar()); // la mostramos setVisible(true); // dibujamos sobre el botn Graphics g = botn.getGraphics(); g.setColor(Color.green); g.fill3DRect(5,40,70,10,true); g.fill3DRect(80,40,90,10,true); } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }

El resultado es:

Tema 5: Desarrollo de aplicaciones grficas

El problema est en que cada vez que se repinta el botn no se vuelve a pintar la lnea. De hecho el dibujo slo se hace una vez, al estar en la constructora, y cada vez que hay que pintar el botn. El mtodo paint Para arreglar este problema hay que saber algunas cosas ms.

Cuando un objeto necesita repintarse, llama a su mtodo public void update(Graphics g). El comportamiento por defecto de update es: o Borrar el componente. o Llamar al mtodo public void paint(Graphics g) para dibujarlo de nuevo. Nosotros no podemos llamar a estos mtodos directamente; pero podemos pedir a un componente que se "repinte" con el mtodo public void repaint().

As pues, la solucin est en sobreescribir el mtodo paint() del componente en el que queremos dibujar; y para ello deberemos hacer una nueva clase que herede de la clase de dicho componente, tal y como muestra el siguiente ejemplo: Ejemplo: Botn subrayado (segunda versin).
BotonSubrayado.java

import java.awt.*; public class BotonSubrayado extends Button { public BotonSubrayado(String nombre) { super(nombre); } public void paint(Graphics g) { // llamamos al pintar original super.paint(g); g.setColor(Color.green); g.fill3DRect(5,40,70,10,true); g.fill3DRect(80,40,90,10,true); } }

Ventana.java

import java.awt.*;

Tema 5: Desarrollo de aplicaciones grficas


import java.awt.event.*; public class Ventana extends Frame{ public Ventana() { // titulo, estilo, tamao y posicin iniciales setTitle("Botn con dibujo V.1"); setLayout(new FlowLayout()); Font fuente = new Font("Arial", Font.BOLD, 40); setFont(fuente); // ventana centrada Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); int ancho=200, alto=90; setSize(ancho, alto); setLocation(d.width/2-ancho/2,d.height/2-alto/2); BotonSubrayado botn = new BotonSubrayado("Aceptar"); add(botn); // aadimos el "listener" para cerrar la ventana addWindowListener(new ParaAcabar()); // la mostramos setVisible(true); Graphics g = botn.getGraphics(); g.setColor(Color.green); g.fill3DRect(5,40,70,10,true); g.fill3DRect(80,40,90,10,true); } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }

Ahora cada vez que haya que volver a pintar el botn se dibujar tambin la lnea

6.2 La clase Canvas


Aunque hemos visto que se puede dibujar en cualquier componente, lo normal es querer dibujar slo en un espacio en blanco destinado a tal fin. Con este propsito se incluye en java el componente Canvas. El procedimiento para incluir grficos como parte de una ventana es: 1. Declarar una clase que herede de canvas. 2. Sobrescribir el mtodo void paint(Graphics g) (y/o void update(Graphics g)) de la nueva clase de forma que se dibuje el grfico deseado. 3. Aadir un objeto de la clase nueva como componente de la ventana.

Tema 5: Desarrollo de aplicaciones grficas


Una aplicacin hecha siguiendo esta idea tendr al menos tres clases, con la siguiente estructura: Lienzo.java
import java.awt.*; // clase para dibujar public class Lienzo extends Canvas { ... // aqu se incluir el cdigo para dibujar public void paint(Graphics g) { .... } ..... }

Ventana.java
import java.awt.*; import java.awt.event.*; public class Ventana extends Frame { ...... public Ventana() { .... .... Lienzo l = new Lienzo(); add(l); ....... ...... } } ......

Principal.java
public class Principal { public static void main(String[] args) { new Ventana(); } }

Tema 5: Desarrollo de aplicaciones grficas


6.3 La clase Graphics
De esta clase no nos interesan sus constructoras, porque nunca vamos a construir un objeto Graphics; slo vamos a utilizar un objeto ya existente.

Mtodos Principales
abstract clearRect(int x, int y, int width, int height) void Borra el rectngulo especificado por sus parmetros; es decir

lo pinta del

color de fondo.
abstract copyArea(int x, int y, int width, int height, int dx, int dy) void Copia el rea del componente especificada por los parmetros a una

distancia dx and dy. Si se quiere que se copie a la izquierda habr que dar un valor dx negativo. Anlogamente, para copiar ms arriba de la posicin actual habr que indicar un valor dy negativo.
void draw3DRect(int x, int y, int width, int height, boolean raised)

Dibuja un rectngulo al que se da aspecto de 3d, bien mostrndolo ligeramente elevado (si raised es true) o hundido (raised false)
abstract drawArc(int x, int y, int width, int height, int startAngle, void int arcAngle) Dibuja un arco (circular o elptico), empezando en el ngulo startAngle y finalizando en arcAngle. El arco estar inscrito en el rectngulo indicado

por los parmetros, con centro en el centro de dicho rectngulo. Ejemplo: El siguiente arco est escrito con la instruccin g.drawArc(50,50,150,100,0,260);. Tambin se muestra en el dibujo el rectngulo (dibujado con g.drawRect(50,50,150,100);).

abstract drawImage(Image img, int x, int y, Color bgcolor, boolean ImageObserver observer) Dibuja la imagen. Las coordenadas (x,y) marcan donde estar situada la esquina superior izquierda del dibujo y bgcolor el fondo que se mostrar en la parte transparente de la imagen. El parmetro observer indica un objeto

al que se va avisando cuando segn se va mostrando la imagen. Nosotros lo lo utilizaremos y lo pondremos a null.
abstract drawImage(Image img, int x, int y, ImageObserver observer) boolean Anlogo al anterior. El color de fondo no vara. abstract drawImage(Image img, int x, int y, int width, int height,

Tema 5: Desarrollo de aplicaciones grficas


boolean bgcolor, ImageObserver observer)

Anlogo a los anteriores con la salvedad de que el grfico se reescalar para ajustarse al rectngulo indicado.
abstract drawImage(Image img, int x, int y, int width, int height, boolean ImageObserver observer)

Anlogo al anterior.
abstract drawLine(int x1, int y1, int x2, int y2) void Dibuja una lnea, en el color actual, entre los dos puntos.

Observacin: Si el punto final es igual al inicial se dibuja un punto. Esto es importante porque no existe ningn mtodo para dibujar puntos, por lo que lo normal es utilizar drawLine(x,y,x,y).
abstract drawOval(int x, int y, int width, int height) void Dibuja un valo inscrito en el rectngulo indicado. Si width = height

se

dibujar una circunferencia


abstract drawPolygon(int[] x, int[] y, int n) void Dibuja un polgono. Para ello traza las rectas (x[0],y[0]),

(x[1],y[1]) ... (x[n-

2],y[n-2]), (x[n-1],y[n-1]), (x[n-1],y[n-1]), (x[0],y[0]).


abstract drawPolyline(int[] xPoints, int[] yPoints, int nPoints) void Dibuja una secuencia de lneas. La diferencia con drawPolygon es que no

incluye la ltima lnea para "cerrar" el polgono.


void drawRect(int x, int y, int width, int height)

Dibuja un rectngulo.
abstract drawRoundRect(int x, int y, int width, int height, int void arcWidth, int arcHeight)

Dibuja un rectngulo con los ngulos "redondeados".


abstract drawString(String str, int x, int y) void Muestra la cadena. El punto (x,y) representa la posicin

inicial (marcada por un punto en la figura de abajo) para el primer carcter de la cadena.

void fill3DRect(int x, int y, int width, int height, boolean raised)

Anlogo a draw3DRect pero dibujando el rectngulo relleno con el color actual.


abstract fillArc(int x, int y, int width, int height, int startAngle, void int arcAngle)

Anlogo a drawArc pero dibujando el arco relleno con el color actual.


abstract fillOval(int x, int y, int width, int height) void Anlogo a fillOval pero con el valo relleno del color actual. abstract fillPolygon(int[] xPoints, int[] yPoints, int nPoints) void Anlogo a drawPolygon pero rellenando el polgono con el color actual.

Tema 5: Desarrollo de aplicaciones grficas


abstract fillRect(int x, int y, int width, int height) void Anlogo a drawRect pero rellenando el rectngulo del color

actual.

abstract fillRoundRect(int x, int y, int width, int height, int void arcWidth, int arcHeight)

Anlogo a drawRoundRect pero rellenando el rectngulo redondeado con el color actual.


void finalize()

Para liberar la memoria requerida por un objeto Graphics que ya no es necesario. Esto se hace porque los objetos Graphics son muy costosos en cuanto a recursos de memoria.
abstract getColor() Color Devuelve el color actual. abstract getFont() Font Devuelve la

fuente (tipo de letra) actual.

FontMetrics getFontMetrics()

Devuelve un valor de tipo FontMetrics representando las caractersticas mtricas de la fuente de letra actual. La clase FontMetrics contiene diversos mtodos para conocer las medidas de los caracteres dentro del tipo actual. Por ejemplo el mtodo stringWidth(String cadena) devolver la anchura en pixels requerida para mostrar la cadena.
abstract getFontMetrics(Font f) FontMetrics Devuelve las caractersticas

mtricas de la fuente de letra que se le pasa

como parmetro.
abstract setColor(Color c) void Cambia el color actual

al color indicado. de letra.

abstract setFont(Font font) void Establece la nueve fuente abstract setPaintMode() void Indica que al dibujar se

borra el fondo. Es el modo de actuacin por defecto. del color de fondo se cambian al color del

abstract setXORMode(Color c1) void Al dibujar los pixels que sean

parmetro y viceversa.
String toString()

Representacin como cadena de caracteres del objeto Graphics.


abstract translate(int x, int y) void Fija un nuevo centro de coordenadas.

6.4 Mostrando imgenes


Para mostrar imgenes que estn en disco en forma .gif o .jpg podemos seguir el procedimiento siguiente:

Tema 5: Desarrollo de aplicaciones grficas


1. Leer la imagen del fichero con el mtodo Toolkit.getDefaultToolkit().getImage(String nombre). En la que el nombre es el nombre del fichero. Este mtodo devuelve un valor de tipo Image, por lo que la instruccin podra ser del estilo: Image img = Toolkit.getDefaultToolkit().getImage("foto.gif"); 2. La clase Image es la que se utiliza para representar imgenes genricas en Java. 3. Utilizar el mtodo showImage de Graphics. Este mtodo esta sobrecargado tal y como vimos en el punto anterior.

Ejemplo: Vamos a mostrar una secuencia de imgenes para producir el efecto de una animacin. Saluda.java
import java.awt.*; import javax.swing.*; public class Saluda extends Canvas Image t[]; // array de imgenes public Saluda() { t = new Image[10]; for } public void paint(Graphics g) { g.drawImage(t[0],0,0, 200,200, Color.white, null); } public void saluda() { Graphics g = getGraphics(); for (int i = 1; i<10; i++) { g.drawImage(t[i],0,0,200,200, Color.white, null); // perdemos un poco de tiempo para que se vea try{ Thread.sleep(150);} catch(Exception e) {} } repaint(); } (int i = 0; i<10; i++) t[i] = Toolkit.getDefaultToolkit().getImage("t"+(i+1)+".gif"); {

Tema 5: Desarrollo de aplicaciones grficas


}

Ventana.java

import java.awt.*; import java.awt.event.*; public class Ventana extends Frame { public Ventana() { // titulo, estilo, tamao y posicin iniciales setTitle("saluda a los seores"); // ventana centrada Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); int ancho=200, alto=250; setSize(ancho, alto); setLocation(d.width/2-ancho/2,d.height/2-alto/2); // el lienzo ir en el centro de la pantalla Saluda lienzo = new Saluda(); add(lienzo); // el botn con su escucha correspondiente Button boton = new Button("saluda!"); Escucha e = new Escucha(lienzo); boton.addActionListener(e); add(boton, BorderLayout.SOUTH); // aadimos el "listener" para cerrar la ventana addWindowListener(new ParaAcabar()); // la mostramos setVisible(true); } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } // escucha del boton class Escucha implements ActionListener { Saluda lienzo;

Tema 5: Desarrollo de aplicaciones grficas


public Escucha(Saluda lienzo) { this.lienzo = lienzo; } public void actionPerformed(ActionEvent e) { lienzo.saluda(); } }

Principal.java
public class Principal { public static void main(String[] args) { new Ventana(); } }

6.5 Un poco de animacin


Vamos a mostrar por medio de un ejemplo un par de tcnicas sencillas que se pueden utilizar para mejorar animaciones de grficos. El ejemplo consiste en una pelota que se mueve rebotando contra las paredes de la ventana. Versin inicial La idea es, como siempre, sobreescribir la clase paint del lienzo para que dibuje un circulo (la pelota), pero de forma que la posicin de la pelota dependa de unas variables x, y, y escribir un mtodo que modifique estas variables y obligue al lienzo a repintarse para simular la animacin. Principal.java

public class Principal { static public void main(String [] args) { new Ventana(); } }

Ventana.java

import java.awt.*; import java.awt.event.*;

Tema 5: Desarrollo de aplicaciones grficas


public class Ventana extends Frame { public Ventana() { // titulo, estilo, tamao y posicin iniciales setTitle("Animacin - V1"); // ventana centrada Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); int ancho=400, alto=250; setSize(ancho, alto); setLocation(d.width/2-ancho/2,d.height/2-alto/2); // el lienzo ir en el centro de la pantalla CorrePelota lienzo = new CorrePelota(); add(lienzo); // aadimos el "listener" para cerrar la ventana addWindowListener(new ParaAcabar()); // la mostramos setVisible(true); // buclew de animacin for (long i=0; i<10000000; i++) { // mover la pelota lienzo.correCorre(); // perder el tiempo try { Thread.sleep(10); } catch(Exception e) {} } } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }

CorrePelota.java
import java.awt.*; public class CorrePelota extends Canvas { private final int radio = 30; int x = 20,y = 20; // pos. inicial int incX = 1, incY = 1; // dir. inicial public CorrePelota() { setBackground(Color.black); setForeground(Color.yellow);

Tema 5: Desarrollo de aplicaciones grficas


} public void correCorre() { // calculamos la nueva posicin de la pelota x += incX; y += incY; // si hay choque invertimos la direccin if (x>370) incX = -((int) (Math.random()*2+1)); if (x<0) incX = (int) (Math.random()*2+1); if (y>190) incY = -((int) (Math.random()*2+1)); if (y<0) incY = (int) (Math.random()*2+1); repaint(); } public void paint(Graphics g) { g.fillOval(x,y,radio,radio); } }

El programa funciona, pero la pelota al moverse tiene un extrao "parpadeo". Vamos a ver como solucionarlo. Yo me lo pinto y yo me lo borro El problema es que antes de pintar el nuevo dibujo debe borrarse el anterior; y de eso se encarga update, que antes de llamar a paint borra el lienzo completo. Como esto tarda en hacerse en ocasiones el refresco de pantalla "pilla" a la animacin justo despus de borrar la figura pero antes de volver a dibujarla y eso provoca el parpadeo. Una solucin es impedir que update() borre la figura anterior y en su lugar hacerlo nosotros, que en lugar de borrar todo el grfico slo borraremos la figura anterior. Para hacer esto slo tenemos que modificar la clase CorrePelota: CorrePelota.java
import java.awt.*; public class CorrePelota extends Canvas { private final int radio = 30; int x = 20,y = 20; // pos. inicial int incX = 1, incY = 1; // dir. inicial int antx, anty; // posicin antigua de la pelota public CorrePelota() { setBackground(Color.black); setForeground(Color.yellow);

Tema 5: Desarrollo de aplicaciones grficas


} public void correCorre() { // guardamos la posicin antigua para borrarla antx = x; anty = y; // calculamos la nueva posicin de la pelota x += incX; y += incY; // si hay choque invertimos la direccin if (x>370) incX = -((int) (Math.random()*2+1)); if (x<0) incX = (int) (Math.random()*2+1); if (y>190) incY = -((int) (Math.random()*2+1)); if (y<0) incY = (int) (Math.random()*2+1); repaint(); } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { // borramos la anterior g.clearRect(antx,anty,radio,radio); g.fillOval(x,y,radio,radio); } }

Aunque el parpadeo disminuye ligeramente sigue existiendo; se tarda demasiado en dibujar el valo. Doble buffer La idea es no dibujar ni borrar directamente en la pantalla, sino en un objeto de tipo Image que nos har de "buffer" o de copia del lienzo. Una vez que hayamos dibujado en el objeto slo tendremos que volcarlo a pantalla con drawImage. As el usuario no podr ver el proceso de borrado y dibujado; slo la figura en la nueva posicin. La nueva versin de la clase CorrePelota es: CorrePelota.java
import java.awt.*; public class CorrePelota extends Canvas { private final int radio = 30; int x = 20,y = 20; // pos. inicial

Tema 5: Desarrollo de aplicaciones grficas


int incX = 1, incY = 1; // dir. inicial int antx, anty; // posicin antigua de la pelota // el doble buffer Image copia; Graphics gCopia; boolean primeraVez = true; public CorrePelota() { setBackground(Color.black); setForeground(Color.yellow); } public void correCorre() { // guardamos la posicin antigua para borrarla antx = x; anty = y; // calculamos la nueva posicin de la pelota x += incX; y += incY; // si hay choque invertimos la direccin if (x>370) incX = -((int) (Math.random()*2+1)); if (x<0) incX = (int) (Math.random()*2+1); if (y>190) incY = -((int) (Math.random()*2+1)); if (y<0) incY = (int) (Math.random()*2+1); repaint(); } public void update(Graphics g) { // para que la pinte paint(g); } public void paint(Graphics g) { if (primeraVez) { copia = createImage(400,250); gCopia = copia.getGraphics(); primeraVez = false; } gCopia.clearRect(antx,anty,radio,radio); gCopia.fillOval(x,y,radio,radio); g.drawImage(copia,0,0,this); } }

Tema 5: Desarrollo de aplicaciones grficas


Observacin: En swing existen mtodos especficos para tratar el doble buffer que permiten mostrar animaciones de mejor calidad.

7.- Applets

7.1 Qu es un Applet? 7.2 Pginas WEB 7.3 Vida (y muerte) de un Applet 7.4 Ejemplo

7.1 Qu es un Applet?
Un applet es un programa Java que se ejecuta dentro de una pgina html. El cdigo (.class) viaja junto con la pgina al ordenador del usuario, donde es ejecutado por la mquina virtual del explorador correspondiente. Observacin: Para que se pueda ver el applet dentro de la pgina hay que tener activada la mquina virtual de Java del explorador Los applets son especialmente utilizados en pginas de tipo cientfico y pedaggicas, para ilustrar conceptos, simular experimentos. Un ejemplo tpico es cuando en nuestra pgina queremos mostrar un grfica que depende de ciertos parmetros introducidos por el usuario.

7.2 Pginas WEB


Pginas html Una pgina WEB es, normalmente un texto escrito en el lenguaje html. La forma ms simple de una pgina en html es

Tema 5: Desarrollo de aplicaciones grficas


pagina.html
<html> <head> <title> Una pgina </title> </head > <body > Esta es una pgina mnima </body> </html>

Podemos escribir este texto en un fichero (por ejemplo con el block de notas), grabarlo y abrirlo con el explorador. En general una pgina html puede contener:

Texto (se incluye el texto sin ms) Imgenes (Ej.: <img src="dibu.jpg"> para incluir dibu.jpg en la pgina ) Enlaces a otras pginas (Ej.: Si incluimos <a href="http://www.ucm.es">ucm</a> aparecer la palabra ucm y al pulsar sobre ella se saltar a la pgina de la universidad complutense).

Sin embargo no puede incluir acciones dinmicas, como por ejemplo pedir datos al usuario, procesarlos y mostrar el resultado, o mostrar una animacin Incluyendo Java en pginas WEB La llamada al cdigo java se introduce mediante el delimitador html applet
<html> <head> <title> Un mini-applet </title> </head > <body > Aqu incluimos una llamada al applet: <p> <applet code=Mini.class" width=150 Height=25></applet> <p> Y luego seguimos con el texto de la pgina </body> </html>

Tema 5: Desarrollo de aplicaciones grficas


El resultado es:

Importante: El cdigo java compilado (Mini.class en el ejemplo) debe encontrarse en la misma carpeta que la pgina html.

7.3 Vida (y muerte) de un Applet


Para escribir un applet debemos escribir una clase que herede de la clase Applet (import java.applet.*). Hay 4 mtodos en esta clase que nos interesan: 1. init(): Inicializa el applet. Es en esta funcin (y no en la constructora) donde debemos crear todos los componentes del applet e insertarlos. 2. start(): se llama una vez creado el applet, para que comience la ejecucin. Por ejemplo en una animacin sera start quien comenzara el movimiento. En este punto conviene ser cuidadosos: si start entra en un bucle sin fin puede dejar "colgada" la pgina. para solucionar esto se utilizan hebras (Threads) que se ejecutan de forma concurrente sin bloquear la pgina. 3. stop(): Se ha detenido el applet. Se puede volver a iniciar con start(). 4. destroy(): Limpieza final y eliminacin del applet.

Tema 5: Desarrollo de aplicaciones grficas

7.4 Ejemplo
El siguiente ejemplo mueve un dibujo ''cab.gif'' por la pantalla. Usa hebras (que no han sido explicadas en clase: interfaz Runnable y funcin run()).

import java.awt.*; import java.awt.event.*; import java.applet.*; public class Imagen extends Applet implements Runnable{ Image coche; int x=600,y=20; Thread corre = new Thread(this); //Inicializar el applet public void init() { MediaTracker tracker = new MediaTracker(this); coche = getImage(getCodeBase(),"cab.gif"); tracker.addImage(coche, 1); try { tracker.waitForAll();} catch(Exception e) {e.printStackTrace();} this.setBackground(Color.white); } public void run() { try { Thread.sleep(1000);

Tema 5: Desarrollo de aplicaciones grficas


} catch (Exception e) {;} while (true) { repaint(); try { Thread.sleep(40); } catch (Exception e) {;} } } public void start() { corre.start(); } public void paint(Graphics g) { update(g); } public void update(Graphics g) { x--; g.drawImage(coche,x,y,70,50,Color.white,this); if (x==-70) x = 600; // volvemos a empezar } }

8.- Dilogos y Mensajes


8.1 La clase Dialog 8.2 La clase FileDialog 8.3 La clase JOptionPane

8.1 La clase Dialog


Los dilogos son ventanas "hijas" de la ventana principal que se utilizan normalmente para mostrar informacin, errores, o pedir confirmacin. El ejemplo ms habitual es la ventana con el mensaje "Desea salir de la aplicacin?" con los botones de aceptar y cancelar. Hay dos tipos de dilogos:

Dilogos modales: No se puede actuar sobre la aplicacin hasta que no se haya cerrado el dilogo. Son los ms comunes. Dilogos no modales: No necesitan cerrarse para seguir trabajando sobre la aplicacin.

Dado que los dilogos son un tipo especial de ventanas, no tenemos que describir sus mtodos, tan slo sus constructoras: Constructoras

Tema 5: Desarrollo de aplicaciones grficas

Dialog(Frame prop): Crea un dilogo no visible (hasta que se haga setVisible(true)), no modal y con ttulo vaco. prop es el nombre del dilogo o la ventana propietaria. Si se desea se puede poner null para indicar que no tiene ventana "madre". Dialog(Frame prop, String titulo): Anlogo al anterior pero indicando el ttulo. Dialog(Frame prop, String titulo, boolean modal): Si modal es true crea una ventana modal.

8.2 La clase FileDialog


Es un caso especial de dilogo modal orientado a la seleccin de ficheros (a menudo asociados a opciones del estilo de "Abrir" o "Guardar como"). Hay que tener en cuenta que el dilogo slo selecciona nombres de ficheros; no abre ni guarda nada. Constructoras La constructora ms completa tiene la sintaxis: FileDialog(Frame vent, String msg, int mode)

Donde vent es la ventana madre, msg es el ttulo del cuadro de dilogo y mode debe ser o bien FileDialog.LOAD si el dilogo se utiliza para abrir un fichero o FileDialog.SAVE si se utiliza para grabar un fichero. Mtodos

String getDirectory(): Cadena con el directorio que contiene el fichero seleccionado. String getFile(): Cadena con el nombre del fichero seleccionado. FilenameFilter getFilenameFilter(): Filtro utilizado en la seleccin. int getMode(): Devuelve el modo: FileDialog.LOAD o FileDialog.SAVE. void setDirectory(String dir) : Establece el directorio inicial que se mostrar al abrir el dilogo. void setFile(String nombreFich): Nombre por defecto del fichero; se usa habitualmente en los dilogos de guardar. void setFilenameFilter(FilenameFilter f): Filtro que se utilizar para mostrar los archivos en el cuadro de dilogo. void setMode(int modo): Pone el modo a FileDialog.LOAD o FileDialog.SAVE.

Adems de estos mtodos es interesante conocer la constante File.separator que indica el separador de directorios (la barra inclinada hacia la derecha o la izquierda dependiendo del sistema operativo). El siguiente ejemplo ilustra como se puede utilizar este dilogo para abrir un fichero:
import java.awt.*; import java.awt.event.*; public class Ventana extends Frame {

Tema 5: Desarrollo de aplicaciones grficas


public Ventana() { setTitle("Entrada de datos"); setLayout(new FlowLayout()); setSize(300,100); setLocation(300,200); Label etiqInfo = new Label("Fichero seleccionado: "); Label etiqSel = new Label(); add(etiqInfo); add(etiqSel); // aadimos el "listener" para cerrar la ventana addWindowListener(new ParaAcabar()); // la mostramos setVisible(true); // creamos un dialogo para abrir un fichero FileDialog fd = new FileDialog(this, "Abrir...",FileDialog.LOAD); // al abrir el dialogo, como es modal, la aplicacin queda // bloqueada fd.setVisible(true); String fname = fd.getFile(); // si el usuario ha cancelado el dialogo se devuelve null if (fname != null) { String fdir = fd.getDirectory(); String name = fdir + fname; // mostramos el nombre elegido en la ventana etiqSel.setText(name); } // if } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }

8.3 La clase JOptionPane


Los dilogos ms comunes son los dilogos modales que se utilizan para presentar informacin, o bien informar de un error, y que incluyen un botn Aceptar o bien botones Aceptar y Cancelar. Por eso en swing se incluyo una clase especial para representar este tipo de dilogos, la clase JOptionPane, que resulta muy til a la hora de presentar informacin debido a su sencillez.

Tema 5: Desarrollo de aplicaciones grficas


Observacin: Es posible (y bastante normal) mezclar en una misma aplicacin componentes awt con componentes swing. Los principales mtodos de esta clase son cuatro mtodos estticos:

showConfirmDialog: Dilogo para pedir confirmacin, como los tpicos dilogos con los botones si/no/cancelar. showInputDialog: Para pedir una entrada de datos al usuario. showMessageDialog: Informacin para el usuario, con un botn de aceptar. showOptionDialog: Combina las posibilidades de los tres anteriores.

Tambin hay 5 constantes que pueden utilizarse para indicar el tipo de mensaje que se est mostrando. La seleccin de la constante adecuada influir en el icono que se presentar en la ventana modal:

ERROR_MESSAGE INFORMATION_MESSAGE WARNING_MESSAGE QUESTION_MESSAGE PLAIN_MESSAGE

Por ltimo, aunque podemos incluir en el dilogo los botones que deseemos, hay 4 constantes que definen los conjuntos de botones ms usuales: DEFAULT_OPTION YES_NO_OPTION YES_NO_CANCEL_OPTION OK_CANCEL_OPTION El primero muestra slo un botn de aceptar (el significado del resto es obvio a partir del nombre). Vamos a ver algunos ejemplos en el siguiente programa:
import java.awt.*; import java.awt.event.*; import javax.swing.*; // para JOptionPane public class Ventana extends Frame { public Ventana() { setTitle("Entrada de datos"); setLayout(new FlowLayout()); setSize(200,100); setLocation(300,200); // el primer argumento es la ventana madre, // el segundo el mensaje a mostrar, el tercero el titulo // de la ventana y el cuarto el tipo de dialogo JOptionPane.showMessageDialog(this, "El fichero se ha grabado correctamente", "informacion", JOptionPane.INFORMATION_MESSAGE); // muestra el dialogo con un simbolo de interrogacion if (JOptionPane.showConfirmDialog(null, "desea salir de la aplicacion?", "aviso", JOptionPane.YES_NO_OPTION) == 0)

Tema 5: Desarrollo de aplicaciones grficas


System.exit(0); // igual pero con un simbolo de informacion JOptionPane.showConfirmDialog(this, "Desea continuar?", "informacion", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE); // para pedir un dato String nombre = JOptionPane.showInputDialog("Su nombre:"); // elegir un dato de una lista Object[] valores = { "Norte","Sur", "Este","Oeste" }; Object selectedValue = JOptionPane.showInputDialog( null, // ventana madre "Elige una direccion", // mensaje "Direcciones", // titulo JOptionPane.INFORMATION_MESSAGE, // tipo mensaje null, // icono valores, // valores valores[0] // valor marcado inicialmente ); // aadimos el "listener" para cerrar la ventana addWindowListener(new ParaAcabar()); } } // clase para cerrar la ventana class ParaAcabar extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }

Este programa muestra las siguientes ventanas de dilogo (consecutivamente, cada una tras cerrar la anterior):

Tema 5: Desarrollo de aplicaciones grficas

Tema 5: Desarrollo de aplicaciones grficas Swing


1 Introduccin 2 Ventanas Swing 3 Ejemplo

1 Introduccin
En este apartado vamos a ver muy sucintamente el paquete Swing, que como ya dijimos es la alternativa a AWT. La mayor parte de los conceptos vistos para AWT (componentes, contenedores, etc) son vlidos tambin para Swing. Y casi todas las clases vistas en AWT tienen su componente correspondiente en Swing: a la clase Button le corresponde JButton, a Frame JFrame, a Applet JApplet, etc, etc. Sin embargo Swing incluye otros componentes que no existen en AWT, como por ejemplo JTree para representar estructuras tipo rbol. Estos componentes, ms potentes y complejos, precisan de un estudio muy detallado, al que no nos vamos a dedicar aqu. Adems, Swing incluye conceptos nuevos, como la definicin de la apariencia genrica de las ventanas y componentes segn distintos estilos (el llamado Look and Feel ). A menudo los libros y tutoriales se refieren a todas las clases relacionadas con la creacin de aplicaciones grficas basadas en Swing como JFC o Java Foundation Class.

2 Ventanas Swing: JFrame


Las ventanas JFrame tienen dos diferencias fundamentales con su correspondiente en AWT, Frame : La ventana se cierra sin necesidad de incluir ninguna escucha (Bien!!!). Si adems se quiere que al cerrar la ventana se abandone la aplicacin basta con hacer
setDefaultCloseOperation(EXIT_ON_CLOSE);

Los componentes bsicos no se aaden directamente a la ventana, sino a un panel que siempre existe asociado a la ventana y que se obtiene mediante el mtodo getContentPane(). Veamos estas diferencias por medio de un ejemplo:
// Crear la ventana JFrame ventana = new JFrame("Ventana Swing"); ventana.setDefaultCloseOperation(EXIT_ON_CLOSE); // Creamos un componente; aqu hay polimorfismo... JComponent comp = new JTextArea(); // un rea de texto // Aadir el componente al panel de la ventana ventana.getContentPane().add(comp, BorderLayout.CENTER);

Tema 5: Desarrollo de aplicaciones grficas Swing


// mostrar la ventana; igual que en AWT ventana.setSize(300, 300); ventana.setVisible(true);

3 Ejemplo
El siguiente programa pide un nmero n y realiza la suma de todos los enteros consecutivos desde 1 hasta n. Para mostrar la evolucin del proceso se va actualizando una barra de progreso. Una curiosidad de este cdigo es que las clases privadas se incluyen dentro de la clase de la ventana, antes de su ltima llave '}', como si fueran mtodos o atributos. Esto es habitual en Java (no importa si estamos usando Swing o AWT). La ventaja es que las clases as incluidas tienen acceso a los atributos de la clase ventana, al ser parte de la propia clase. Obsrvese igualmente que el modelo de eventos es el mismo de AWT.
VentanaProgreso.java

import import import import

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

public class VentanaProgreso extends JFrame { private Container panelPrincipal = null; private JButton botonEmpezar, botonParar; private JTextField campoEntrada, campoResultado; private ProgressMonitor pMonitor = null; private Timer reloj = null; private int suma,contador; public VentanaProgreso() { suma = contador = 0; setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(400,100); // 1. Aadimos un grid layout al panel principal panelPrincipal = this.getContentPane(); panelPrincipal.setLayout(new GridLayout(2,1)); // 2. aadimos una caja horizontal al gridlayout Box caja = Box.createHorizontalBox(); panelPrincipal.add(caja); // 3. Rellenamos la caja horizontal caja.add(Box.createHorizontalGlue()); JLabel etiq1 = new JLabel("Suma del 1 al ", JLabel.LEFT);

Tema 5: Desarrollo de aplicaciones grficas Swing


etiq1.setFont(new Font("Dialog", Font.PLAIN, 15)); caja.add(etiq1); campoEntrada = new JTextField("100", 4); caja.add(campoEntrada); JLabel etiq2 = new JLabel(" Resultado: ", JLabel.LEFT); etiq2.setFont(new Font("Dialog", Font.PLAIN, 15)); caja.add(etiq2); campoResultado = new JTextField(10); caja.add(campoResultado); caja.add(Box.createHorizontalGlue()); // 4. Otra caja horizontal Box caja2 = Box.createHorizontalBox(); panelPrincipal.add(caja2); // 5. Botones de empezar y acabar botonEmpezar = new JButton("Empezar"); botonEmpezar.addActionListener(new EscuchaBoton()); caja2.add(Box.createHorizontalGlue()); caja2.add(botonEmpezar); caja2.add(Box.createHorizontalGlue()); // botn para parar la suma botonParar = new JButton("Parar"); botonParar.addActionListener(new EscuchaBoton()); caja2.add(Box.createHorizontalGlue()); caja2.add(botonParar); caja2.add(Box.createHorizontalGlue()); // 6. creamos un reloj // el primer parmetros es el nm. de milisegundos // que pasa entre cada llamada a la escucha // 10 significa llamar constantemente reloj = new Timer(10, new EscuchaReloj()); } // 7. Aqu se hace todo class EscuchaReloj implements ActionListener { public void actionPerformed(ActionEvent e) { if (Integer.parseInt(campoEntrada.getText())> 0){ contador++; suma += contador; pMonitor.setProgress(contador); pMonitor.setNote("Sumando " + contador); campoResultado.setText(Integer.toString(suma)); } else { campoResultado.setText("0");

Tema 5: Desarrollo de aplicaciones grficas Swing


} if (contador >= Integer.parseInt(campoEntrada.getText())){ reloj.stop(); botonEmpezar.setEnabled(true); } } } // 8. Escucha de los botones class EscuchaBoton implements ActionListener { public void actionPerformed(ActionEvent e) { JButton button = (JButton) e.getSource(); if (button.getText() == "Empezar") { botonEmpezar.setEnabled(false); //9. Crear una barra de progreso pMonitor = new ProgressMonitor(panelPrincipal, "suma en progreso...", "Nota", 0, 100); // tiempo que pasa hasta que se muestra en ms // si no se pone no aparece la barra de progreso pMonitor.setMillisToPopup( 0 ); campoResultado.setText(""); if (campoEntrada.getText() != " ") { // tamao de la barra pMonitor.setMaximum(Integer.parseInt( campoEntrada.getText())); suma = contador = 0; // empezar a utilizar el reloj reloj.start(); } } else if (button.getText() == "Parar") { botonEmpezar.setEnabled(true); // paramos el reloj y cerramos el monitor reloj.stop(); pMonitor.close(); campoResultado.setText(""); suma = contador = 0; } } } }

Conviene recordar que para que esta clase pueda ser utilizada hacer falta escribir otra clase, la principal que se encargue de ''arrancarla'':
PruebaJFC.java

Tema 5: Desarrollo de aplicaciones grficas Swing


public class PruebaJFC { public static void main(String[] args) { VentanaProgreso ventana = new VentanaProgreso(); ventana.setVisible(true); } }

El resultado es:

El componente Reloj (de tipo Timer) es el que se encarga de ir actualizando la barra de progreso pMonitor (de tipo ProgressMonitor). Su escucha se llama automticamente por Java, aunque el usuario no haga nada, a intervalos constantes de tiempo. El nmero de milisegundos entre el fin de una llamada y la siguiente llamada se fija en la constructora. En este ejemplo hemos puesto el valor 10.

Das könnte Ihnen auch gefallen