0% encontró este documento útil (0 votos)
6 vistas140 páginas

Curso - Java

El documento presenta un curso sobre Java Standard Edition J2SE, elaborado por docentes del Instituto Universitario de Tecnología 'Dr. Federico Rivero Palacio'. Se abordan temas fundamentales del lenguaje Java, sus características, y su comparación con C/C++, además de detallar la plataforma Java y sus herramientas de desarrollo. El curso tiene como objetivo enseñar a los estudiantes los principios básicos de programación en Java y su aplicación en el desarrollo de software.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
6 vistas140 páginas

Curso - Java

El documento presenta un curso sobre Java Standard Edition J2SE, elaborado por docentes del Instituto Universitario de Tecnología 'Dr. Federico Rivero Palacio'. Se abordan temas fundamentales del lenguaje Java, sus características, y su comparación con C/C++, además de detallar la plataforma Java y sus herramientas de desarrollo. El curso tiene como objetivo enseñar a los estudiantes los principios básicos de programación en Java y su aplicación en el desarrollo de software.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

INSTITUTO UNIVERSITARIO DE TECNOLOGÍA

“DR. FEDERICO RIVERO PALACIO”


DEPARTAMENTO DE INFORMÁTICA
“Dr. Federico Rivero Palacio”

CURSO

Java STANDARD EDITION J2SE

Caracas, 2006

Curso de Java Standard Edition – J2SE 1


Java Standad Edition J2SE

Elaborado por:
- Prof. Castañeda, Marbella
- Prof. Hidalgo, Erika
- Prof. Ramos, Darwin
- Prof. Rivas, Ronel

Docentes del Departamento de Informática del Instituto Universitario de Tecnología

“Dr. Federico Rivero Palacio”.

Caracas, 2005

Curso de Java Standard Edition – J2SE 2


CONTENIDO DEL CURSO

Tema I. Fundamentos de Java

Tema II. Clases, objetos y paquetes

Tema III. Herencia, clases abstractas e interfaces

Tema IV. Excepciones

Tema V. Entrada/Salida

Tema VI. Tecnologías de acceso a datos

Tema VII. Interfaces Gráficas

Apéndice 1. Herramientas y Utilidades de Desarrollo

Curso de Java Standard Edition – J2SE 3


..
..
..
..
.
T E M A I: F u n d a m e n t o s d e J a v a

OBJETIVOS:

ƒ Describir la Plataforma Java y las características del lenguaje de programación Java.

ƒ Realizar la declaración e inicialización de variables simples u objetos en Java.

ƒ Describir el funcionamiento de los operadores y estructuras de control en Java.

CONTENIDO:

ƒ Orígenes del Lenguaje

ƒ El lenguaje de programación Java

ƒ Características del Lenguaje

ƒ Java vs C/C++

ƒ La plataforma Java

ƒ Los tipos de datos de Java

ƒ Identificadores

ƒ Operadores de Java

ƒ Estructuras de Control

............................
4
Curso de Java Standard Edition – J2SE 4
1. ORÍGENES DEL LENGUAJE

La creación y desarrollo de los lenguajes de programación se rige por dos factores básicos: el
perfeccionamiento del arte de programar y agregar cambios al ámbito de la computación.

El lenguaje de programación Java no es una excepción, ya que se genera partiendo del extenso
legado de C y C++, y agrega refinamiento y características que reflejan el estado actual de la
programación. Este lenguaje fue concebido por James Gosling, Patrick Naughton, Chris Warth, Ed
Frank y Mike Sheridan para Sun Microsystems, en 1991. Se le llamó inicialmente “Oak” pero después
en 1995, se renombró como Java.

La razón más importante para la creación de este lenguaje era la necesidad de crear un lenguaje
independiente de la plataforma y que se pudiera usar para crear software incorporable en
dispositivos electrónicos, como televisores, hornos microondas, neveras, etc. En la búsqueda de
una solución, se trabajó en un lenguaje portátil de plataforma cruzada que generase códigos que se
pudiesen ejecutar en distintos CPU para diversos ambientes.

Como se puede observar la motivación inicial de Java no era la Internet, pero a pesar de esto, el
mismo está fuertemente ligado a la red, ya que mientras se elaboraban los detalles de Java,
apareció un factor que jugaría un papel crucial en el futuro de este lenguaje: La World Wide Web. El
equipo de desarrolladores de Java observó que este nuevo entorno presentaba los mismos
requerimientos que ellos perseguían cubrir con Java: programas de código pequeño, confiable,
seguro e independiente de la plataforma. Si el mundo Web no hubiese tomado forma a la vez
que se estaba implementado Java, Java podría haber sido un lenguaje útil pero dedicado a la
programación de dispositivos electrónicos para el consumo.

2. EL LENGUAJE DE PROGRAMACIÓN JAVA

Java es en esencia un lenguaje de programación orientado a objetos. Sin embargo, Java no es solo
un lenguaje de programación, sino que también define una plataforma en la que las aplicaciones
pueden ser desarrolladas y ejecutadas.

La mayoría de las características básicas de Java provienen de C y C++. Esto se hizo


intencionalmente, a fin de hacer atractivo al lenguaje para el gran número de programadores de C y
C++. Java provee un ambiente de programación poderoso y lógicamente consistente, que contiene
los mejores elementos del pasado y le agrega nuevas características necesarias para ambientes en
línea. Uno de los aspectos centrales de la filosofía del diseño en C, C++ y Java, es que el
programador ejerce el control; excepto por las restricciones que impone el ambiente Internet.

El diseño de Java es tal que, es multiplataforma en código fuente y la forma binaria compilada. Esto
es posible, ya que Java compila su código fuente en un bytecode intermedio e independiente de la
plataforma. Este bytecode es interpretado usando un intérprete específico de la plataforma, es decir
la Máquina Virtual de Java (Java Virtual Machine – JVM) en tiempo de ejecución del programa.

El lenguaje de programación Java permite desarrollar básicamente dos tipos de programas:


aplicaciones y applets. Una aplicación es un programa autónomo que puede ejecutarse en una
computadora, bajo el sistema operativo de esa computadora. Un applet es un pequeño programa
Java que puede se embebido en una página HTML. Aunque, se pueden desarrollar programas de
consola, esta no es su orientación.

Curso de Java Standard Edition – J2SE 5


3. CARACTERÍSTICAS DEL LENGUAJE

A continuación se presentan las principales características que han convertido a Java en un lenguaje
sumamente popular.

- Simple: Java es bastante fácil de aprender, dado que tiene la sintaxis de C/C++. Es muy fácil
que un programador experimentado la domine, ya que solo se necesita una comprensión
apropiada de los conceptos de programación orientada a objetos. Además de su similitud con
C/C++, Java tiene otra característica que lo hace simple, y es que Java hace un esfuerzo por no
tener características sorprendentes. En Java hay un número reducido de formas claras para
abordar una tarea dada.

- Orientado a Objetos: Java no se creó para ser compatible en código fuente con otros
lenguajes. Esto otorgó a los desarrolladores de Java la libertad de diseñar un lenguaje partiendo
de cero. El resultado de esto fue una aproximación limpia, útil y pragmática a los objetos, en un
lenguaje puramente orientado a objetos. El modelo de objetos Java es simple y fácil de ampliar,
mientras los tipos simples permanecen como “no objetos” de alto rendimiento.

- Portable: Java, usa un conjunto optimizado de instrucciones, diseñado para ser ejecutado por
una Máquina Virtual, que es emulada por el sistema en tiempo de ejecución de Java. Este
conjunto de instrucciones se conoce como BYTECODE, que representa la salida de un compilador
de Java. Esto significa que el sistema de tiempo de ejecución de Java es un Intérprete de
BYTECODE. Debido a esto, sólo el sistema de tiempo de ejecución de Java tiene que ser
implementado para cada plataforma, y una vez que este paquete existe para un sistema,
cualquier programa Java puede correr en él.

- Interpretado y de Alto Rendimiento: Java fue diseñado para ser un lenguaje interpretado, a
fin de solucionar los aspectos relacionados con la descarga a través de la Internet. Ejecutar
programas de Java en diferentes entornos es una tarea simple debido a que estos programas
(BYTECODE) son Interpretados por una Máquina Virtual Java. A pesar de que el BYTECODE de Java
es interpretado, está diseñado de tal forma que fácil de traducir a código máquina nativo para
alto rendimiento.

- Seguro: Una de las principales características de Java, es que la ejecución de un programa Java
está limitada al entorno de ejecución Java, por lo que no se proporciona acceso a partes
restringidas del computador. Esto lo garantiza la característica de ser un lenguaje interpretado,
ya que el sistema de tiempo de ejecución puede contener un programa y evitar que produzca
efectos colaterales fuera del sistema, obedeciendo al hecho que la Máquina Virtual controla la
ejecución de cada programa Java.

- Robusto: Siendo un lenguaje estrictamente tipificado, Java verifica el código del programador
en tiempo de compilación, y además en tiempo de ejecución. Java da una alta prioridad a la
capacidad de generar programas confiables, a fin de enfrentar las extraordinarias demandas
provenientes del entorno multiplataforma de Internet.

- Multihilo: Java fue diseñado para cumplir el requisito del mundo real de crear programas env
red interactivos. Para conseguir esto, Java proporciona la programación multihilo, que permite
escribir programas que realicen varias cosas a la vez. El intérprete Java permite la sincronización
de multiprocesos, que permite la construcción de programas interactivos, que se ejecuten
eficientemente.

Curso de Java Standard Edition – J2SE 6


- Distribuido: Java fue diseñado para el entorno distribuido de Internet, por lo que trabaja con
el protocolo TCP/IP. Java incorpora capacidades para el envío de mensajes que hacía posible
que los objetos en computadoras separadas ejecutaran procedimientos en forma remota. Esta
característica le proporciona una abstracción única para la programación Cliente-Servidor.

- Dinámico: En Java el código puede ser enlazado dinámicamente en forma segura. Esto es
posible por las grandes cantidades de data en tiempo de ejecución que procesan los programas
de Java, que es usada para la verificación y resolución de accesos a objetos en tiempo de
ejecución. Esta característica es importante para la robustez del entorno de applets, y hace
posible actualizar dinámicamente pequeños bits del BYTECODE en un sistema en plena ejecución.

4. JAVA vs C/C++

Comparado con C++, Java es considerado un lenguaje puramente orientado a objetos, debido a que
los programas Java requieren necesariamente el uso de objetos y no como en C++, en donde se
pueden escribir programas híbridos. En Java no existen funciones ni variables globales; todas las
interfaces con data de objetos deben ser definidas en las bibliotecas de clases.

Java es robusto considerando sus técnicas de administración de memoria, ya que administra la


asignación y liberación de memoria de forma automática. A diferencia de C/C++ en donde el
programador debe asignar y liberar manualmente la memoria dinámica.

Los desarrolladores de Java añadieron la característica de la recolección automática de basura. En


C/C++ una fuente complejidad en muchas aplicaciones es la administración de almacenamiento,
que significa asignación y liberación de memoria. La recolección de basura que efectivamente
significa liberación periódica de memoria que no está siendo referenciada, asegura que Java no solo
facilita la programación, sino ayuda a reducir drásticamente los errores en tiempo de ejecución.

Java omite muchas características de difícil comprensión de C++. Estas características omitidas
consisten principalmente en la sobrecarga de operadores, la herencia múltiple y las conversiones
automáticas extensivas.

La mayor diferencia entre Java y C/C++, es la característica de Java de ser Multiplataforma. En


C/C++ es imposible ejecutar el mismo archivo objeto en diversas plataformas. El diseño de Java es
tal que es multiplataforma tanto el código fuente como el código binario.

5. LA PLATAFORMA JAVA

Una plataforma se define como el entorno de hardware y/o software sobre el cual se ejecutan los
programas. La plataforma Java es una plataforma de sólo software, que se ejecuta sobre cualquier
otra plataforma basada en hardware. Java posee tres grandes plataformas: la J2SE (Java 2 Platform
Standard Edition), la J2EE (Java 2 Platform Enterprise Edition) y la J2ME (Java 2 Platform Micro
Edition).

La Java 2 Platform Standard Edition – J2SE (Plataforma Java 2 Edición Estándar) es un


conjunto de especificaciones que describen el ambiente de desarrollo de aplicaciones Java. Está será
la plataforma a estudiar en este curso.

Curso de Java Standard Edition – J2SE 7


En la siguiente gráfica se describe la plataforma J2SE:

HERRAMIENTAS/UTILIDADES DE DESARROLLO

Básicas RMI Internacionalización

Seguridad IDL y RMI-IIOP Plug-in

JAVA RUNTIME ENVIRONMENT - JRE

TECNOLOGÍAS DE DESPLIEGUE

J2SDK Java Web Start Java Plug-in

API

Interfaces de
Núcleo Integración
Usuario

MÁQUINA VIRTUAL DE JAVA

Java HotSpot Java HotSpot


Componentes Client VM Server VM

Componentes a utilizar

Plataformas
SOLARIS LINUX WINDOWS OTRO

Gráfico 1. Plataforma Java 2 Edición Estándar

El J2SDK (Equipo Estándar de Desarrollo - SDK), es un ambiente de desarrollo para construir


aplicaciones, applets, y componentes usando el lenguaje de programación Java. El Java 2 SDK,
incluye un conjunto de herramientas y utilidades de desarrollo así como también el ambiente de
ejecución Java.

5.1. HERRAMIENTAS Y UTILIDADES DE DESARROLLO

Es un conjunto de herramientas para desarrollar y probar programas escritos en el lenguaje Java y


ejecutarlos en la plataforma Java. Están diseñadas para ser usadas desde la línea de comandos.
Generalmente se agrupan en las siguientes categorías:

- Básicas: herramientas fundamentales del SDK que se usan para crear y construir
aplicaciones. Algunas de las herramientas básicas que usaremos en este curso se describen
a continuación:

Curso de Java Standard Edition – J2SE 8


HERRAMIENTA COMANDO FUNCIÓN
Compilador Genera el código binario de uno o
javac [Link]
(javac) varios programas Java.

Depurador Permite verificar la semántica de la


jdb myProg
(jdb) aplicación.

Lanzador de Invoca a la Máquina Virtual de Java


java myProg
aplicación (java) para que ejecute la aplicación.
Evalúa la declaración y los comentarios
Documentador de un conjunto de programas y
javadoc [Link] produce un conjunto de páginas HTML
(javadoc) que describen las clases, interfaces,
constructores, atributos y métodos.

- RMI: herramientas que te permiten crear aplicaciones que interactúan entre redes, tales
como la Web.

- Internacionalización: herramientas que te permiten crear aplicaciones que puedan ser


adaptadas a cualquier idioma y región. El estudio de estas herramientas esta fuera del
alcance de este curso.

- Seguridad: herramientas que te permiten establecer políticas de seguridad en tu sistema


operativo y crear aplicaciones que puedan trabajar dentro del alcance de estas políticas y
permitir, de forma segura, el acceso a tu aplicación desde sitios remotos. El estudio de estas
herramientas esta fuera del alcance de este curso.

- IDL y RMI-IIOP: herramientas utilizadas para crear aplicaciones que usen el estándar
OMG IDL y CORBA/IIOP.

- Java Plug-in: utilidades para usar en conjunto con el Java Plug-in.

5.2. EL AMBIENTE EN TIEMPO DE EJECUCIÓN DE JAVA – JRE

El Java 2 Runtime Environment (Ambiente de Ejecución de Java - JRE), permite ejecutar


aplicaciones escritas en Java. Contiene la Máquina Virtual de Java, las clases comprendidas en la API
de Java y las tecnologías de despliegue.

- La Máquina Virtual de Java - JVM: La Java Virtual Machine es una computadora


abstracta implementada sobre una plataforma particular que interpreta el código binario o
BYTECODE y lo ejecuta en esa plataforma, limitando el acceso a otras partes del sistema. La
JVM (JVM) se compone de las siguientes partes:
o Java HotSpot Client VM: diseñado para ejecutar las aplicaciones en un ambiente de
Cliente, reduciendo el tiempo de carga de una aplicación y la paginación de
memoria.
o Java HotSpot Server VM: diseñado para obtener las máximas velocidades de
ejecución en un ambiente de Servidor.

- La Interfaz de Programación de Aplicaciones – API: La Interfaz de Programación de


Aplicaciones Java (API), es una conjunto de partes de software (clases e interfaces)
organizada, coherente y consistente en paquetes. Estas clases, suelen agruparse de acuerdo
al servicio que prestan:

Curso de Java Standard Edition – J2SE 9


o Núcleo (proveen el conjunto de paquetes esenciales para crear aplicaciones Java,
tales como: fundamentos del lenguaje, utilidades del lenguaje, procesos de E/S,
comunicación de redes, preferencias, colecciones, JNI, seguridad, XML, cifrado y
componentes).
o Integración (proveen el conjunto de paquetes que te permiten crear aplicaciones
que puedan invocar métodos/procedimientos remotos, comunicarse con bases de
datos y crear servicios de nombres y directorios).
o Interfaces de Usuario: proveen el conjunto de paquetes para la creación de
aplicaciones con amigables interfaces graficas de usuario (AWT y Swing).

- Tecnologías de despliegue: están representadas por la “Java Web Start” y el “Java


Plugin”, que son tecnologías que permiten ejecutar aplicaciones Java desde Internet.

6. LOS TIPOS DE DATOS DE JAVA

En la base de cualquier lenguaje de programación están sus tipos de datos y operadores, y java no
es la excepción. Los tipos de datos son importantes en Java, porque este es un lenguaje
fuertemente “tipeado”. Esto significa que todas las expresiones tienen algún tipo cuya
compatibilidad es verificada por el compilador.

Java contiene dos categorías generales de tipos de datos incorporados: el orientado a objetos y el
no orientado a objetos. Los tipos de Java orientado a objetos son definidos por clases y los no
orientados a objetos, son los que nosotros llamamos tipos de datos simples.

- Tipos de datos simples: Estos tipos de datos son también llamado elementales o
primitivos y a partir de éstos, pueden ser construidos otros tipos de datos. Java especifica
un rango estricto y un comportamiento para cada tipo simple, que deben soportar las
implementaciones de la Máquina Virtual de Java. Por ejemplo, una variable de tipo “int” es
igual en todos los entornos de ejecución. Esto permite que los programas sean
transportables. Los tipos simples permitidos en Java son:

VALOR
TIPO SIGNIFICADO # BITS RANGO
INICIAL
boolean Representa valores true/false 16 true / false false
char Carácter (Unicode) 16 0 a 65.536 ‘\u0000’
float Real de simple precisión 32 1,7e-308 a 1,7e+308 0.0f
double Real de doble precisión 64 3,4e-38 a 3,4e+38 0.0
byte Enteros de 8 bits 8 -128 a 127 0
short Entero corto 16 -32.768 a 32.767 0
int Entero 32 -[Link] a [Link] 0
long -[Link].854.775.808
Entero largo 64 [Link].854.775.807
0L

o Conversiones implícitas de tipos: En la programación es común asignar un tipo


de variable a otro. Por ejemplo se pudiese querer asignar un valor int a una variable
float.
int i; float f;
i = 10; f = i;

Cuando se mezclan tipos compatibles en una asignación, el valor del lado derecho
es automáticamente convertido al tipo del lado izquierdo. De modo que en el
ejemplo anterior, el valor de i es convertido en float y luego asignado a f. Sin

Curso de Java Standard Edition – J2SE 10


embargo, no todos los tipos son compatibles, por lo que no todas las conversiones
son compatibles. Por ejemplo, boolean e int no son compatibles.

En resumen, cuando un tipo de datos se destina a otro tipo de variables, se realiza


una conversión de tipo automática, si se cumplen dos condiciones:
1. Los dos tipos son compatibles.
2. El tipo destino es más grande que el tipo de origen.

Cuando se cumplen estas dos condiciones, tiene lugar una conversión implícita. Por
ejemplo, el tipo int siempre es suficientemente grande como para almacenar todos
los valores byte. Un long a double es una conversión implícita que es
automáticamente desarrollada. No hay conversión implícita de los tipos numéricos a
char o boolean. Tampoco char y boolean son compatibles entre si. Sin embargo, un
literal entero puede ser asignado a char.

BYTE SHORT INT LONG FLOAT DOUBLE


1byte 2bytes 4bytes 8bytes 4bytes 8bytes

- Tipos de datos orientados a objetos: Estos tipos de datos son clases construidas a
partir de los tipos de datos simples. Java especifica un conjunto de clases que permiten
realizar programas Java 100% orientados a objetos, y esto es lo que hace a los programas
transportables. Los tipos orientados a objetos proporcionados en Java, se encuentran
almacenados en paquete [Link], y éstos son:

o Object: Object es la superclase de todas las demás clases, representa la clase más
arriba en la jerarquía de todos los objetos en Java. Algunos de los métodos que
define la clase Object y que están disponibles para todos los objetos son:

MÉTODO DESCRIPCIÓN
Crea un nuevo objeto idéntico al objeto que llama
Object Clone() Throws Throwable
al método.
Devuelve true si el objeto que llama método es
boolean equals(Object objeto)
equivalente a objeto.
Método finalize() por omisión. El método finalize
void finalize () throws Throwable
es semejante a los destructores.
Obtiene un objeto Class que describe el objeto
final Class getClass()
que declara el método.
String toString() Devuelve una cadena que describe al objeto.

o String: En muchos lenguajes de programación, una cadena es un arreglo de


caracteres. Este no es el caso de Java. En Java, las cadenas son objetos. Cuando se
crea una cadena literal, realmente, se está creando un objeto String. Por ejemplo, el
literal “Hola”, es elaborado automáticamente, por Java, dentro de un objeto String.
Las cadenas simplemente se construyen como cualquier otro objeto, utilizando el
operador new y llamando al constructor de la clase; en este caso la llamada se
hace al constructor de String, el cual tiene dos formas: Sin parámetro y con un
objeto String, como parámetro, para inicializar la cadena.

Ejemplos de construcción de cadenas:


String cad = new String ();
String cad1 = new String (“Hola”);
String cad2 = new String (cad1);
String cad3 = “Hola Mundo”;

Curso de Java Standard Edition – J2SE 11


Algunos de los métodos que define la clase String se presentan a continuación:

MÉTODO DESCRIPCIÓN

Devuelve true si la cadena invocada contiene la


boolean equals (String str)
misma secuencia de caracteres que str.
int length () Obtiene y retorna la longitud de la cadena
Obtiene el carácter que se encuentra, dentro de la
char charAt (int index) cadena, en la posición index. Las cadenas se
comienzan a numerar en 0.
Retorna un valor menor que cero si la cadena
invocada es menor que str, y un valor mayor que
int compareTo (String str)
cero si la cadena es mayor que str y cero si las
cadenas son iguales.
Busca en la cadena invocada la subcadena
int indexOf (String str) especificada por str. Regresa el índice de la primera
correspondencia ó -1 en caso de falla.
Busca en la cadena invocada la subcadena
int lastIndexOf (String str) especificada por str. Regresa el índice de la última
correspondencia ó -1 en caso de falla.

o Character: representa la abstracción orientada a objeto, del tipo de dato simple


char. Algunos de los métodos que define la clase Carácter se presentan a
continuación:

MÉTODO DESCRIPCIÓN
Devuelve true si Ch está definido por Unicode,
Static Boolean IsDefined(char Ch)
en caso contrario, devuelve false.
Devuelve true si Ch es un dígito, devuelve
Static Boolean IsDigit(char Ch)
false.
Devuelve True si Ch es una letra, en caso
Static Boolean IsLetter(char Ch)
contrario devuelve False.
Devuelve True si Ch es una letra o un dígito, en
Static Boolean IsLetterOrDigit(char Ch)
caso contrario devuelve False.
Devuelve True si Ch es una letra minúscula, en
Static Boolean IsLowerCase(char Ch)
caso contrario devuelve False.
Devuelve True si Ch es un espacio en blanco,
Static Boolean IsSpace(char Ch)
en caso contrario devuelve False.
Devuelve True si Ch es carácter de título
Static Boolean IsTitleCase(char Ch)
Unicode, en caso contrario devuelve False.
Devuelve True si Ch es una letra mayúscula, en
Static Boolean IsUpperCase(char Ch)
caso contrario devuelve False.
Static char toLowerCase (char Ch) Devuelve la letra minúscula equivalente a Ch
Static char toTitleCase (char Ch) Devuelve la letra de título equivalente a Ch
Static char toUpperCase (char Ch) Devuelve la letra mayúscula equivalente a Ch

Curso de Java Standard Edition – J2SE 12


o Number: clase abstracta que define una superclase que es implementada por las
clases que envuelven los tipos numéricos int, long, float y double. Number tiene
métodos abstractos que devuelven el valor del objeto en cada uno de los tipos
simple, es decir, doubleValue() devuelve el valor como un double. floatValue ()
devuelve el valor como un float y así sucesivamente. A continuación se muestran
estos métodos:

MÉTODO DESCRIPCIÓN
Devuelve el valor especificado como un int.
public abstract int intValue()
Este método puede involucrar redondeo.
Devuelve el valor especificado como un long.
public abstract long longValue()
Este método puede involucrar redondeo.
Devuelve el valor especificado como un float.
public abstract float floatValue()
Este método puede involucrar redondeo.
Devuelve el valor especificado como un double.
public abstract double doubleValue()
Este método puede involucrar redondeo.
Devuelve el valor especificado como un short.
public short shortValue()
Este método puede involucrar redondeo.

o Integer: esta clase es una envoltura para los tipos de datos simples int, short y
byte. Los constructores para la clase Integer son:

Integer (int)
Integer (String) throws NumberFormatException

Esta clase define las constantes MIN_VALUE y MAX_VALUE, que establecen el rango
de valores que puede representar un objeto de esta clase. A continuación se
muestran estos métodos:

MÉTODO DESCRIPCIÓN
Devuelve true si el objeto Integer que lo llama
boolean equals (Object objInteger)
es equivalente a objInteger
Devuelve un valor entero equivalente al número
static int parseInt (String)
contenido en la cadena str.
Devuelve un valor entero equivalente al número
static int parseInt (String, int)
contenido en la cadena str usando la base.
Devuelve un Integer que contiene el valor
static Integer valueOf (String)
especificado por la cadena str.
Devuelve un Integer que contiene el valor
static Integer valueOf (String, int) especificado por la cadena str usando la base
indicada.
Todos estos métodos arrojan la excepción “NumberFormatException”

o Long: esta clase es una envoltura para los tipos de datos simples int, short y byte.
Los constructores para la clase Long son:
Long (int)
Long (String) throws NumberFormatException

Esta clase define las constantes MIN_VALUE y MAX_VALUE, que establecen el rango
de valores que puede representar un objeto de esta clase. A continuación se
muestran estos métodos:

Curso de Java Standard Edition – J2SE 13


MÉTODO DESCRIPCIÓN
Devuelve true si el objeto Long que lo llama es
boolean equals (Object)
equivalente a objLong
Devuelve un valor long equivalente al número
static long parseLong (String)
contenido en la cadena str.
Devuelve un valor long equivalente al número
static long parseLong (String, int) contenido en la cadena str usando la base
indicada.
Devuelve un Long que contiene el valor
static Long valueOf (String)
especificado por la cadena str.
Devuelve un Long que contiene el valor
static Long valueOf (String, int)
especificado por el String usando la base int.
Todos estos métodos arrojan la excepción “NumberFormatException”

o Double: esta clase es una envoltura para el tipo de dato simple double. Los
constructores para la clase Double son:

Double (int)
Double (double)
Double (String) throws NumberFormatException

Esta clase define las constantes MIN_VALUE y MAX_VALUE, que establecen el rango
de valores que puede representar un objeto de esta clase. Igualmente define las
constantes NaN (No es número), POSITIVE_INFINITY (Infinito Positivo) y
NEGATIVE_INFINITY(Infinito Negativo). A continuación se muestran estos métodos:

MÉTODO DESCRIPCIÓN
Devuelve true si el objeto Double que lo llama
boolean equals (Object objDouble)
es equivalente a objDouble
Devuelve true si el objeto contiene un valor
boolean isInfinite ()
infinito. En caso contrario, devuelve false.
Devuelve true si num contiene un valor
static boolean isInfinite(float num)
infinito. En caso contrario, devuelve false.
Devuelve true si el objeto contiene un valor
boolean isNaN () que no es número. En caso contrario, devuelve
false.
Devuelve true si num contiene un valor que no
static boolean isNaN (float num) es un número. En caso contrario, devuelve
false.
Devuelve un objeto Double que contiene el
static Double valueOf (String str)
valor especificado por la cadena String
static double parseDouble(String str) Devuelve un valor double equivalente al
número contenido en la cadena str.
Todos estos métodos arrojan la excepción “NumberFormatException”

o Float: esta clase es una envoltura para el tipo de dato simple float. Los
constructores para la clase Float son:

Curso de Java Standard Edition – J2SE 14


Float (int)
Float (double)
Float (String) throws NumberFormatException

Esta clase define las constantes MIN_VALUE y MAX_VALUE, que establecen el rango
de valores que puede representar un objeto de esta clase. Igualmente define las
constantes NaN (No es número), POSITIVE_INFINITY (Infinito Positivo) y
NEGATIVE_INFINITY(Infinito Negativo). A continuación se muestran estos métodos:

MÉTODO DESCRIPCIÓN
Devuelve true si el objeto Float que lo llama es
boolean equals (Object objFloat)
equivalente a objFloat
Devuelve true si el objeto contiene un valor
boolean isInfinite ()
infinito. En caso contrario, devuelve false.
Devuelve true si num contiene un valor
static Boolean isInfinite (float num)
infinito. En caso contrario, devuelve false.
Devuelve true si el objeto contiene un valor
boolean isNaN () que no es número. En caso contrario, devuelve
false.
Devuelve true si num contiene un valor que no
static Boolean isNaN (float num) es un número. En caso contrario, devuelve
false.
Devuelve un objeto Float que contiene el valor
static Float valueOf (String str)
especificado por la cadena String
Devuelve un valor float equivalente al número
static float parseFloat (String str)
contenido en la cadena str.
Todos estos métodos arrojan la excepción “NumberFormatException”

o Boolean: esta es una envoltura muy simple alrededor de valores boolean que sólo
es útil cuando se quiere pasar una variable bolean por referencia. Esta clase
contiene las constantes TRUE y FALSE, que definen un objeto Boolean true y false.
A continuación se muestran constructores de esta clase:
Boolean (boolean ValorBoolean)
Boolean (String CadenaBoolean)

En el primer constructor, la variable ValorBoolean tiene que ser true o false. En el


segundo constructor, si CadenaBoolean contiene la cadena “true” (en mayúsculas o
minúsculas), entonces el nuevo objeto Boolean será TRUE, en caso contrario será
FALSE.
MÉTODO DESCRIPCIÓN
Boolean booleanValue() Devuelve el valor boolean equivalente al objeto
Devuelve true si el objeto es equivalente al Objeto
Boolean equals(Boolean)
Bolean pasado por parámetro
Devuelve true si la propiedad del sistema
Static Boolean getBoolean(String) especificada por el String es true. En caso
contrario, devuelve false.
Int hashCode() Devuelve el código hash del objeto
String toString() Devuelve la cadena equivalente al objeto.
Devuelve true si String contiene la cadena “true”
Static Boolean valueOf(String)
(en mayúsculas o minúsculas), sino “false”.

Curso de Java Standard Edition – J2SE 15


o Arreglos Unidimensionales: En Java los arreglos son considerados variables
orientadas a objetos. Los elementos de los arreglos se indexan a partir de 0, para lo
cual se debe utilizar un índice entero. Debido a que los arreglos están
implementados como objetos: es posible asignar una variable de referencia de
arreglo a otra y simplemente está intercambiando aquel objeto al cual la variable se
refiere. Cada arreglo tiene asociado, una variable de instancia length, que posee el
número de elementos que la variable es capaz de almacenar (tamaño del arreglo).
Para crear un arreglo, se deben seguir los siguientes pasos: declaración,
construcción e inicialización.
ƒ Declaración de una arreglo:
boolean booleans[]; int ints[];
byte bytes[]; float floats[];
short[] shorts; long longs[];
char chars[]; double[] doubles;
Integer enteros []; Character [] caracteres;
En la declaración de un arreglo, los corchetes pueden ser colocados tanto
antes como después del nombre del arreglo. La declaración de un arreglo
no reserva espacio memoria, esto solo declara la variable.

ƒ Construcción de una arreglo:


Los Arreglos son construidos a través de la palabra reservada new. Cuando
se construye un arreglo el tamaño del mismo debe ser provisto.
short arreglo[];
arreglo = new short[5];
double [] arr = new double [10];

ƒ Inicialización de un arreglo:
Cuando un arreglo es construido en Java, sus elementos son inicializados
automáticamente con los valores por omisión, en caso de no haber una
inicialización explicita.
int ints[] = new int []{10,20,30,40};
double [] reales = new double [3]; Æ Todos los elementos del arreglo con 0.0d

Java no permite desbordar los límites de un arreglo en tiempo de ejecución, cuando


se intenta esto, se genera un mensaje de error representado por la excepción
ArrayIndexOutOfBoundsExeption, y termina la ejecución del programa.

o Arreglos Multidimensionales: En Java los arreglos multidimensionales son


considerados como arreglos de arreglos. Como un arreglo bidimensional es un
arreglo de arreglos, la variable de instancia length contendrá el número de arreglos
almacenados. La forma de obtener el número de elementos de uno de los arreglos
es la siguiente: sample[2].length.

La forma general de Declarar un arreglo multiidimensional:


tipo nombreArreglo[][]= new tipo[N° Filas][N° Columnas] ;

La forma de acceder una posición del arreglo, es la siguiente:


Arreglo [3] [5];

Los arreglos multidimensionales son inicializados colocando los valores iniciales de


cada sub-arreglo dentro de su propio conjunto de corchetes:

Curso de Java Standard Edition – J2SE 16


tipo nombreArreglo [] = {
{Valor1, Valor2, ... , ValorN};
{Valor1, Valor2, ... , ValorN};
...
{Valor1, Valor2, ... , ValorN};
};

Cuando se reserva memoria para un arreglo multidimensional, sólo se necesita


especificar la memoria para la primera dimensión. Después debe reservarse la
memoria, separadamente, para las otras dimensiones restantes no es necesario
reservar el mismo número de elemento para cada dimensión. Ejemplo:

int sample [][] = new [3][];


sample [0] = new int [2];
sample [1] = new int [4];
sample [2] = new int [3];

7. IDENTIFICADORES

Los identificadores usados en Java siguen reglas estándar: comienzan con una letra y pueden
contener sólo letras, números, los caracteres underscore (_) y dólar ($). Además no deben incluir
espacios. No existe restricción de longitud para los identificadores de Java. Los identificadores en
Java son sensibles a mayúsculas y minúsculas.

- Convención de Nombres. Generalmente, la primera letra en el nombre de la variable o en


el nombre de un método está en minúscula, mientras que la primera letra en un nombre de
clase está en mayúscula.

- Declaraciones. Las declaraciones de variables en Java contienen el nombre del tipo y


luego una lista de los nombres de las variables, donde los nombres de las variables son
separados por comas. Todas las sentencias en Java terminan con punto y coma. Es
importante destacar que en Java las variables pueden ser inicializadas en la sentencia de
declaración.

- Inicialización. Al igual que ocurre en C++, Java también permite la declaración de


variables en cualquier parte del código del programa. A diferencia de C++, el compilador de
Java no permite usar la variable antes de su inicialización. En el caso de C++, se genera un
mensaje de advertencia, mientras que en Java, se genera un error de compilación. Esta es
una ilustración del intento de Java por asegurar la portabilidad, dado que algunas
plataformas permiten el uso de variables no inicializadas, mientras que otras plataformas no.
Los datos miembros de una clase pueden no ser inicializados. Las variables de función
deben inicializarse.

- Alcance y Bloques. Al igual que en C y C++, Java también usa los caracteres { y } para
marcar el inicio y el final del bloque de sentencia(s). Una variable declarada dentro del
bloque sólo puede usarse dentro de ese bloque o en cualquier bloque que esté anidado en
él. La variable no estará disponible una vez que el control del programa salga del bloque en
el que fue declarada.

Curso de Java Standard Edition – J2SE 17


8. OPERADORES EN JAVA

Java tiene seis clases generales de operadores: aritméticos, a nivel de bits, relacionales y lógicos.
Java también define algunos operadores adicionales que permiten controlar ciertas situaciones
especiales.

- Operadores Aritméticos: Los operadores +, -,* y /, pueden ser aplicados a cualquier tipo
de datos numéricos, así como también, a los tipos char.

OPERADOR SIGNIFICADO EJEMPLO


+ SUMA 1+2Æ3
- RESTA 1 - 2 Æ -1
* MULTIPLICACIÓN 1*2Æ1
/ DIVISIÓN 2/1Æ2
% RESIDUO DE LA DIVISIÓN 1%2Æ0
++ INCREMENTO 1++ Æ 2 Ó ++1 Æ 2
-- DECREMENTO 1-- Æ 0 Ó --1 Æ 0

- Operadores de Bits: estos operadores insertan ceros o unos a la izquierda o derecha de


las variables numéricas a nivel de bits.

OPERADOR SIGNIFICADO USO


>> SIGNED RIGHT SHIFT 1 >> 31 Æ 0
<< UN-SIGNED LEFT SHIFT 1 << 31 Æ 2147483648
>>> UN-SIGNED RIGHT SHIFT -1 >>> 31 Æ 1

- Operadores Relacionales: El resultado de los operadores lógicos es un valor boolean.

OPERADOR SIGNIFICADO EJEMPLO


> MAYOR 1 > 2 Æ FALSE
>= MAYOR O IGUAL QUE 2 >= 2 Æ TRUE
< MENOR QUE 1 < 2 Æ TRUE
<= MENOR O IGUAL QUE 2 <= 1 Æ FALSE
== IGUAL A 1 == 2 Æ FALSE
¡= NO ES IGUAL A 1 != 2 Æ TRUE

- Operadores Lógicos: El resultado de los operadores lógicos es un valor boolean.

OPERADOR SIGNIFICADO EJEMPLO


! NEGACIÓN ! (FALSE) Æ TRUE
& CONJUNCIÓN AND LÓGICO 1 & 1 Æ TRUE
^ XOR 0 ^ 0 Æ FALSE
| DISYUNCIÓN OR LÓGICO 0 | 2 Æ FALSE
&& AND EN CORTOCIRCUITO 1 && 1 Æ TRUE
|| OR EN CORTOCIRCUITO 0 || 2 Æ FALSE

Curso de Java Standard Edition – J2SE 18


La diferencia de usar &, l o &&, ll, es que los primeros operandos siempre evaluarán cada
operando, mientras que las versiones de cortocircuito evaluarán el segundo operando sólo
cuando sea necesario.

- Operador instanceof: permite conocer si una variable de objeto está instanciada con un
tipo de objeto específico. La forma Genaro de este operador es como sigue:

variableObjeto instanceof ClaseObjeto

El resultado de la evaluación de la expresión anterior, será true si la variableObjeto, hace


referencia a un objeto de la clase ClaseObjeto.

- Asignaciones Taquigráficas: Java permite simplificar las declaraciones de asignación.

OPERADOR USO EQUIVALENTE A


+= OP1 += OP2 OP1 = OP1 + OP2
-= OP1 -= OP2 OP1 = OP1 - OP2
*= OP1 *= OP2 OP1 = OP1 * OP2
/= OP1 /= OP2 OP1 = OP1 / OP2
%= OP1 %= OP2 OP1 = OP1 % OP2
&= OP1 &= OP2 OP1 = OP1 & OP2
^= OP1 ^= OP2 OP1 = OP1 ^ OP2
<<= OP1 <<= OP2 OP1 << OP2
>>= OP1 >>= OP2 OP1 >> OP2
>>>= OP1 >>>= P2 OP1 >>> OP2

- Precedencia de Operadores: La siguiente tabla muestra el orden de precedencia de


mayor a menor para los operadores Java. Note que la primera fila muestra elementos que,
generalmente, no son considerados como operadores: paréntesis, corchetes, y el operador
punto. Recuerde que los paréntesis permiten alterar la precedencia de una operación.

PRIORIDAD OPERADORES
() [ ] .
MAYOR ++ -- !
* / %
+ -
>> >>> <<
>= >= < <=
. == !=
. &
. ^
|
&&
||
?:
MENOR = OP=

Curso de Java Standard Edition – J2SE 19


9. ESTRUCTURAS DE DE CONTROL

Las estructuras de control permiten realizar asignaciones, documentar el código, así como
también permiten tomar decisiones y realizar procesos repetidas veces, por lo que éstas
se clasifican en dos amplias categorías Condicionales e Iterativas. Estas en Java, son
básicamente las mismas sentencias que existen C/C++, solo con algunas consideraciones
especiales.

- Comentarios: Los comentarios son sentencias que ayudan a explicar el código.


No son procesados por Java, por lo cual no incrementarán el tamaño del BYTECODE .
Estos se expresan escribiendo frases precedidas por un doble // SLASH si el
comentario es de una sola línea o un conjunto de líneas encerradas por un bloque
/* */.

- Asignación: Las sentencias de asignación se utilizan para dar un (nuevo) valor a


una variable. Otra forma de verlo es como un método para copiar datos desde un
origen a un destino. Java utiliza el signo igual (=) para está operación.

- Condicionales: Son estructuras de decisión que hacen que el programa continúe


en una dirección cuando se encuentra una condición en particular.

o Sentencia if … else: Está es utilizada para ejecutar una sentencia en el


caso que una condición establecida sea verdadera, de lo contrario se podrá
ejecutar una sentencia distinta.

if (COND) {
...
} else {
...
}

o Sentencia switch: Esta sentencia permite realizar operaciones diferentes


dependiendo del valor de una variable de tipo ordinal.

switch(var){
case valor1: { … }
case valor2: { … }; break;

default: { … }
}

- Iterativas: También se denominan BUCLES y son aquellas sentencias de control


que nos permiten ejecutar un grupo de sentencias hasta que se cumpla cierta
condición.

o Sentencia while: Ejecuta un grupo de instrucciones cero (0) o más veces,


MIENTRAS una condición dada sea cierta.

while (COND) {
...
}

Curso de Java Standard Edition – J2SE 20


o Sentencia do … while: Ejecuta un grupo de instrucciones, MIENTRAS una
condición dada sea cierta. La condición es verificada después de ejecutarse
el conjunto de sentencias.

do {
...
} while (COND);

o Sentencia for: Ejecuta un grupo de instrucciones repetidamente un


número determinado de veces.

for (sentencia1; CONDICION_DE_PARADA; sentencia2) {


...
}

- Sentencia break: Las sentencia break ocasiona que el flujo de control salte a
sentencia inmediatamente siguiente a la sentencia actual (rompe la ejecución). La
sentencia break se puede emplear tanto en las sentencias condicionales como en
las iterativas.

- Sentencia continue: generalmente se utiliza la sentencia continue dentro de las


iterativas, para saltar a otra sentencia. La sentencia continue solo puede ser
llamada dentro de un bucle. Si se utiliza de la forma sencilla, la iterativa obvia
hasta el final del cuerpo del bucle y evalúa nuevamente la condición. If se usa con
etiquetas, la sentencia pasa a ejecutar la instrucción inmediatamente siguiente a la
etiqueta utilizado con la sentencia continue.

Curso de Java Standard Edition – J2SE 21


..
..
..
..
.
TEMA II: Clases, Objetos y Paquetes

OBJETIVOS:

ƒ Escribir un programa simple en Java que emplee Objetos, definiendo y agrupando


apropiadamente las clases y paquetes.

CONTENIDO:

ƒ Clases

ƒ Objetos

ƒ Paquetes

ƒ Un programa Java completo

............................
22
Curso de Java Standard Edition – J2SE 22
1. CLASES

1.1. NOCIONES BÁSICAS

La clase es núcleo de Java. Es la construcción lógica sobre la que se construye el lenguaje Java, ya
que define la forma y la naturaleza de un objeto. La clase constituye la base de la Programación
Orientada a Objetos en Java. Cualquier concepto que desee implementar en un programa Java debe
ser encapsulado en una clase. Dentro de una clase están definidos los datos y los códigos que
actúan sobre esos datos. Todas las actividades del programa Java ocurren dentro de una
clase, razón por la cual se dice que Java es un lenguaje 100% orientado a objetos.

Una clase en Java se define como: “una plantilla que tiene las definiciones de variables o estados y
métodos o comportamientos que es común a todos los objetos de un tipo en particular”. Java usa
especificaciones de clase para construir objetos, que son instancias de una clase. De tal manera,
una clase es básicamente un juego de planos que especifican cómo construir un objeto. Es
importante tener claro que una clase es una abstracción lógica, por lo que hasta que un objeto de
esa clase sea creado, no existirá una representación física de esa clase en memoria.

Los miembros de la clase, es decir los atributos y los métodos son llamados respectivamente
variables de instancia y métodos de instancia; ya que estos representan el estado de un
objeto, es decir que cada objeto de una clase contiene una copia propia de esas variables,
separada a la de los otros objetos de la clase. Además, existen las variables y métodos de clase,
los cuales pueden ser accedidos directamente de una clase sin instanciar, es decir que son
comunes a todos los objetos de una clase por igual.

1.2. DEFINICIÓN DE LAS CLASES

Cuando se define una clase, se manifiesta su naturaleza y forma exacta. Esto se hace especificando
los miembros de la clase, es decir las variables y los métodos que operan en ella.

Una clase se define a través de la palabra clave class. A continuación se muestra la forma general
de la definición de una clase:

[acceso] [modif] class NombreClase [extends SuperClase] [implements Interfaces] {

// Variables miembro
[acceso] [modif] tipo nombreVariable [= valorInicial];
CUERPO DE LA CLASE

// Métodos miembro
[acceso] [modif] tipo nombreMetodo([parametros]) [throws excepciones]{
// Cuerpo del método
};

};

Curso de Java Standard Edition – J2SE 23


- Componentes de la definición de una clase

COMPONENTES PROPÓSITO

De forma predeterminada todas las clases son friendly. Se puede


acceso
establecer como modificador de acceso public

abstract Opcional. La clase no se puede instanciar


Modif.
final Opcional. La clase no se puede derivar

Class NombreClase Especifica el nombre de la clase

extends SuperClase Opcional. Especifica el nombre de la SuperClase (Clase Padre)

implements Interfaces Opcional. Especifica las Iinterfaces implementadas por la clase

Implementación de la clase, declaración de variables y métodos


{ cuerpo de la clase };
miembro

Tabla 1. Componentes de la definición de una clase

- Componentes de la definición de variables miembro

[acceso] [modif] tipo nombreVariable [= valorInicial];

COMPONENTES PROPÓSITO

acceso Especifica el nivel de acceso de la variable (ver Tabla 4).

static Indica la declaración de una variable de clase.

final Indica que la variable es una constante.


modif
transient Indica que la variable no es serializable.

volatile Le indica al compilador que debe realizar ciertas optimizaciones.

tipo Indica el tipo de la variable

NombreVariable Indica el identificador de la variable

valorInicial Especifica el valor inicial para esa variable

Tabla 2. Componentes de la definición de variables miembro

Cuando el sistema encuentra una clase por primera vez en un programa, crea una única copia
de todas las variables de clase que serán compartidas por todas las instancias (objetos) de la
clase. Si una variable de clase es cambiada por un objeto de la clase, entonces el cambio de su
valor se refleja en todas las demás instancias de la clase.

Curso de Java Standard Edition – J2SE 24


- Componentes de la definición de métodos miembro

[acceso] [modif] tipo nombreMetodo([parametros]) [throws excepciones]{


// Cuerpo del método
};

COMPONENTES PROPÓSITO

acceso Especifica el nivel de acceso del método (ver Tabla 4).

static Indica la declaración de un método de clase

abstract Indica que no se proporciona la implementación del método (función virtual)

modif final Indica que la subclase no puede sobrescribir el método

native Indica que la implementación de método está escrita en otro lenguaje

syncronized Indica que el método necesita de un “Monitor” para ejecutarse

tipo Indica el tipo de retorno del método

nombremetodo Indica el identificador del Método

parametros Especifica la lista de argumentos formales para el método

throws excepciones Da la lista de excepciones lanzadas por el método

Tabla 3. Componentes de la definición de métodos miembro

Ya que Java es un lenguaje netamente orientado a objetos, cuando sea necesario implementar
funciones para uso general, la forma de hacerlo es a través de los métodos de clase (static).

- Especificadores de acceso
Podemos usar los especificadores de acceso a Java para proteger las variables y métodos de
una clase mientras se declaran. La siguiente tabla presenta los niveles de accesos permitidos:

ESPECIFICADOR SIGNIFICADO

private Accesible sólo dentro de la clase donde se define

Accedida por la clase en donde está definida, sus subclases y las clases en
protected
el mismo paquete

public Accesible desde cualquier parte

Accesible desde todas las clases presentes en el mismo paquete. Este es


friendly
el modificador de acceso por omisión.

Tabla 4. Especificadores de acceso

Curso de Java Standard Edition – J2SE 25


- Ejemplo de la declaración de una clase

public class Ejemplo { Objeto


// Variables Miembro x
VARIABLES
y
private int x; DE INSTANCIA

float Y;
static char sc;
class Ejemplo
static double sd; {
… sc VARIABLES sv
} DE CLASE
// Métodos Miembro
void setX(int valor) {
x=valor;
x VARIABLES
};
Variables y
DE INSTANCIA
public float getY() {
Objetos Objeto
return Y;
};
};

1.3. CLASES EJECUTABLES

Como ya se ha mencionado en Java todo es una clase, por lo tanto la aplicación (programa) también
es una clase. Dicha clase tiene la característica particular de poseer un método de clase denominado
main. Este método es semejante a la función main() de un programa C++, razón por la cual, va a
ser el primer método en ejecutarse al correr un programa Java.

public class NombreClase [extends SuperClase] [implements interfaz] {


// Variables miembro
...
// Métodos miembro
CUERPO DE LA CLASE

...

// Método main
public static void main(String [ ] args) {
// Cuerpo del método
};

};

Otra característica importante de las clases ejecutables, es que la misma debe ser public y llamarse
igual al archivo que la contiene, es decir el nombre del archivo fuente (archivo .java) debe ser el
idéntico al nombre de la clase.

Curso de Java Standard Edition – J2SE 26


2. OBJETOS

Usualmente, en un programa Java, se crean muchos objetos a partir de diferentes clases y estos
interactúan entre ellos enviando mensajes. Después de que el objeto completa el trabajo para el
cual se creó, se recolecta como basura y sus recursos se liberaron, para el uso de otros objetos. El
ciclo de vida de un objeto consiste típicamente de los siguientes pasos: creación de objetos, uso de
los objetos creados y destrucción de los objetos.

2.1. CREACIÓN DE OBJETOS

Cuando se crea una clase se está creando un nuevo tipo de dato que se puede utilizar para declarar
objetos de ese tipo. Sin embargo, para obtener objetos de una clase es necesario hacer dos pasos.
En primer lugar, se debe declarar una variable del tipo de la clase. Esa variable no define un objeto,
sino que es simplemente una variable que puede referirse a un objeto. En segundo lugar, se debe
obtener una copia física y real del objeto y asignarla a la variable.

La creación de un objeto es básicamente la creación de una instancia de una clase. Un objeto de


una clase se crea mediante el operador new, como se muestra a continuación:

Coordenadas plano = new Coordenadas ();

En realidad, en la sentencia dada se realizan tres acciones: la declaración del objeto, la instanciación
del objeto y la inicialización del mismo. La declaración del objeto no necesita realizarse junto con la
creación del objeto. Pueden hacerse en pasos separados como se muestra a continuación:

Coordenadas plano;
plano = new Coordenadas();

Aquí la primera de las dos líneas es la declaración del objeto, en donde Coordenadas representa a la
clase y plano es la variable de referencia a los objetos. El operador new en Java es llamado
operador de instanciación, el cual se usa para crear nuevos objetos. La inicialización del objeto
se hace usando Coordenadas(), que es la llamada a su constructor usado para inicializar el objeto.

- Constructores de una clase: Todas las clases en Java tienen al menos un constructor
para inicializar un objeto nuevo creado a partir de un tipo en particular. El nombre del
constructor es el mismo que el nombre de la clase, no tiene tipo de retorno y debe ser
público. Java nos permite tener tantos constructores como queramos para una clase
(sobrecarga del constructor). Mientras creamos nuestra propia clase, no necesitamos
escribirle un constructor, ya que el sistema en tiempo de ejecución proporciona un
constructor por omisión para la clase si nosotros no desarrollamos ninguno. Este constructor
por omisión, tiene una implementación vacía.

public class Coordenada {



// Constructor predeterminado de la clase Coordenadas
public Coordenada() {
super();
};

// Constructor parametrizado de la clase Coordenadas


public Coordenada(int x, int y) {

Curso de Java Standard Edition – J2SE 27


super();
setEjeX(x);
setEjeY(y);
};

};
Ejemplo de invocación de los constructores:
Coordenada plano1 = new Coordenada(); // Constructor por omisión
Coordenada plano2 = new Coordenada(20,25); // Constructor parametrizado

2.2. USO DE OBJETOS

Una vez que se crea un objeto, nos gustaría usarlo para realizar alguna tarea. Podemos necesitar
alguna información del objeto, podemos querer cambiar su estado, o podemos querer usarlo para
realizar alguna tarea. Hacemos estas cosas ya sea manipulando o visualizando sus variables o
llamando a sus métodos. En fin, el uso de los objetos está limitado a invocar a los métodos
miembros de la clase a la cual pertenecen, y a cambiar de referencia.

Objeto.Método(parámetros);

Supongamos que la clase Coordenada, posee un método para asignar y obtener la coordenada x, su
implementación e invocación sería como sigue:

Coordenada OBJ = new Coordenada();


[Link](12);
int X = [Link]();

2.3. DESTRUCCIÓN DE OBJETOS (RECOLECCÍON DE BASURA)

Los objetos están dinámicamente asignados en una sección de memoria libre por medio del
operador new. Como sabemos, la memoria no es infinita y la memoria libre puede agotarse. Por
esta razón, un componente clave para cualquier esquema de asignación dinámica de memoria,
consiste en recobrar la memoria libre de objetos que no estén en uso, disponiendo de esta memoria
para reasignaciones posteriores. En muchos lenguajes de programación, el liberar memoria asignada
con anterioridad se hace manualmente. Por ejemplo, en C++ se usa el operador delete para liberar
memoria que estaba asignada. Sin embargo, Java emplea un método diferente: recolección de
basura.

El sistema de recolección de basura de Java, automáticamente reclama objetos que aparecen


transparentemente detrás de escena, sin ninguna intervención del programador. Trabaja de la
siguiente forma: cuando no existe una referencia a un objeto, se asume que ese objeto no se
necesita más y se recupera la memoria ocupada por éste. Esta memoria reciclada puede usarse
entonces para una asignación posterior.

La recolección de basura ocurre sólo esporádicamente durante la ejecución de su programa. No


ocurrirá simplemente porque uno o más objetos existan y no se usen. La recolección de basura se
ejecuta, generalmente sólo cuando se cumplen dos condiciones: que existan objetos para reciclar, y
la necesidad de reciclarlos.

Curso de Java Standard Edition – J2SE 28


- El método finalize (): De forma análoga a lo que eran los destructores en C++, en Java
existen los finalizadores. Estos métodos se emplean, cuando un objeto necesita realizar una
serie de acciones cuando es destruido. El finalizador de una clase se llama justo antes de la
recolección de basura, por lo que los finalizadores son diferentes a los destructores. Es
importante entender, que no se puede saber cuándo (o inclusive si) el método finalize()
será ejecutado.

public class Ejemplo {



protected void finalize() {
// Código de finalización
};
};

3. PAQUETES

Un paquete es un contenedor que permite guardar el nombre de la clase en una forma de


compartimientos. En muchas formas, un paquete es como un directorio, que permite guardar en
forma segura una clase dentro de él. Es decir, que los paquetes son grupos de clases relacionadas
almacenadas en una unidad, la cual ayuda a organizar el código y proporciona otra capa de
encapsulación.

En programación, los paquetes, son útiles para agrupar las piezas relacionadas de un programa. En
Java, un paquete sirve para dos propósitos: primero, suministra un mecanismo por el cual piezas
relacionadas de un programa pueden ser organizadas como una unidad; así, un paquete
proporciona la manera de nombrar una colección de clases. Segundo, un paquete participa en los
mecanismos de control de acceso en Java. Las clases definidas dentro de un paquete pueden
hacerse privadas a ese paquete y no accesibles por código fuera del paquete.

Es importante aclarar, que a los paquetes hay que considerarlos desde dos puntos de vista: el punto
de vista lógico, en el cual los paquetes almacenan las declaraciones de las clases (archivos fuente de
Java); y el punto de vista físico, en el cual los paquetes van a almacenar los archivos .class de las
clases definidas dentro del paquete.

3.1. ESPACIOS DE NOMBRES

En general, cuando nombra una clase, está asignando un nombre desde el espacio de nombre.
Un espacio de nombre define una región declaratoria. En Java dos clases no pueden usar el mismo
nombre desde el mismo espacio. Así, dentro de un espacio de nombre dado, cada nombre de clase
debe ser único. Los paquetes suministran una manera de dividir el espacio de nombre, evitando
problemas de duplicidad de nombres. Cuando una clase se define dentro de un paquete, el nombre
de ese paquete se une a cada clase, con lo que se evita que los nombres choquen con otras clases
del mismo nombre, pero que estén en otros paquetes. Si Para una clase, no se define un paquete,
dicha clase pertenecerá al paquete predeterminado de Java y por ende al espacio de nombre
predeterminado o global de Java.

Curso de Java Standard Edition – J2SE 29


3.2. DEFINICIÓN DE PAQUETES

Todas las clases en Java pertenecen a algún paquete. Como se mencionó anteriormente, cuando no
se especifica algún paquete se usa el paquete predeterminado (o global). Además, el paquete
predeterminado no tiene nombre, lo que lo hace transparente.

Para crear un paquete, coloque un comando package como la primera sentencia del archivo fuente
de Java. Esto asegurará que cualquier clase declarada en ese archivo pertenecerá a ese paquete
particular. Debido a que un paquete define un espacio de nombre, los nombres de las clases que
coloque dentro del archivo fuente, se convierten en parte de ese espacio del paquete. Una misma
sentencia package se puede incluir en más de un archivo fuente, por lo que no se impide que otras
clases de otros archivos puedan formar parte de un mismo paquete. En las aplicaciones reales, los
paquetes se suelen distribuir en muchos archivos fuente.

Java usa el sistema de archivo para manejar los paquetes, con cada paquete almacenado en su
propio directorio. Como el resto de Java, los nombres de paquetes son sensibles a mayúsculas y
minúsculas. Es decir, el directorio en el cual es guardado un paquete debe ser el mismo del nombre
del paquete.

package myPack;

Este paquete corresponderá con un directorio en el sistema de archivos llama \myPack. Observe que
se puede crear una jerarquía de paquetes dentro de paquetes separando los niveles con puntos.

package paq1.paq2.paq3;

Esta jerarquía de paquetes se debe reflejar en el sistema de archivos del sistema de desarrollo de
Java: \paq1\paq2\paq3.

3.3. UBICACIÓN DE PAQUETES

Como se explicó, los paquetes son reflejados en directorios. ¿Cómo sabe el sistema en tiempo de
ejecución de Java dónde buscar los paquetes que usted creó? La respuesta tiene dos partes.
Primero, por omisión: el sistema en tiempo de ejecución de Java busca en el directorio en curso
como punto de partida. Así, si sus archivos de clase están en el directorio actual, o en un
subdirectorio del directorio actual, ellos se encontrarán. Segundo, puede especificar una ruta o rutas
de directorios, colocándola en la variable de entorno CLASSPATH. Dicha variable, controla la
ubicación particular que debe ser considerada por Java como la raíz de la jerarquía de paquetes.

Para configurar esta variable de entorno, desde la consola del sistema escribir lo siguiente:

[set] CLASSPATH=.;CLASSPATH[;otros_directorios]

3.4. PAQUETES Y ACCESO A MIEMBROS

Java proporciona muchos niveles de protección para permitir un control adecuado de la visibilidad
de las variables y métodos dentro de clases, subclases y paquetes. Las clases y los paquetes son
dos medios de encapsular y contener el espacio de nombre y alcance de las variables y métodos.
Java proporciona cuatro tipos de visibilidad para los miembros de clase. Visibilidad de los miembros
de la clase según su modificador de acceso.

Curso de Java Standard Edition – J2SE 30


ESPECIFICADOR CLASE SUBCLASE PAQUETE MUNDO

private Si No No No

protected Si Si Si No

public Si Si Si Si

package Si No Si No

Tabla 5. Paquetes y acceso a miembros

3.5. IMPORTACIÓN DE PAQUETES

Dado que los paquetes existen y son un buen mecanismo para organizar de forma estructurada las
clases, es fácil de ver por qué todas las clases incorporadas en Java se almacenan en paquetes. No
hay ninguna clase de Java almacenada en el paquete por omisión.

De manera análoga, a lo que sería una directiva #include en C++, Java incluye la sentencia
import, para que se puedan ver ciertas clases o paquetes enteros. En un archivo fuente de Java,
las sentencias import tienen que ir inmediatamente después de la sentencia package, si existe, y
antes de las definiciones de las clases.

import [Link]; // Importa una clase específica


import paquete.*; // Importa todas las clases en un paquete

3.6. PAQUETES DE RELEVANCIA

A continuación estudiaremos los paquetes de mayor relevancia que proporciona la API de Java.

- [Link]: Este paquete se importa automáticamente en todos los programas y contiene


clases e interfaces que son fundamentales para la programación en Java. Es el paquete más
utilizado de Java. [Link] incluye las siguientes clases:

Object Boolean SecurityManager


String Character ClassLoader
Number Class Proccess
Long System Thread
Integer Math ThreadGroup
Double StringBuffer Throwable
Flota Runtime Compiler

Nota: las clases en cursiva fueron vistas en los tipos de datos orientados a objetos (Tema
I). En esta parte se estudiaran las clases resaltadas en negrita.

o Class: encapsula el estado de ejecución de un objeto o interfaz. Los objetos del


tipo Class se crean automáticamente cuando se cargan las clases. Un objeto
Class no se puede declarar de forma explícita. Generalmente, se obtiene un
objeto Class llamando al método getClass() definido en la clase Object. .
Algunos de los métodos que define la clase Class son:
Curso de Java Standard Edition – J2SE 31
MÉTODO DESCRIPCIÓN
Devuelve un objeto Class dando su nombre
static Class forName(String name)
completo.
Cuando se invoca sobre un objeto, devuelve
una matriz de interfaces implementadas por
Class [] getInterfaces() la clase del objeto. Si se invoca sobre una
interfaz, devuelve una matriz con sus
interfaces Padre.
Devuelve el nombre completo de la clase o
String getName()
interfaz del objeto que llama el método
Devuelve la clase padre del objeto. Retorna
Class getSuperclass()
null si el objeto es de tipo Object.
Bolean isInterface() Devuelve trae si el objeto es una interfaz

o System: esta clase contiene un conjunto de métodos y variables estáticos. La


entrada, salida y salida de error del intérprete de Java se almacenan en las
variables in, out y err. Veamos algunos de los usos más comunes de la clase
System:

MÉTODO DESCRIPCIÓN
Devuelve la hora actual en milisegundos
static long currentTimeMillis ()
desde el 1 de enero de 1970
Detiene la ejecución y devuelve el valor
Static void exit(int codSalida) codSalida al proceso padre. El valor cero (0)
indica que ha terminado correctamente.
Static void gc() Inicia el sistema de recolección de basura
Carga la biblioteca dinámica cuyo nombre
Static void loadLibrary(String lib)
está asociado con lib
Inicia la llamada a los métodos finalize() de
Static void runFinalization() todos los objetos no utilizados y que todavía
están sin recolectar

o Math: contiene todas las funciones en coma flotante que se utilizan en


geometría y trigonometría, así como algunos métodos de propósito general.
Math define dos constantes double E = 2.72 y double PI = 3,14.. los métodos
definidos en la clase Math son:

MÉTODO DESCRIPCIÓN

static int abs(int arg) Devuelve el valor absoluto de arg


static long abs(long arg) Devuelve el valor absoluto de arg.
static float abs(float arg) Devuelve el valor absoluto de arg.
static double abs(double arg) Devuelve el valor absoluto de arg.
Devuelve el número completo más pequeño
static double ceil(double arg)
mayor o igual que arg.
Devuelve el número completo más grande
static double floor(double arg)
menor o igual que arg.

Curso de Java Standard Edition – J2SE 32


static int max(int x, int y) Devuelve el máximo de x e y.
static long max(long x, long y) Devuelve el máximo de x e y.
static float max(float x, float y) Devuelve el máximo de x e y.
static double max(double x,
Devuelve el máximo de x e y.
double y)
static int min(int x, int y) Devuelve el mínimo de x e y.
static long min(long x, long y) Devuelve el mínimo de x e y.
static float min(float x, float y) Devuelve el mínimo de x e y.
static double min(double x,
Devuelve el mínimo de x e y.
double y)
static double rint(double arg) Devuelve el valor entero mas cercano de Arg
static int round(float arg) Devuelve arg redondeado al int mas cercano
Devuelve arg redondeado al long mas
static long round(float arg)
cercano

- [Link]: La biblioteca de Java contiene un conjunto de clases de utilidades que se utilizan


en los paquetes principales de Java y que también están disponibles para ser utilizados en
cualquier programa escrito. Estas clases se utilizan para almacenar conjuntos de objetos,
generar números aleatorios, manipulación de la fecha y hora y operaciones con cadenas. A
continuación se muestran las clases incluidas en [Link]:

Date Stack Observable


Random Dictionary Map
Vector Properties HashTable

Nota: En esta parte solo se estudiaran las clases en negrita.

o Date: Representa una fecha y hora. Los métodos más importantes definos en la
clase Date son lo siguientes:

MÉTODO DESCRIPCIÓN

Date() Inicializa el objeto con la fecha y hora actual


Construye un objeto con la fecha y hora
Date(String fecha)
especificada.
Inicializa el objeto con la fecha pasada. El
parámetro año especifica el número de años
que han transcurrido de 1900. el parámetro
Date(int año, int mes, int dia) mes establece el mes del año comenzando
en 0. El parámetro día establece el día del
mes. Este constructor establece la hora del
objeto a las 12:00:00
Devuelve trae si el objeto Date contiene una
boolean after(Date fecha)
fecha posterior a la especificada en fecha

Curso de Java Standard Edition – J2SE 33


Devuelve trae si el objeto Date contiene una
boolean befote(Date fecha) fecha anterior a la especificada en el
parámetro
Devuelve trae si el objeto Date contiene la
boolean equals(Object fecha) misma fecha y hora que la especificada por
parámetro
int getDate() Devuelve el día del mes (1 – 31)
int getDay() Devuelve el día de la semana (0 – Domingo)
Int getMonth() Devuelve el mes (0 - Enero)
Devuelve el número de años desde 1900.
Int getYear() por lo tanto el año actual será este valor
devuelto + 1900
int getHours() Devuelve la hora, en 24 horas
int getMinutes() Devuelve los minutos
Int getSeconds() Devuelve los segundos
void setDate(int dia) Establece el día del mes
void setMonth(int mes) Establece el mes
Establece el año. El valor del año se debe
void setYear(int año)
colocar restándole 1900
void setHours(int hora) Establece la hora (0 – 23)
void setMinutes(int min) Establece los minutos (0 – 59)
void setSeconds(int sec) Establece los segundos (0 – 59)
Nota: no se puede establecer el día de la semana ya que éste depende del día
del mes.

o Random: es un generador de números pseudos-aleatorios. Se les llama así,


porque son secuencias distribuidas uniformemente. Cuando se inicializa un
objeto Random con un valor (semilla), se está definiendo el punto inicial de
una secuencia aleatoria. Si se utiliza la misma semilla, para inicializar otro objeto
Random se obtendrá la misma secuencia aleatoria. Para generar distintas
secuencias es necesario especificar distintas semillas. Algunos de los métodos
que define la clase Random son:
o
MÉTODO DESCRIPCIÓN
Crea un generador de número que utiliza la
Random()
hora actual como valor inicial.
Permite especificar el valor inicial de la
Random(long semilla)
secuencia aleatoria.
double nextDouble() Devuelve el siguiente número aleatorio double
float nextFloat() Devuelve el siguiente número aleatorio float
int nextInt() Devuelve el siguiente número aleatorio int
long nextLong() Devuelve el siguiente número aleatorio long
Establece la semilla, es decir, el punto de inicio
void setSeed(long semilla)
del generador de número aleatorios

o Vector: La clase Vector es básicamente un arreglo de longitud variable de


referencias a objetos, es decir, un Vector puede dinámicamente aumentar o
disminuir su tamaño. Los vectores se crean con un tamaño inicial y cuando se

Curso de Java Standard Edition – J2SE 34


supera ese tamaño, automáticamente aumentan su tamaño. Todos los vectores
comienzan con una capacidad inicial. Algunos de los métodos definidos en la
clase Vector son los siguientes:

MÉTODO DESCRIPCIÓN
Este constructor crea un vector vacío con
Vector()
capacidad para 10 elementos.
Este constructor crea un vector vacío con
Vector(int N)
capacidad para N elementos.
Este constructor crea un vector vacío con
capacidad para N elementos y cuyo
incremento es incr. El incremento especifica el
número de elementos que se tienen que
Vector(int N, int incr)
reservar cada vez que se aumenta el tamaño
del Vector, si no se especifica incr, entonces el
Vector duplica su tamaño cada vez que se
reserva memoria para él.
final void addElment(Object elm) Añade al Vector el objeto especificado por elm
Final void insertElementAt(Object o, Añade el Objeto al Vector en la posición
int pos) indicada
final int capacity() Devuelve la capacidad del Vector
final int size() Devuelve el numero de elementos en el Vector
final boolean contain(Object obj) Devuelve true si el objeto está en el Vector
final Object elementAt(int pos) Devuelve el Objeto en la posición especificada
final Object firstElement() Devuelve el primer objeto en el Vector
final Object lastElement() Devuelve el ultimo objeto en el Vector
final bolean isEmpty() Devuelve true si el Vector está vacío
Elimina todos los elementos del Vector. Una
final void removeAllElements()
vez ejecutado el tamaño del Vector es cero.
Elimina la primera instancia del objeto en el
final void removeElement(Object o)
Vector
final void removeElementAt(int pos) Elimina el elemento de la posición indicada
final void setElementAt(Object o, int p) Coloca el objeto en la posición indicada
Devuelve la posición de la primera ocurrencia
final int indexOf(Object element) del elemento. Si el objeto no se encuentra
devuelve -1

o Stack: Esta es una subclase de Vector, que implementa la abstracción de una


pila. Los métodos que agrega la clase Snack son los siguientes:

MÉTODO DESCRIPCIÓN
Stack() Crea una pila vacía
boolean empty() Devuelve true si la pila está vacía
Devuelve el elemento en el tope, pero no lo
Object peek()
retira de la pila
Devuelve el elemento en el tope y lo extrae
Object pop()
de la pila
Object push(Object element) Introduce un elemento en la pila.

Curso de Java Standard Edition – J2SE 35


- [Link]: El paquete [Link], contiene todas las clases que permiten elaborar
aplicaciones en Java, capaces de operar en redes. El estudio de estas clases está fuera
del alcance de este curso.

- [Link]: El paquete [Link], contiene todas las clases para realizar las operaciones de
Entrada/Salida (E/S). El estudio de estas clases se realizará en el Tema V:
Entrada/Salida.

- [Link]: El paquete [Link], suministra todas las clases que proporcionan la


conectividad a bases de datos. El estudio de estas clases se realizará en el Tema VI:
Tecnologías de acceso a datos.

- [Link]: El paquete [Link], proporciona las clases básicas para el manejo de de


interfaces gráficas de usuario. El estudio de estas clases se realizará en el Tema VII:
Interfaces Gráficas.

- [Link]: El paquete javaxswing, proporciona todas las clases para realizar el


manejo de interfaces gráficas de usuario. El estudio de estas clases se realizará en el
Tema VII: Interfaces Gráficas.

Curso de Java Standard Edition – J2SE 36


4. UN PROGRAMA JAVA COMPLETO

/**
* ARCHIVO....: [Link]
* @autor.......: Prof. Ronel J. Rivas R.
* @date........: 19/09/2005
* DESCRIPCIÓN: Archivo que contiene la especificación de un ejemplo sobre:
* paquetes, importación de paquetes y clases, clases generales,
* clases Ejecutables, objetos y referencias a objetos
**/

package myPack;

import [Link].*;
import [Link];

/*************************
** CLASES DEL PAQUETE **
*************************/
// Clase para manejar la Hora
class JTime {
// VARIABLES DE INSTANCIA
private int hour, minutes, seconds;

// CONSTRUCTORES
public JTime() {
super();
setHour(12);
setMinutes(0);
setSeconds(0);
};
public JTime(int h,int m,int s) {
super();
setHour(h);
setMinutes(m);
setSeconds(s);
};

// METODOS DE INSTANCIA
public void setHour(int h) {
[Link] = h;
};
public int getHour(){
return [Link];
};

Curso de Java Standard Edition – J2SE 37


public void setMinutes(int m) {
[Link] = m;
};
public int getMinutes(){
return [Link];
};
public void setSeconds(int s) {
[Link] = s;
};
public int getSeconds(){
return [Link];
};
};

/**********************************
** CLASE PRINCIPAL DEL PAQUETE **
***********************************/
// Clase de Ejemplo
public class Example {
// VARIABLES DE INSTANCIA
private int day, month, year;
private JTime time;

// CONSTRUCTORES
public Example() {
super();
setDate(12,2,2004);
time = new JTime();
};

// METODOS DE INSTANCIA
public void setDay(int d) {
[Link] = d;
};
public int getDay(){
return [Link];
};
public void setMonth(int m) {
[Link] = m;
};
public int getMonth(){
return [Link];
};
public void setYear(int y) {
[Link] = y;
};

Curso de Java Standard Edition – J2SE 38


public int getYear(){
return [Link];
};
public void setDate(int d, int m, int y) {
setDay(d);
setMonth(m);
setYear(y);
};
public Date getDate(){
return new Date(getYear(),getMonth(),getDay());
};
public void setTime(int hour, int minutes, int seconds) {
time = new JTime(hour,minutes,seconds);
};
public JTime getTime() {
return [Link];
};

// METODO PRINCIPAL
public static void main(String [] args){
Example miEjemplo = new Example();
JTime hora;

[Link](12,2,2004);
[Link](1,15,0);
hora = [Link]();

[Link]("La Fecha Actual es: " + [Link]());


[Link]("La Hora Actual es: " + [Link]() + "-");
[Link]([Link]() + "-" + [Link]());

hora = new JTime(3,0,0);


[Link]("La nueva Hora es: " + hora);
};
};

Curso de Java Standard Edition – J2SE 39


..
..
..
..
.
TEMA III: Herencia, Clases Abstractas e Interfaces

OBJETIVOS:

ƒ Manejar los conceptos de Herencia, clases abstractas, interfaces y polimorfismo.

ƒ Escribir un programa en Java, donde se reflejen los conceptos de herencia y polimorfismo.

CONTENIDO:

ƒ Herencia

ƒ Clases abstractas

ƒ Interfaces

............................
40
Curso de Java Standard Edition – J2SE 40
1. HERENCIA

1.1. FUNDAMENTOS

La herencia es considerada uno de los fundamentos de la programación orientada a objetos, dado


que permite crear una jerarquía de clasificaciones. Usando este concepto se puede definir una clase
general que da la definición de los rasgos comunes a un conjunto de clases relacionadas. Otras
clases que añaden características que son únicas para ellas pueden heredar de esta clase general.
En Java, la clase que es heredada es llamada una superclase y la clase que hereda de otra, es
llamada una subclase. Por lo tanto, una subclase es un tipo especial de la superclase. Aunque una
superclase tenga una subclase, esto no significa que la superclase no pueda ser utilizada por sí sola.

Sólo puede haber una superclase para cualquier clase que se cree, ya que Java no soporta la
herencia múltiple, es decir varias superclases en una subclase. Sin embargo, se puede crear una
jerarquía de herencia en la que una subclase llegue a ser una superclase de otra subclase. Ninguna
clase puede ser superclase de sí misma.

Para especificar que una clase hereda de otra, la clase que hereda debe usar en su declaración la
palabra clave extends después del nombre de la clase. Esto implica que la subclase extiende la
funcionalidad y características de la superclase. La forma general de declarar una clase que hereda
de una superclase se muestra a continuación:

class NombreSubClase extends NombreSuperClase {


// Cuerpo de la clase
};

1.2. ACCESO A MIEMBROS Y HERENCIA

El siguiente programa es un ejemplo sencillo de herencia, donde se crea una superclase A y una
subclase llamada B.
//Crea una superclase
class A {
private int i;
private int j;
public void setIJ (int x, int y) {
i = x;
j = y;
}
public int getI () {
return i;
}
}

//Crea una subclase que extiende o hereda de la clase A


class B extends A {
private int total;
public void setTotal (int t) {
total = t;
}
public int getTotal () {

Curso de Java Standard Edition – J2SE 41


return total;
}
public void sumar (){
setTotal ( getI() + j ); // Error: j no es accesible aquí, por ser privada.
}
}

// Clase Ejecutable
public class Acceso {
public static void main (String args[]) {
B subObj = new B();
[Link] (10, 12);
[Link] ();
[Link] (“El total es ” + [Link]());
}
}

Este programa no compila ya que la referencia a la variable j dentro del método sumar () de la clase
B provoca una violación de acceso. Como j es una variable privada sólo es accesible por los otros
miembros de su propia clase. Aunque una subclase hereda todos los miembros de su superclase, no
puede acceder a aquellos miembros de su superclase que hayan sido declarados private. Para
solucionar esto es necesario implementar un método de instancia público que tenga acceso al
miembro privado.

1.3. REFERENCIAR OBJETOS SUBCLASE A TRAVÉS DE OBJETOS SUPERCLASE

Una referencia al objeto de la superclase puede tener asignada una referencia a cualquier objeto de
sus subclases. Cuando a una variable de referencia a superclase se le asigna la referencia a la
subclase, el acceso será sólo a los miembros que están definidos en la superclase; debido a que la
superclase no conoce acerca de las características especiales añadidas por su subclase. El siguiente
ejemplo ilustra este aspecto, usando las clases A y B del ejemplo anterior (sin error):

//Crea una superclase


class A {
private int i;
private int j;
public void setIJ (int x, int y) {
i = x;
j = y;
}
public int getI () {
return i;
}
}
//Crea una subclase que extiende o hereda de la clase A
class B extends A {
private int total;
public void setTotal (int t) {
total = t;
}
Curso de Java Standard Edition – J2SE 42
public int getTotal () {
return total;
}
public void sumar (){
setTotal ( getI() + getJ() );
}
}

// Clase Ejecutable
public class Acceso {
public static void main (String args[]) {
B subObj = new B();
A superObj = new A();
[Link] (10, 12);
[Link] ();
[Link] (“El total es ” + [Link]());
// Asigna una referencia de B a una referencia de A
superObj = subObj;
[Link] (1, 5); // Correcto: el método setIJ() está definido en la superclase
[Link](); // Error: en la clase A no está definido un método sumar()
}
}

Como B es una subclase de A, es posible asignar subObj a superObj. Sólo el tipo de variable
referencia determina los miembros que se pueden acceder, no el tipo de los objetos a los que se
hace referencia. Por lo tanto, la referencia superObj no puede acceder al miembro sumar(), que sólo
está presente en la clase B.

1.4. EL MODIFICADOR “SUPER”

Al trabajar con herencia, es posible que tanto la superclase como la subclase proporcionen sus
propios constructores, donde cada uno tiene la responsabilidad de inicializar su porción del objeto.

Cuando la superclase y la subclase definen juntas constructores, ambos constructores deben ser
ejecutados. En este caso debe usarse la palabra clave de Java, super, que tiene dos formas
generales. La primera llama un constructor superclase. La segunda es utilizada para acceder a un
miembro de la superclase que ha sido ocultado por un miembro de una subclase.

- Uso de super para llamar constructores de superclase: Una subclase puede llamar al
constructor de la superclase utilizando el modificador super de la siguiente forma:
super (lista_de_parámetros);
Aquí, lista_de_parámetros especifica los parámetros del constructor de la superclase. Si
se utiliza el modificador super(), tiene que ser la primera sentencia ejecutada dentro del
constructor de la subclase.

Cuando una subclase llama a super(), el constructor de la superclase inmediata será


llamado. Así que, super() siempre se refiere a la superclase inmediatamente encima de la
clase que llama. Esto se cumple incluso en una jerarquía multinivel. Cualquier forma del
constructor definida por la superclase, puede ser llamada usando super(). Si se omite la

Curso de Java Standard Edition – J2SE 43


llamada a super(), se ejecutará automáticamente el constructor predeterminado de la
superclase.

//Crea una superclase


class A {
private int i;
private int j;
//Constructor con 2 parámetros
A (int x, int y) {
setIJ ( x, y);
}
//Constructor con 1 parámetro
A (int x) {
setIJ ( x, 1);
}
public void setIJ (int x, int y) {
i = x; j = y;
}
public int getI () {
return i;
}
public int getJ () {
return j;
}
}

//Crea una subclase que extiende o hereda de la clase A


class B extends A {
private int total;
//Constructor sin parámetros
B () {
super (1); //Invoca al constructor con 1 parámetro de la superclase
setTotal (0);
}
//Constructor con 3 parámetros
B (int n1, int n2, int n3) {
super (n1, n2); //Invoca al constructor con 2 parámetros de la superclase
setTotal (n3);
}
public void setTotal (int t) {
total = t;
}

Curso de Java Standard Edition – J2SE 44


public int getTotal () {
return total;
}
public void sumar () {
setTotal ( getI() + getJ() );
}
}

// Clase Ejecutable
public class Acceso {
public static void main (String args[]) {
B obj1 = new B(); // Utiliza el constructor sin parámetros de la subclase y
// el constructor con 1 parámetro de la superclase
B obj2 = new B(2, 3, 0); // Utiliza el constructor con 3 parámetros de la subclase y
// el constructor con 2 parámetros de la superclase
[Link] ();
[Link] (“El total 1 es ” + [Link]());
[Link] ();
[Link] (“El total 2 es ” + [Link]());
}
}

- Uso de super para acceso a miembros de la superclase: La segunda forma de utilizar


super es parecida a la utilización de this, excepto que super siempre se refiere a la
superclase de la subclase en la que se utiliza. Su formato es:
[Link]
Donde miembro puede ser cualquier método o variable de la superclase a la cual se desea
hacer referencia. Esta forma es útil cuando los miembros de la subclase sirven para ocultar
los miembros que tienen el mismo nombre en la superclase y se quiere tener acceso a los
miembros de la superclase.

// Crea una superclase


class A {
private int i;
public void setI (int x) {
i = x;
}
public int getI () {
return i;
}
}

// Crea una subclase que extiende o hereda de la clase A


class B extends A {
private int i;

Curso de Java Standard Edition – J2SE 45


//Constructor con 2 parámetros
B (int n1, int n2) {
[Link] (n1); // setI() de A (superclase)
setI (n2); // setI() de B (subclase)
}
public void setI (int x) {
i = x; // Este setI oculta al setI de la superclase A
}
public int getI () {
return i; // Este getI oculta al getI de la superclase A
}
public void mostrar () {
[Link] (“i de la superclase: ” + [Link]());
[Link] (“i de la subclase: ” + getI());
}
}
// Clase Ejecutable
public class Acceso {
public static void main (String args[]) {
B obj = new B(1, 2);
[Link] ();
}
}

1.5. CREACIÓN DE UNA JERARQUÍA “MULTINIVEL”

Como se mencionó, es perfectamente aceptable usar una subclase como superclase de otra. Por
ejemplo, dadas tres clases llamadas A, B y C. La clase C puede ser una subclase de B, que es una
subclase de A. Cuando este tipo de situación ocurre, cada subclase hereda todas las características
encontradas en todas sus superclases. En este caso, C hereda todos los aspectos de B y A.

Objeto de A

Objeto de B

Objeto de C

Curso de Java Standard Edition – J2SE 46


1.6. ORDEN DE EJECUCIÓN DE LOS CONSTRUCTORES

En una jerarquía de clases, los constructores son llamados en orden de derivación, de superclases a
subclases. Además, como super() tiene que ser la primera sentencia que se ejecuta dentro del
constructor de la subclase, este orden es el mismo tanto si se utiliza super() como si no. Si no se
utiliza super() entonces se ejecuta el constructor por omisión o sin parámetros de cada superclase.
El siguiente ejemplo ilustra el orden de ejecución de los constructores:

// Clase A
class A{
//Constructor por omisión de A
A(){
[Link] (“Construyendo A”);
}
}
// Clase B - subclase de A y superclase de C
class B extends A{
//Constructor por omisión de B
B(){
[Link] (“Construyendo B”);
}
}
//Clase C - subclase de B
class C extends B{
//Constructor por omisión de C
C(){
[Link] (“Construyendo C”);
}
}
public class Acceso{
public static void main (String args[]){
C c = new C();
}
}
La salida del programa es la siguiente:
Construyendo A
Construyendo B
Construyendo C

1.7. SOBRESCRITURA DE MÉTODOS

En una jerarquía de clases, si un método en la subclase tiene la misma fima (los mismos nombres
de métodos, tipos de argumentos, tipo de retorno y excepciones que arroja), que el método en la
superclase, entonces el método en la superclase se dice que fue sobrescrito por el método en la
subclase. Cuando se invoca un método sobrescrito desde la subclase, siempre se refiere al método
definido dentro de la subclase. La versión del método que se encuentra en la superclase está oculto
y puede ser accedido usando la palabra super dentro de la subclase.

En caso de que el método en la superclase y la subclase tengan el mismo nombre pero sus firmas
sean diferentes, entonces los métodos se sobrecargan, más no se sobrescriben; por lo tanto el

Curso de Java Standard Edition – J2SE 47


método de la superclase no está oculto y es accesible directamente desde la subclase, sin usar la
palabra super. Cuando se aplica sobrescritura, tanto para métodos como para variables, no se
puede hacer menos accesible de lo que era inicialmente, desde la superclase. Por ejemplo, si un
método en la superclase tiene acceso public, en la subclase sólo puede aparecer como public. A
continuación, se presenta un cuadro que resume el uso de los modificadores de acceso cuando se
trabaja con sobrescritura:

ACCESO EN
SUBCLASE
SUPERCLASE
private private, package, protected, public
package package, protected, public
protected protected, public
public public

1.8. USO DEL MODIFICADOR “final”

La palabra clave final tiene tres usos: con una variable, con un método y con una clase. Cuando se
usa con una variable, permite crear el equivalente de una constante con nombre. Cuando se usa con
un método, previene la sobrescritura del método. Cuando se usa con una clase, previene que la
clase se herede.

- Uso del modificador final para prevenir sobrescritura: Cuando se desea que un
método no sea sobrescrito, se usa el modificador final en la declaración del método. Al
declarar un método como final en la superclase, no es posible sobrescribirlo en la subclase;
de ocurrir esto, se producirá un error de compilación. El uso del modificador final ayuda a
eliminar la sobrecarga de costo asociado con la llamada del método. Usualmente, el
compilador de Java resuelve la llamada a un método dinámicamente en tiempo de
ejecución; lo que se denomina enlace tardío. Como los métodos finales no pueden
sobrescribirse, una llamada al método final puede ser resuelta en tiempo de compilación; lo
que se denomina enlace temprano.

class A {
private int x, y, w;
public final int sumar () {
setW ( getX() + getY() );
return w;
}
public int getX () {
return x;
}
public int getY () {
return y;
}
public void setW (int n) {
w = n;
}
}

Curso de Java Standard Edition – J2SE 48


class B extends A{
private int total;
public int sumar () {
setTotal ([Link]()); // Error de compilación: método final no puede ser sobrescrito
int c = ( getTotal() + 5 );
return c;
}
public int getTotal () {
return total;
}
public void setTotal (int t) {
total = t;
}
}

- Uso del modificador final para prevenir herencia: El modificador final se utiliza en la
declaración de una clase para evitar que esta se herede. Cuando la clase se declara como
final, Java declara implícitamente todos los métodos de la clase como final. No es posible
declarar una clase abstracta como final, dado que la clase abstracta no está completa por sí
misma y espera que sus subclases proporcionen las implementaciones completas.

final class A{
private int x;
public void setX (int n){
x = n;
}
public int getX (){
return x;
}
}
class B extends A{ // Error de compilación: no se puede heredar A
...
}

Curso de Java Standard Edition – J2SE 49


1.9. EJEMPLO COMPLETO DE HERENCIA Y SOBRESCRITURA DE MÉTODOS

// Superclase Figura
class Figura {
private double dim1;
private double dim2;
// Constructor por omisión
Figura (double a, double b) {
setDim1 (a);
setDim2 (b);
}
// Métodos GET’s y SET’s
public void setDim1 (double x) {
dim1 = x
}
public double getDim1 () {
return dim1;
}
public void setDim2 (double x) {
dim2 = x
}
public double getDim2 () {
return dim2;
}
// Método para calcular el área de la figura (No definido)
public double area () {
[Link] (“El área de la figura no está definida”);
return 0;
}
}
// Clase Rectangulo que extiende a Figura
class Rectángulo extends Figura {
Retangulo (double a, double b) {
super (a, b); // Se inicializa el objeto usando el constructor de la superclase
}
// Sobrescribe el método area para el rectángulo
public double area () {
[Link] (“Dentro del método área para un rectángulo”);
Return getDim1() * getDim2();
}
}

Curso de Java Standard Edition – J2SE 50


// Subclase Triangulo que extiende a Figura
class Triangulo extends Figura {
Triangulo (double a, double b) {
super (a, b); // Se inicializa el objeto usando el constructor de la superclase
}
// Sobrescribe el método área para un triángulo
public double area () {
[Link] (“Dentro del método área para un triángulo”);
return getDim1() * getDim2() / 2
}
}

// Clase Ejecutable
public class EncontrarAreas {
public static void main (String args[]) {
Figura f = new Figura (10, 10);
Rectangulo r = new Rectangulo (5, 5);
Triangulo t = new Triangulo (4, 8);
Figura figRef;
FigRef = r;
[Link] (“El área es: ” + [Link]());
FigRef =tr;
[Link] (“El área es: ” + [Link]());
FigRef = f;
[Link] (“El área es: ” + [Link]());
}
}

La salida de este programa es la siguiente:

Dentro del método área para un rectángulo


El área es: 25
Dentro del método área para un triángulo
El área es: 16
El área de la figura no está definida
El área es: 0

Curso de Java Standard Edition – J2SE 51


2. CLASES ABSTRACTAS

2.1. MODIFICADOR “ABSTRACT”

El modificador abstract puede usarse de dos formas, con una clase y con un método. Cuando una
clase tiene el modificador abstract en su declaración, esta se denomina clase abstracta; lo que
indica que la clase no puede ser instanciada (no se puede crear un objeto de la clase). Cuando el
modificador abstract es usado en la declaración de un método, es llamado método abstracto; en
este caso, el modificador indica que la implementación del método no se proporciona en la clase.
Los métodos abs tractos sólo pueden presentarse dentro de una clase abstracta. Si se incluye
el modificador abstract en la declaración de un método, indica que la clase que herede de esa clase,
tendrá que proporcionar la implementación para este método; si no proporciona la implementación,
entonces esa subclase deberá ser declarada como abstract.

2.2. CLASES Y MÉTODOS ABSTRACTOS

Una clase abstracta sirve para definir el comportamiento genérico de la clase. La clase abstracta
tiene las definiciones de los métodos, que proporcionan el comportamiento de la clase; también
puede implementar algunos de los métodos definidos en la clase, dando una implementación parcial
de su comportamiento.

Una clase abstracta no se puede instanciar, pero si se puede derivar. Tampoco es


posible, declarar constructores abstractos o métodos estáticos abstractos.

La forma general de declarar una clase abstracta es la siguiente:

abstract class X {
// Cuerpo de la clase

}

Las clases abstractas se usan cuando se quiere definir una superclase que declara la estructura de
una abstracción sin proporcionar una implementación completa de cada método. Usualmente,
cuando una superclase es incapaz de brindar una implementación significativa para un método,
pueden aplicarse dos soluciones: la primera, simplemente dar un mensaje que se imprima en la
salida estándar; y la segunda, declarar el método como abstracto.

La forma general de declarar un método abstracto se da a continuación:

abstract tipo nombreMétodo (lista_de_parámetros);

Como es evidente, el cuerpo del método está ausente, lo que significa que la implementación del
método no se proporciona en la clase, y por lo tanto, debe ser implementado por la subclase.
Una clase abstracta puede contener cualquier cantidad de métodos abstractos. Además es posible
que una clase abstracta no tenga ningún método abstracto en ella. Cuando una clase es
declarada como abstracta, no es necesario que la clase contenga métodos abstractos,
pero cuando existe al menos un método abstracto dentro de la clase, esta debe ser
declarada como abstract.

Curso de Java Standard Edition – J2SE 52


2.3 EJEMPLO DE CLASES Y MÉTODOS ABSTRACTOS.

// Superclase Figura
abstract class Figura {
private double dim1;
private double dim2;
// Constructor
Figura (double a, double b) {
setDim1 (a);
setDim2 (b);
}
// Métodos GET’s y SET’s
public void setDim1 (double x) {
dim1 = x;
}
public double getDim1 () {
return dim1;
}
public void setDim2 (double x) {
dim2 = x;
}
public double getDim2 () {
return dim2;
}
// Método para calcular el área de la figura (No implementado)
abstract public double area () {
[Link] (“El área de la figura no está definida”);
return 0;
}
}
// Clase Rectangulo que extiende a Figura
class Rectángulo extends Figura {
Retangulo (double a, double b) {
super (a, b); // Se inicializa el objeto usando el constructor de la superclase
}
// Sobrescribe el método area para el rectángulo
public double area () {
[Link] (“Dentro del método área para un rectángulo”);
Return getDim1() * getDim2();
}
}

Curso de Java Standard Edition – J2SE 53


// Subclase Triangulo que extiende a Figura
class Triangulo extends Figura {
Triangulo (double a, double b) {
super (a, b); // Se inicializa el objeto usando el constructor de la superclase
}
// Sobrescribe el método area para un triángulo
public double area () {
[Link] (“Dentro del método área para un triángulo”);
return getDim1() * getDim2() / 2;
}
}

// Clase Ejecutable
class EncontrarAreas {
public static void main (String args[]) {
//Figura f = new Figura (10, 10); // Esto no es correcto
Rectangulo r = new Rectangulo (5, 5);
Triangulo t = new Triangulo (4, 8);
Figura figRef; // Esto es correcto
FigRef = r;
[Link] (“El área es: ” + [Link]());
FigRef = t;
[Link] (“El área es: ” + [Link]());
}
}

La salida de este programa es la siguiente:


Dentro del método área para un rectángulo
El área es: 25
Dentro del método área para un triángulo
El área es: 16

Curso de Java Standard Edition – J2SE 54


3. INTERFACES

Las interfaces son sintácticamente igual a las clases, pero sin variables de instancia y sin
implementación para los métodos declarados en ella. La palabra clave interface permite especificar
qué es lo que debe hacer la clase, pero no cómo lo hace. Una interfaz puede ser implementada por
cualquier número de clases. Además, una clase puede implementar cualquier número de interfaces.
Una clase, que implementa una interfaz, debe implementar el conjunto completo de
métodos definidos por la interfaz. Las interfaces actúan como sustitutos para implementar la
herencia múltiple.

3.1. DEFINICIÓN DE UNA INTERFAZ

La forma general de una interfaz es:

[acceso] interface NombreInterfaz [extends interfaz] {


tipo nombreVar = valor;
tipo_retorno nombreMetodo (lista_de_parámetros);

}

El acceso es public o no se utiliza. Cuando no se utiliza ningún modificador de acceso, entonces se


aplica el acceso por omisión y la interfaz está sólo disponible para otros miembros del paquete en
que ha sido declarada. Pueden existir variables en la declaración de la interfaz; implícitamente estas
serán de la forma final y static, lo que significa que no podrán ser cambiadas por la clase que las
implemente y además deben ser inicializadas con un valor constante. Todos los métodos declarados
en la interfaz son básicamente métodos abstractos, ya que no puede haber implementación o
cuerpo para ninguno de ellos. Si la interfaz es declarada como pública, entonces todos los métodos
y variables en la interfaz tendrán acceso público.

interface Contestadora {
void guardarMensaje (String mens);
String getMensaje ();
}

3.2. IMPLEMENTACIÓN DE UNA INTERFAZ

Una vez definida una interfaz, puede ser implementada por una o más clases. Para implementar una
interfaz, es necesario incluir la sentencia implements en la definición de la clase y crear los
métodos definidos por la interfaz.

La forma general, de la implementación de una clase, es la siguiente:

acceso class NombreClase [extends Superclase] [implements Interfaz1 [, Interfaz2…] ] {


// Cuerpo de la clase
}

Si una clase implementa más de una interfaz, las interfaces están separadas con una coma. Si una
clase implementa dos interfaces que declaran el mismo método, la clase da sólo una implementación
para el método. Los métodos que implementan una interfaz deben declarase como
públicos y deben corresponder exactamente, en firma, con los métodos definidos en la
interfaz.

Curso de Java Standard Edition – J2SE 55


Ejemplo: El siguiente código tiene la una clase que implementa la interfaz Contestadora:

class Telefono implements Contestadora {


String mensLlamada;
String mensGrabado = “llame luego por favor”;

public void guardarMensaje (String mens) {


[Link] (“Mensaje dejado en llamada:” + mens);
mensLlamada = mens;
}
public String getMensaje () {
[Link] (“Mensaje grabado:” + mensGrabado);
return (mensGrabado);
}

3.3. IMPLEMENTACIÓN PARCIAL

Si una clase incluye una interfaz, pero no implementa todos los métodos definidos por esa interfaz,
entonces esa clase tiene que ser declarada como abstract. Por ejemplo:

abstract class TeleFax implements Contestadora {


String mensGrabado = “llame en 3 horas”;
public String getMensaje () {
[Link] (“Mensaje grabado de TeleFax:” + mensGrabado);
return (mensGrabado);
}
}

Como la clase TeleFax no implementa el método guardarMensaje(String mens) tiene que ser
declarada como abstracta. Cualquier clase que herede de TeleFax, tiene que implementar el
método guardarMensaje(String mens) o ser declarada como abstract.

3.4. VARIABLES EN UNA INTERFAZ

Es posible aplicar las interfaces para importar constantes compartidas en muchas clases, mediante
una interfaz que declara las variables que son inicializadas con valores deseados. La clase que
implementa la interfaz, incluirá automáticamente todos los nombres de variables como constantes.
Si una interfaz no tiene ningún método, entonces cualquier clase que incluye dicha interfaz no se
tiene que preocupar de implementar nada; realmente, es como importar las variables constantes
declaradas en la interfaz como variables final en la clase que la implementa.

interface Constantes {
int A = 0;
int B = 1;
int C = 2;
}
class X implements Constantes {
int determinarConstante () {

Curso de Java Standard Edition – J2SE 56


int ran = (int) ([Link]() * 100);
if (ran < 30) return A;
else if (ran < 60) return B;
else return C;
}
}

class Y implements Constantes {


void evaluarResultado (int res) {
switch (res) {
case A: [Link] (“Número bajo”); break;
case B: [Link] (“Número medio”); break;
case C: [Link] (“Número alto”); break;
}
}
public static void main (String args []) {
X x = new X ();
Y y = new Y ();
[Link] ( [Link] () );
}
}

Ambas clases implementaron la interfaz Constantes, donde A, B y C son los enteros definidos. El
valor de estas variables no puede ser cambiado por la clase que implementa la interfaz, pero los
valores que inicializan estas variables están disponibles para las clases que implementes la interfaz,
como si cada clase las hubiese definido o heredado directamente.

3.5. JERARQUÍA DE INTERFACES

Una interfaz puede heredar de otra interfaz usando la palabra clave extends. Esto es similar a la
herencia de clases. Sólo una interfaz puede heredar de otra interfaz; una clase no puede heredar de
una interfaz. Cuando una clase implementa una interfaz que hereda de otra, tiene que implementar
todos los métodos definidos en la cadena de herencia de la interfaz.

interface A {
void metodo1 ();
void metodo2 ();
}
interface B extends A {
void metodo3 ();
void metodo4 ();
}
interface C extends B {
void metodo4 ();
void metodo6 ();
}
interface D {
void metodo6 ();
}

Curso de Java Standard Edition – J2SE 57


class PruebaInterfaz implements C, D {
public void metodo1 () {
[Link] (“Dentro de metodo1”);
}
public void metodo2 () {
[Link] (“Dentro de metodo2”);
}
public void metodo3 () {
[Link] (“Dentro de metodo3”);
}
public void metodo4 () {
[Link] (“Dentro de metodo4”);
}
public void metodo6 () {
[Link] (“Dentro de metodo6”);
}
}
public class InterfazDemo {
public static void main (String args[]) {
PruebaInterfaz obj = new PruebaInterfaz ();
obj.metodo1 ();
obj.metodo2 ();
obj.metodo3 ();
obj.metodo4 ();
obj.metodo6 ();
}
}

La salida del programa es la siguiente:


Dentro de metodo1
Dentro de metodo2
Dentro de metodo3
Dentro de metodo4
Dentro de metodo6

Tanto la interfaz B como la C declaran el mismo método: metodo4 (); a pesar que la interfaz C
hereda el metodo4 () definido en B. Esto es similar a la sobrescritura de métodos en el caso de
clases. La clase PruebaInterfaz implementa las interfaces C y D. La clase tiene que proporcionar la
implementación para los siguientes métodos: metodo1 (), metodo2 (), metodo3(), metodo4() y
metodo6(); debido a que la interfaz C declara implícitamente todos los métodos anteriores, dado
que hereda de las interfaces A y B. Tanto la interfaz C como la D declaran el método: metodo6(),
pero la clase tiene que dar sólo una implementación del método; en caso contrario, ocurre un error
de compilación. Si la clase dejara de dar implementación para alguno de los métodos, esta
tendría que ser declarada como abstract.

3.6. USO DE INTERFACES COMO REFERENCIAS

Se pueden tener una variable de tipo interfaz, que hagan referencia a una instancia de una clase
que implementa la misma interfaz. Cuando se invoca un método a través de tal referencia, la versión
correcta del método invocado se basará en la instancia actual de la interfaz que es referenciada (se
Curso de Java Standard Edition – J2SE 58
elige dinámicamente, en tiempo de ejecución). El manejo de interfaces a través de referencia, es
similar a la referencia de una superclase, para acceder a una subclase. A continuación se muestra
un programa que ilustra el poder polimórfico de una variable de referencia de interfaz:

interface Contestadora {
void guardarMensaje (String mens);
String getMensaje ();
}

class Telefono implements Contestadora {


String mensLlamada;
String mensGrabado = “llame luego por favor”;

public void guardarMensaje (String mens) {


[Link] (“Mensaje dejado en llamada en Telefono: ” + mens);
mensLlamada = mens;
}
public String getMensaje () {
[Link] (“Mensaje grabado de Telefono:” + mensGrabado + “\n”);
return (mensGrabado);
}
}

class TelefonoCelular implements Contestadora {


String mensLlamada;
String mensGrabado = “llame en 2 horas”;
public void guardarMensaje (String mens) {
[Link] (“Mensaje dejado en llamada en TelefonoCelular: ” + mens);
mensLlamada = mens;
}
public String getMensaje () {
[Link] (“Mensaje grabado de TelefonoCelular: ” + mensGrabado + “\n”);
return (mensGrabado);
}
}

class InterfazDemo {
public static void main (String args[]) {
String mens;
Contestadora con = new Telefono();
mens = [Link]();
[Link] (“Mensaje recibido: ” + mens) ;
[Link](“cita a las 11 am”);

TelefonoCelular t2 = new Telefono2();


con = t2;
mens = [Link]();
[Link] (“Mensaje recibido: ” + mens) ;
[Link](“cita a las 2 pm”);

Curso de Java Standard Edition – J2SE 59


}
}

La salida del programa es la siguiente:


Mensaje grabado en Telefono: llame luego por favor
Mensaje recibido: llame luego por favor
Mensaje dejado en llamada de Telefono: cita a las 11 am

Mensaje grabado de TelefonoCelular: llame en 2 horas


Mensaje recibido: llame en 2 horas
Mensaje dejado en llamada de TelefonoCelular: cita a las 2 pm

Curso de Java Standard Edition – J2SE 60


..
..
..
..
.
TEMA IV: Excepciones

OBJETIVOS:

ƒ Escribir programas en Java, que manipulen los errores a través de las excepciones definidas
en el lenguaje.

ƒ Crear y utilizar en programas Java, excepciones definidas por el mismo, de acuerdo a las
necesidades de cualquier problema.

CONTENIDO:

ƒ Definición de Excepción

ƒ Tipos de excepciones

ƒ Manejo de excepciones

ƒ Jerarquía de excepciones

ƒ Propagación de excepciones

ƒ Sobrescritura de métodos y excepciones

ƒ Definición de excepciones propias

............................
61

Curso de Java Standard Edition – J2SE 61


1. DEFINICIÓN DE EXCEPCIÓN

Una de las verdades fundamentales al escribir programas es la ocurrencia inevitable de errores.


Algunos lenguajes de programación controlan y manejan estos errores de forma manual mezclando
el código de la aplicación con el de verificación y manejo de errores, lo que resultaba en un código
complejo, difícil de leer y de mantener.

Lenguaje C: Visual Basic:


void main() { Private Sub Dividir ()
int a=10; int b=0; Dim a, b As Integer
double res=0; Dim res As Double
if (b) { a=0 b=0 res=0
res = a / b; On Error Goto 110
printf(“El resultado es: %g”, res) res = a / b
} else { print “El resultado es: + CStr(res)
printf(“Error División por 0”); halt(0)
} 110: print “Error División por 0”
} End Sub

Java ofrece una elegante solución a estos problemas con un mecanismo para el manejo de los
errores en tiempo de ejecución, conocida como manipulación de Excepciones. Una excepción es
una condición anormal que ocurre durante la ejecución de un programa e interrumpe el
flujo normal de sus instrucciones. En otras palabras, una excepción es un error en tiempo de
ejecución. Una excepción en Java es un Objeto que describe una condición excepcional, es decir,
un error que se ha producido en un fragmento de código. La gestión de excepciones de Java evita
todos los inconvenientes de la gestión de errores por validaciones y códigos de error y, en el
proceso, lleva a la gestión de errores en tiempo de ejecución al mundo orientada a objetos.

public class ProgramaExcepciones {


public static void main(String [] args) {
int a=10; int b=0;
double res=0;
try {
res = a / b;
MANEJADOR DE
EXCEPCIONES

[Link](“El resultado es: ” + res);


} catch (Exception e) {
[Link](“Error División por 0”);
}
}
}

La ventaja más importante del manejo de excepciones, es que éste automatiza gran parte del
código para manejar aquellos errores en tiempo de ejecución que previamente han sido
determinados. Por ejemplo, en varios lenguajes de programación (como Visual Basic), los códigos de
errores son retornados cuando un método falla, y estos valores se deben revisar manualmente cada
vez que se invoque al método. Esta aproximación es tediosa y propensa a error. El manejo de
excepciones, controla los errores de líneas de flujo, lo que permite definir en un programa un bloque
de código, conocido como manejador de excepciones, que es ejecutado automáticamente
cuando ocurre un error. No es necesario comprobar manualmente el éxito o falla de cada operación
o método específico; si ocurre un error, éste será procesado por el manejador de excepciones.

Curso de Java Standard Edition – J2SE 62


2. TIPOS DE EXCEPCIONES EN JAVA

Las excepciones pueden ser generadas por el intérprete Java o pueden ser generados por el propio
código. Las excepciones generadas por Java están relacionadas con errores fundamentales que
violan las reglas del lenguaje o las restricciones del entorno de ejecución. Las excepciones
generadas manualmente se usan para informar de alguna condición de error al método que lo
invocó.

Todos los tipos de excepciones en Java son subclases de la clase Throwable (lanzable) o de una de
sus subclases. Sólo los objetos de esta clase, o de una de sus subclases, pueden ser lanzados al
sistema en tiempo de ejecución con la cláusula throw; y sólo esta clase o una de sus subclases
puede ser un argumento en una cláusula catch. Throwable contiene una copia de la pila de
llamadas de métodos y un mensaje que describe al objeto lanzado. La clase Throwable se encuentra
en el paqueta [Link]. Las siguientes son subclases de Throwable:

- Error: los objetos de esta clase representan errores fatales en la JVM o fallas de enlace
dinámico. No es normal para un programa típico de Java lanzar Error.

Throwable
Error

LinkageError ThreadDeath VirtualMachineError

ClassCircularityError InternalError

ClassFormatError OutOfMemoryError

ExceptionInitializeErr StackOverflowError

IncompatibleClassCh UnknownError

AbstractMethodError

IllegalAccessError

InstantiantionError

NoSuchFieldError

NoSuchMethodError

NoClassDefFormatErr

UnsatisfiedLinkError

VerifyError

Gráfico 1. Jerarquía de la clase Error

La siguiente tabla describe las clases de error más generales:

ERROR DESCRIPCIÓN
LinkageError Se lanza cuando ocurre un error en tiempo de enlace
ThreadDeath Se lanza cuando la ejecución de un hilo falla
VirtualMachineError Se lanza con un error interno de la Máquina Virtual de Java

Curso de Java Standard Edition – J2SE 63


- Exception: indica que existe algún problema, no necesariamente uno fatal, que puede ser
manejado por un programa razonable. Todos los programas Java probablemente lanzaran y
capturaran Exception pero no Error.

Throwable

Exception

ClassNotFoundException

CloneNotSupportedException

RuntimeException

AritmeticException

ArrayStoreException

IllegalArgumentException

IllegalThreadStateException

NumberFormatException

ClassCastExcepcion

IllegalMonitorStateException

IllegalStateException

IndexOutOfBoundsException

ArrayIndexOutOfBoundsExce

StringIndexOutOfBoundsExce

NegativeArraySizeException

SecurityException

NullPointerException

IllegalAccessException

InstantiationException

InterruptedException

IOException

Gráfico 2. Jerarquía de la clase Excepción

La siguiente tabla describe las clases de excepción más generales:

EXCEPTION DESCRIPCIÓN
Es lanzada, cuando no se consigue un recurso o una clase
ClassNotFoundException
solicitada
CloneNotSupportedException Lanzado cuando se ejecuta el método clone() de la clase Class
RuntimeException Engloba una serie de errores en tiempo de ejecución
IllegalAccessException Engloba los errores de acceso
InstantiationException Cuando ocurre un error en la instanciación de una clase
IOException Se lanza cuando ocurre un error de Entrada/Salida (E/S)

Curso de Java Standard Edition – J2SE 64


3. MANEJO DE EXCEPCIONES EN JAVA

Cuando ocurre un error, se crea un objeto que representa la excepción y se envía al sistema en
tiempo de ejecución. El sistema en tiempo de ejecución busca un manejador de excepciones
apropiado en la pila de llamadas hacia atrás, empezando con el método en el que ocurrió el error. Si
un manejador de excepción es elegido se dice que captura la excepción. Si no se encuentra un
manejador de excepción apropiado, el sistema en tiempo de ejecución y el programa Java terminan.

Ocurre un ERROR
Objeto Excepción
Objeto Excepción
entregado al sistema
creado
en tiempo de ejecución

El sistema en tiempo de
ejecución examina la pila de
llamadas empezando en el
método en que ocurrió el error

¿La Excepción
Manejador de
lanzada es del tipo
del manejador? Excepciones apropiado
Si encontrado

No
Dejar que el manejador
Buscar hacia atrás en capture la excepción
la pila de llamadas

No ¿Buscó en Si Termina el sistema en


toda la pila tiempo de ejecución y el
de llamadas? programa Java

Gráfico 3. Manejo de Excepciones en Java

El manejo de excepciones en Java se realiza mediante cinco palabras claves: try, catch, throw,
throws y finally. Básicamente el funcionamiento es el siguiente:

- Las sentencias del programa que pueden generar una excepción se incluyen dentro del bloque
try.

- El código puede capturar esta excepción, usando cath, y tratarla de manera racional.
- Para generar una excepción se usa throw.

- Para especificar las excepciones que puede lanzar un método se usa throws.

- Cualquier código que se tenga que ejecutar antes de que termine un método se introduce en
un bloque finally.

Curso de Java Standard Edition – J2SE 65


Esta es la forma general de un bloque de código con gestión de excepciones:

try {
// bloque de código
} catch (tipoExcepción e) {
// Código para manejar las excepciones para el tipoExcepción

} finally {
// bloque de código que se ejecutara antes de que termine el try
}

4. REQUERIMIENTO DE CAPTURA O ESPECIFICACIÓN DE JAVA

En Java, es necesario que un método capture o especifique todas las excepciones verificadas que
pueden ser lanzadas dentro del alcance del método. Esto es:

- Capturar: un método puede capturar una excepción proporcionando un manejador


apropiado para ese tipo de excepción.

- Especificar: si un método elige no capturar una excepción debe especificar que puede
lanzarla.

- Excepciones verificadas: son excepciones que el compilador verifica que sean capturadas
o especificadas.

- Alcance del método: las excepciones pueden ser lanzadas directamente usando throw; o
indirectamente por la llamada a otros métodos.

5. JERARQUÍA DE EXCEPCIONES

Se debe capturar primero la excepción más específica, y luego proceder a capturar las excepciones
más generales hasta alcanzar aquella que sea la más genérica.

try {
FileInputStream fis = new FileInputStream(“[Link]”);
} catch (FileNotFoundException fnfe) {

} catch (IOException ioe) {

} catch (Exception e) {

}

6. PROPAGACIÓN DE EXCEPCIONES

En la sintaxis declarativa de los métodos, existe una sección destinada a especificar cuales son las
excepciones que dicho método no manipula en su cuerpo y que puede lanzar a la pila de llamadas.

[acceso] [modif] tipo nombreMetodo([parámetros]) [throws exceptions]

Curso de Java Standard Edition – J2SE 66


Es posible que una excepción no sea capturada en el alcance del método. En tal caso, la excepción
se propagará en la pila de llamadas hasta encontrar un manejador de excepción apropiado.

Gráfico 4. Propagación de Excepciones

Un método sobrescrito en una subclase solo puede lanzar excepciones declaradas en la clase padre
o hijos de las excepciones declaradas en la clase padre.

public class Base {


public void metodo1 () throws IOException {
};
}
public class Derivada extends Base {
public void metodo1 () throws FileNotFoundException {
};
}

7. DEFINIENDO NUESTRAS PROPIAS EXCEPCIONES

Las clases de excepción generalmente tienen constructores pero no datos ni métodos. Todo lo que
hacen es llamar a los constructores de subclase. Por eso nosotros podemos crear nuestras propias
excepciones y para ello creamos una clase que extienda de clase Exception.

public class MiExcepcion extends Exception {


public MiExcepcion () {
super();
}
public MiExcepcion (String s) {
super(s);
}
}

8. EJEMPLO COMPLETO DE UN PROGRAMA JAVA QUE MANEJA EXCEPCIONES

/*
* Ejemplo de un programa Java con manejo de excepciones
* Sumar n números enteros
*/

Curso de Java Standard Edition – J2SE 67


public class SumarEnteros {
public static void main(String args[]) {
int r = 0;
try {
for(int i=0; i<[Link]; i++)
r += [Link](args[i]);
} catch(ArrayIndexOutOfBoundsException e) {
[Link](“Formato: SumarEnteros n1 n2 nN”);
} catch(NumberFormatException e) {
[Link](“Error: Los argumentos deben ser enteros.”);
} finally {
[Link](“El resulado es ” + r);
}
}
}

Curso de Java Standard Edition – J2SE 68


..
..
..
..
.
TEMA V: Entrada/Salida

OBJETIVOS:

ƒ Escribir programas en Java, que utilicen flujos de entrada y salida para interactuar con los
usuarios.

ƒ Crear y utilizar en programas Java, que implementen la persistencia de datos, a través de


los flujos de archivo y de la serialización de objetos.

CONTENIDO:

ƒ Flujos

ƒ Tipos de flujos

ƒ Flujos predefinidos

ƒ Entrada/Salida por consola

ƒ Flujos de archivo

ƒ Serialización de objetos

............................
69

Curso de Java Standard Edition – J2SE 69


Desde el comienzo del curso se han estado utilizando (sin una explicación formal) partes del
Sistema de Entrada/Salida (E/S) de Java, tales como [Link](). En este tema se
estudiará el método de Java para manejar las entradas y salidas desde consola y archivos. Aunque
solo se estudiará una porción del extenso sistema, afortunadamente el mismo es coherente y
consistente, por lo que una vez que se entiendan sus fundamentos, el resto del sistema es fácil de
manejar.

1. FLUJOS (STREAMS)

Los programas Java realizan procesos de E/S a través de flujos. El programa establece una conexión
con un dispositivo físico para leer información de él o para escribir información en él, y la
información se lee o escribe en forma serial.

Un flujo puede ser definido como una entidad lógica que produce o consume información, y
está encadenado a un dispositivo físico por el sistema de E/S de Java. Los flujos pueden
ser dirigidos a cualquier dispositivo de E/S compatible. Todos los flujos se comportan de la misma
manera, aunque los dispositivos físicos reales a los que estén ligados difieran. Así las mismas clases
y métodos de E/S pueden ser aplicadas a cualquier tipo de dispositivo, bien sea bien sea la entrada
o salida estándar, la memoria, un archivo, una conexión de red, etc.

Flujo de Entrada Flujo de Salida

PROGRAMA DATOS DISPOSITIV PROGRAMA DATOS DISPOSITIV


O FÍSICO O FÍSICO

Gráfico 1. Flujos de Entrada/Salida

2. TIPOS DE FLUJOS

El paquete [Link] tiene las clases necesarias para la utilización de flujos en Java. Los flujos pueden
ser clasificados de la siguiente manera:

- De acuerdo con el tipo de dato que utilizan: se pueden clasificar en flujos de


caracteres (manipulan los datos como caracteres Unicode) y flujos de bytes (manipulan los
datos como objetos).

- De acuerdo con el uso que se les dé: se pueden clasificar en flujos consumidores
(obtienen datos de una fuente) y flujos de procesamiento (utilizan funciones para la
conversión, clasificación y filtrado de datos obtenidos de los flujos).

Flujos

De Caracteres De Bytes

Class Reader Class Writer Class InputStream Class OutputStream

Gráfico 2. Clasificación de Flujos en Java

Curso de Java Standard Edition – J2SE 70


Reader Writer

BufferedReader BufferedWriter

LineNumberReader CharArrayWriter

CharArrayReader
OutputStreamWrit
er
InputStreamReader
FileWriter
FileReader
FilterWriter
FilterReader

PipedWriter
PushBackReader

StringWriter
PipedReader

StringReader PrintWriter

Gráfico 3. Jerarquía de clases Reader y Writer

InputStream OutputStream

FileInputStream
FileOutputStream
PipedInputStream
PipedOutputStream
ByteArrayInputStream
FilterOutputStream
StringBuferInputStream

SequenceInputStream DataOutputStream

FilterInputStream PrintStream

DataInputStream
BufferedOutputStre
am
LineNumberInputStrea
PushBackOuputStre
BufferedInputStream am
ObjectOutputStream
PushBackInputStream

ObjectInputStream ByteArayOuputStream

Gráfico 4. Jerarquía de clases InputStream y OutputStream

De las jerarquías de clases de flujos en Java, es importante señalar que las clases que aparecen
sombreadas representan las clases procesadoras (añaden características a la forma de recibir o
enviar los datos de los dispositivos) y las otras son las clases consumidoras (definen de dónde o a
dónde se están enviando o recibiendo los datos, es decir al dispositivo que se conecta en flujo).
La siguiente tabla explica la jerarquía de clases para los flujos de carácter:

Curso de Java Standard Edition – J2SE 71


COMPONENTE PROPÓSITO

Reader y Writer Clases abstractas para leer y escribir flujos de carácter.

Leen o escriben texto desde los flujos de caracteres. Permiten


BufferedReader y BufferedWriter almacenar en un buffer los caracteres, de manera de leer o escribir
eficientemente caracteres, líneas y arreglos

Heredan de Reader. El buffer de caracteres que implementan estas


CharArrayReader y CharArrayWriter
clases sirven como flujo de entrada y salida de caracteres.

Actúan como puente entre los flujos de bytes y los flujos de


InputStreamReader y OutputStreamWriter caracteres. Permiten leer o escribir los bytes y convertirlos en
caracteres de acuerdo a la codificación de caracteres especificada.

Son subclases de InputStreamReader, y nos permiten leer o escribir


FileReader y FileWriter
convenientemente en los archivos de caracteres.

Son clases abstractas que heredan de la clase Reader y Writer.


FilterReader y FilterWriter
Permiten leer o escribir flujos de caracteres filtrados.

Es una subclase de FilterReader, y es una clase lectora de flujos de


PushBackReader
caracteres. Nos permite colocar los caracteres en el flujo.

Son subclases de Reader y Writer. Se usan para encauzar los flujos


PipedReader y PipedWriter
de entrada y salida de caracteres.

Son subclases de Reader y Writer. Permiten ller o escribir un flujo de


StringReader y StringWriter
caracteres. La fuente del flujo debe ser una cadena

Hereda de BufferedReader. Es un flujo de entrada de caracteres que


se guarda en un buffer y permite llevar un registro de los números de
LineNumberReader
líneas. Identifica el fin de la línea usando un cambio de líneas “\n” o
un retorno de carro “\r”.

Hereda de Writer. Permite imprimir en un flujo de salida de texto, las


representaciones del objeto que se está formateando. PrintWriter
PrintWriter implementa todas las versiones del método print que están
disponibles en PrintStream. Esta clase no puede ser usada para bytes
puros de datos (raw data).

Tabla 1. Jerarquía de clases para Flujos de Caracter

La siguiente tabla explica la jerarquía de clases para los flujos de carácter:

COMPONENTE PROPÓSITO

InputStream y OutputStream Son clases abstractas que permiten leer bytes de datos.

Son subclases de InputStream y OutputStream, que leen o escriben


FileInputStream y FileOutputStream
contenido en un archivo en la forma de bytes.

Es una subclase de InputStream y OutputStream, lee o escribe bytes


PipedInputstream y
de datos a través de una tubería de comunicación y los
PipedOutputStream
PipedXXXStream son el extremo de envío o recepción de la tubería.

Son subclases de InputStream y Outputstream, y posee un buffer


ByteArrayInputStream y interno que guarda los bytes que pueden ser leídos o escritos en el
ByteArrayOutputStream flujo. Tienen un contador interno que permite guardar un registro del
siguiente byte a ser proporcionado para la lectura o escritura.

Curso de Java Standard Edition – J2SE 72


COMPONENTE PROPÓSITO

Es una subclase de InputStream. Permite que una aplicación cree un


flujo en una cadena y lea su contenido en la forma de bytes. Esta
StringBufferInputStream
clase solo usa los ocho bits bajos usados para representar un carácter.
Está actualmente en desuso (deprecated).

Es una subclase de InputStream. Representa la concatenación lógica


de otros flujos de entrada. Se inicia con una colección de flujos de
SequenceInputStream entrada y lee el primer flujo hasta alcanzar el fin de la entrada, luego
toma el siguiente flujo de entrada y así sucesivamente, hasta que
alcanza el fin del último flujo de entrada contenido.

Son subclases de InputStream y OutputStream. Toman la data de


FilterInputStream y FilterOutputStream
algún otro flujo de entrada/salida y la manipula según se requiera.

Son subclases de FilterInputStream y FilterOutputStream. Permiten


que una aplicación lea o escriba los tipos de datos primitivos de Java
DataInputStream y DataOutputstream
desde el flujo de entrada/salida asociado, independientemente del tipo
de máquina.

Son subclases de FilterInputStream y FilterOutputStream. Permiten a


BufferedInputStream y los flujos de entrada y salida almacenar en un buiffer los bytes de
BufferedOutputStream data ya leídos o escritos, con lo cual no necesita efectuar llamadas al
sistema subyacente por cada byte, leído o escrito.

Ofrecen la funcionalidad para colocar nuevamente (unread) un byte


especifico de dato de un flujo de entrada o salida. Es útil cuando los
PushBackInputStream y bytes de data que son leídos o escritos están delimitados por un byte
PushBackOutputStream específico. El último byte que es leído o escrito será regresado al flujo,
de manera que la siguiente operación leerá o escribirá nuevamente
ese byte.

Es una subclase de FilterInputStream. Esta clase es un flujo de


entrada filtrado con una funcionalidad adicional para guardar un
LineNumberInputStream
registro del número de línea actual. Identifica el fin de la línea usando
un cambio de líneas “\n” o un retorno de carro “\r”.

Es una subclase de FilterOutputStream, permite que otro flujo base de


PrintStream salida imprima convenientemente la representación de varios tipos de
valores de datos.

Permiten la serialización deserialización de datos primitivos u objetos


ObjectInputStream y ObjectOutputStream
para ser leídos o escritos en un programa.

Tabla 2. Jerarquía de clases para Flujos de Bytes

3. FLUJOS PREDEFINIDOS

En el paquete [Link] se encuentra la clase System que encapsula algunos aspectos del entorno
de ejecución. Esta clase tiene 3 variables de clase públicas que están asociadas con flujos:

- out: se refiere al flujo de salida estándar que, por omisión, es la consola ([Link])
- in: se refiere a la entrada estándar que, por omisión, es el teclado ([Link])
- err: se refiere al error estándar que, por omisión, también es la consola ([Link])

Curso de Java Standard Edition – J2SE 73


4. ENTRADA/SALIDA POR CONSOLA

En Java, la entrada por consola se efectúa leyendo bytes de un flujo de entrada. Estos bytes se
pueden leer en varios objetos, como pueden ser caracteres y cadenas. El método de entrada de mas
bajo nivel es read(). Este método está definido en la clase InputStream. Cada vez que se llama al
método read() lee un único byte del flujo de entrada y lo devuelve como un valor entero.
El método devuelve -1 cuando encuentra el final del flujo.

int read() throws IOException

El siguiente programa muestra el funcionamiento del método read(), donde leen caracteres de la
entrada estándar hasta que el usuario pulsa la letra “s”.

import [Link].*;
public class LecturaPorConsolaCaracter {
public static void main (String args[]) throws IOException {
char caract;
[Link](“Introduzca caracteres, ‘s’ para salir: ”);
do {
caract = (char) [Link]( );
[Link] (caract);
} while (caract != ‘s’);
}
}

[Link] es, por omisión, un flujo con búfer, es decir, no se pasa ninguna entrada al programa
hasta que se pulsa la tecla ENTER. Esto hace que el método read() no sea muy útil para entradas
por consola interactivas, ya que una de las acciones de entrada más comunes que realiza un
programa es la lectura de una cadena completa del teclado y el método read() solo permite leer
carácter por carácter. Para facilitar la lectura por consola de una cadena entera con una sola
instrucción se utiliza el método readLine() de la clase BufferedReader. Este método lee todos los
caracteres hasta encontrar “\n” o “\r” y devuelve un String (sin incluir estos caracteres).

final String readLine() throws IOException

El siguiente programa muestra el funcionamiento del método readLine(), donde lee una cadena de
caracteres de la entrada estándar.

import [Link].*;
public class LecturaPorConsolaCadena {
public static void main (String args[]) throws IOException {
String str;
BufferedReader br = new BufferedReader (new InputStreamReader([Link]));
[Link] (“Escriba una cadena de caracteres sin espacio y presione ENTER.”);
s = [Link] ();
[Link] (“Ud. escribió: ” + str);
}
}

Curso de Java Standard Edition – J2SE 74


En Java, la salida por consola se realiza con la ayuda de los métodos print () y println() que están
definidos en la clase PrintStream que es el tipo del objeto referenciado por [Link]. los
métodos print() y println(), permiten escribir por consola cualquier tipo de datos simple, ya que
están sobrecargados para ello. Como la clase PrintStream es un flujo de salida derivado de
OutputStream, también implementa el método de bajo nivel write ().

void write(int valorByte)

El siguiente programa utiliza el método write() para imprimir el carácter “A” seguido de un carácter
de línea nueva.

public class Escribir {


public static void main(String args[]) {
int a = new Integer(20);
Double dou = 15.5;
String cad = new String(“El valor de pi es: ”);
[Link] (a);
[Link] (“Un valor double es ” + dou + “\n”);
[Link] (cad + [Link])
}
}
Cuando los métodos print () o println () son invocados y se les pasa por parámetro un Object,
automáticamente se imprime el resultado de ejecutar el método toString() de la clase a la que
pertenece el parámetro referenciado.

5. FLUJOS DE ARCHIVOS

Para utilizar los archivos en Java, se pueden emplear tanto los flujos de carácter como los flujos de
byte y ambos funcionan de manera similar, sólo varían en la forma como el lenguaje se comunica
con el dispositivo físico internamente. Para comprender esto, hay que tener en cuenta que los
archivos para Java solo son secuencias de bytes, denominados archivos secuenciales; razón por
la cual no hace diferencia si el archivo es de texto o es un archivo estructurado. Por otro lado
también existen los archivos de acceso aleatorio que son tratados de forma diferente.

5.1. ARCHIVOS SECUENCIALES

Las clases FileReader y FileWriter crean flujos de caracteres asociados a los archivos
secuenciales. Mientras que las las clases FileInputStream y FileOutputStream crean flujos de
bytes asociados a los archivos. Para abrir un archivo, simplemente es necesario crear un objeto de
estas clases, especificando el nombre del archivo en el constructor. Para cerrar el archivo, se invoca
al método close(), definido en todas las clases.
o FileReader(String rutaArchivo) throws FileNotFoundException // Abrir para Lectura
o FileInputStream(String rutaArchivo) throws FileNotFoundException // Abrir para Lectura
o FileWriter(String rutaArchivo) throws IOException // Abrir para escritura
o FileOutputStream(String rutaArchivo) throws IOException // Abrir para Escritura

Curso de Java Standard Edition – J2SE 75


El siguiente programa utiliza el método read() de la clase FileReader y FileInputStream para leer y
mostrar el contenido de un archivo.

import [Link].*; import [Link].*;


public class LeerArchivoSecuencial{ public class LeerArchivoSecuencial {
public static void main(String args []) { public static void main(String args []) {
try { try {
FileReader fr = null; FileInputStream fis = null;
try { try {
fr = new FileReader(“[Link]”); fis=new FileInputStream (“[Link]”);
} catch (FileNotFoundException e) { } catch (FileNotFoundException fnf) {
[Link](“Archivo no encontrado”); [Link](“Archivo no encontrado”);
} }
int caract = [Link](); int num = [Link]();
while (caract != -1) { while (num != -1) {
[Link]((char)caract); [Link](num);
caract = [Link](); num = [Link]();
} }
[Link](); [Link]();
} catch(IOException ioe) { } catch(IOException ioe) {
[Link](); [Link]();
} }
} }
} }

El siguiente programa utiliza el método write() de la clase FileWriter y FileOutputStream para


escribir una serie de bytes en un archivo.

import [Link].*; import [Link].*;


public class EscribirArchivoSecuencial{ public class EscribirArchivoSecuencial {
public static void main(String args[]) { public static void main(String args[]) {
try { try {
FileWriter fw=null; FileOutputStream fos=null;
try { try {
fw= new FileWriter(“[Link]”); fos = new FileOutputStream(“[Link]”);
} catch (IOException ioe) { } catch (IOException ioe) {
[Link](“Error al abrir el archivo [Link](“Error al abrir el archivo para
para salida…”); salida…”);
} }
for (int i=0;i<10;i++) for (int i=0;i<10;i++)
[Link](“Número ” + i + “.”); [Link](i);
[Link](); [Link]();
} catch(IOException ioe){ } catch(IOException ioe){
[Link](“Error al tratar el archivo [Link](“Error al tratar el archivo para
para salida:” + [Link] ()); salida:” + [Link] ());
} }
} }
} }

Curso de Java Standard Edition – J2SE 76


5.2. ARCHIVOS DE ACCESO ALEATORIO

El paquete [Link] declara una clase RandomAccessFile, que sirve para leer o escribir en archivos
de forma aleatoria. Los argumentos de la clase instanciada deciden si el objeto será utilizado para
leer o escribir. Para abrir un archivo, simplemente es necesario crear un objeto de ésta clases,
especificando el nombre del archivo en el constructor y el modo de apertura.
- RandomAccessFile(String rutaArchivo, “r”) // Abrir para Lectura
- RandomAccessFile(String rutaArchivo, “rw”) // Abrir para Lecto-Escritura

RandomAccessFile soporta el concepto de un puntero de archivo para indicar la ubicación actual en


el archivo. En el momento de creación del archivo, el puntero de archivo se establece en 0,
indicando el inicio del archivo. Luego el número de bytes que son leídos o escritos mueve el puntero
de archivo. RandomAccessFile dispone de los siguientes métodos para manipular el puntero de
archivo:

- int skipBytes(int nroBytes): Mueve el puntero de archivo hacia delante el número de


bytes especificado.

- void seek(long pos): Posiciona el puntero de archivo antes del byte especificado.

- long getFilePointer(): Permite obtener la ubicación actual del puntero de archivo.

En caso de que el fin de archivo se alcance antes de leer el número de bytes especificado, entonces
se lanza una EOFExcepcion y en caso de no leer o escribir un byte, entonces se lanza una
IOExcepcion.

El siguiente programa ejemplifica el uso de la clase RandomAccessFile para leer y mostrar el


contenido de un archivo.

import [Link].*; import [Link].*;


public class LeerArchivoAleatorio { public class EscribirArchivoAleatorio {
public static void main(String args []) { public static void main(String args []) {
try { try {
RandomAccessFile ra = null; RandomAccessFile ra = null;
try { try {
ra = new RandomAccessFile(“[Link]”,”r”); ra = new RandomAccessFile(“[Link]”,”rw”);
} catch (FileNotFoundException e) { } catch (FileNotFoundException fnf) {
[Link](“Archivo no encontrado”); [Link](“Archivo no encontrado”);
} }
for(int i=0;i<[Link]();i++){ for(int i=0;i<10;i++) {
[Link](i); seek(i);
[Link]([Link]()); [Link](i);
} }
[Link](); [Link]();
} catch(IOException ioe) { } catch(IOException ioe) {
[Link](); [Link]();
} }
} }
} }

Curso de Java Standard Edition – J2SE 77


6. SERIALIZACIÓN DE OBJETOS

La serialización de objetos es el proceso por el cual el estado de un objeto es transformado en un


flujo de bytes. Se aplica en RMI (comunicación entre objetos vía conectores de red) y persistencia
ligera (forma de guardar sólo el estado del objeto).

Para escribir una clase cuyos objetos sean serializables en Java, la clase tiene que implementar la
interfaz [Link]. Serializable es una interfaz sin métodos que permite identificar la
semántica de la serialización.

interface Serializable {
}

El proceso de escribir o almacenar el estado de un objeto se conoce como serialización.


El proceso de leer o recuperar el estado de un objeto se conoce como deserialización.

La clase del objeto, la firma de la clase y los valores de los campos no transient y no static de un
objeto se escriben mediante el mecanismo de serialización por omisión. Cualquier referencia a otros
objetos en campos no transient y no static causara que los objetos referenciados se escriban.

El siguiente programa permite almacenar objetos en un archivo.

import [Link].*;
public class Serializar {
public static void main(String args[]) {
FileOutputStream fos = new FileOutputStream(“c:\[Link]”);
ObjectOutputStream oos = new ObjectOutputStream(fos);
[Link](1243); // Escribe un objeto de Integer
[Link](“Ejemplo”); // Escribe cualquier tipo Object
[Link](); [Link]();
}
}

El siguiente programa muestra como son recuperados (deserialización) los objetos escritos en el
archivo [Link]:

import [Link].*;
public class Deserializar {
public static void main(String args[]) {
FileInputStream fis = new FileInputStream(“c:\[Link]”);
ObjectInputStream ois = new ObjectInputStream(fis);
[Link]([Link]);
[Link]((String)[Link]());
[Link](); [Link]();
}
}

Si una superclase de una clase no es serializable, entonces la subclase puede tomar la


responsabilidad de encargarse de serializar las variables public, protected, y friendly (cuando es
accesible) de la superclase y restaurarlos. Esto es posible cuando la superclase tiene un constructor
que no toma ningún parámetro para inicializar su estado y es accesible a subclase. Durante la

Curso de Java Standard Edition – J2SE 78


deserialización, los campos de la superclase son inicializados usando este constructor. Los campos
de la subclase serializable son recuperados de ObjectInputStream.

La interfaz [Link] extiende de Serializable. No tiene comportamientos


automáticos, todo esta en manos del programador.

interface Externalizable extends Serializable {


public void writeExternal(ObjectInput)
public void readExternal(ObjectOutput)
}

Al transformarse un objeto, el método writeExternal() es responsable de todo lo que se hace. Sólo


se guardará lo que se indique dentro de este método.

El método readExternal() debe ser capaz de recuperar lo guardado por writeExternal(). La


lectura debe ser en el mismo orden que la escritura. Es importante saber que antes de llamar a este
método se llama al constructor de la clase.

Curso de Java Standard Edition – J2SE 79


..
..
..
..
.
TEMA VI: Tecnología de Acceso a Datos

OBJETIVOS:

ƒ Describir las tecnologías de acceso a bases de datos de Java.

ƒ Escribir programas en Java que sean capaces de interactuar con una base de datos.

CONTENIDO:

ƒ Manejo de Base de Datos en Java

ƒ La API JDBC

ƒ Acceso a base de datos

ƒ Clases de soporte JDBC

............................
80
Curso de Java Standard Edition – J2SE 80
Hasta los momentos hemos visto como hace Java para crear objetos, para implementar el principio
de Herencia, el concepto de clases abstractas e interfaces. Aprendimos sobre paquetes y sobre el
manejo de excepciones. Además, entendimos el simple pero poderoso mecanismo para manejar las
entradas y salidas. En este tema, veremos como la información guardada en una base de datos
puede ser recuperada a través de un programa en Java, y aprenderá a escribir información en una
base de datos desde un programa hecho en Java.

1. MANEJO DE BASES DE DATOS EN JAVA

Tradicionalmente en la programación para Bases de Datos, las aplicaciones se enfrentan a docenas


de manejadores de bases de datos disponibles, y cada uno de ellos se comunica con tu aplicación en
su propio lenguaje. Si la aplicación necesita comunicarse con un nuevo motor de bases de datos,
entonces se tiene que aprender una nueva forma de comunicación. Para los programadores Java,
sin embargo, esto no representa un problema, ya que Java brinda la capacidad de “escribir una vez,
compilar una vez y correr donde sea”, lo que implica que la programación para bases de datos sea
bastante sencilla.

En la actualidad, se emplean, principalmente tres tipos de bases de datos: Bases de Datos


relacionales, Bases de Datos relacional-objeto, Bases de Datos orientadas a objetos. Java
proporciona conectividad a todos los tipos de Bases de Datos, a través de su “Conectividad a
Bases de Datos Java (Java Data Base Connectivity - JDBC) API”.

Ya que no se puede definir un denominador común para el almacenamiento y acceso de datos entre
los tipos de bases de datos, la especificación JDBC autoriza requerimientos no específicos en el
DBMS (Data Base Management System) subyacente. En lugar de colocar requerimientos de cómo
se debe implementar el DBMS para poderlo usar (ODBC), la especificación JDBC de Java, coloca
todos sus requerimientos en la implementación específica del mismo.

Al escribir programas en Java que se comuniquen con una base de datos, se requiere:

o Una base de datos (relacional, orientada a objetos, etc.).


o Interfaz Java (a través de API JDBC).
o Simple conocimiento de sentencias SQL.

2. PASOS INVOLUCRADOS EN EL ACCESO A BASES DE DATOS

Cuando hablamos de acceso a una base de datos, las siguientes operaciones son las más
importantes a través de un programa Java: el programa debe ser capaz de leer desde una base de
datos y el programa debe ser capaz de escribir información a una base de datos.

En Java, hay una serie de pasos para acceder la información que se encuentra en una base de datos
y estos son:

- Se debe cargar en la memoria un controlador que habilitará la conexión entre el programa


Java y el sistema de base de datos (DBMS).
- A través de este controlador, se debe establecer una conexión a la base de datos.
- Una vez establecida la conexión y usándola, se pueden ejecutar las sentencias SQL.
- Finalmente, se debe cerrar la conexión.

Escribir programas en Java que se conecten con una base de datos y trabajen, es tan simple como
implementar estos cuatro pasos.

Curso de Java Standard Edition – J2SE 81


3. EL API JDBC

El API de JDBC proporciona una forma universal para acceder a datos desde el lenguaje de
programación de Java. Usando el API JDBC, usted puede acceder virtualmente cualquier fuente de
datos, desde las bases de datos relacional a las hojas de cálculo y archivos planos. La tecnología de
JDBC también proporciona una base común sobre la cual pueden construirse herramientas e
interfaces.

Para trabajar con las empresas líderes en el campo de las bases de datos, Sun Microsystems,
desarrolló una sencilla API para acceso a bases de datos JDBC. En el proceso de desarrollo, se
establecieron tres puntos principales:

- JDBC debe ser una API que soporte SQL.


- JDBC debe construirse sobre la experiencia de trabajar con otras API para bases de datos.
- El trabajo con JDBC debe ser sencillo.

JDBC es un API que soporta SQL, debido a que permite construir sentencias SQL embebidas
dentro de las llamadas a la API JDBC de Java. JDBC permite comunicar sin problemas el mundo de
los manejadores de bases de datos con el de la programación Java, ya que se construyó en base las
experiencias anteriores en el manejo de bases de datos, como por ejemplo el uso de la tecnología
ODBC de Microsoft. Y finalmente, el trabajar con JDBC se hace sencillo, porque consiste
básicamente en hacer uso de funciones predefinidas y que se comportan igual para cualquier
manejador de base de datos.

3.1. LA ESTRUCTURA DE JDBC

JDBC logra establecer, para las interfaces Java, implementaciones diferentes para cada manejador.
El grupo de clases, que implementan las interfaces JDBC para un motor de base de datos particular
es llamado un Driver JDBC. En la elaboración de una aplicación de bases de datos, no interesa
conocer como están implementadas estas clases, ya que JDBC oculta la implementación específica
para cada base de datos, y solo se deben emplear los métodos definidos en las diferentes interfaces
JDBC.

Gráfico 1. La arquitectura JDBC

La arquitectura JDBC, establece que “una aplicación Java trabaja con cualquier bases de
datos, empleando los métodos definidos en las interfaces JDBC las cuales son
específicas para cada manejador”.

Curso de Java Standard Edition – J2SE 82


Gráfico 2. Driver JDBC

La figura anterior, muestra como una aplicación usa JDBC para comunicarse con una o más bases
de datos sin conocer los detalles concernientes a la implementación de “Driver” específico para dicha
base de datos.

3.2. CLASES E INTERFACES BÁSICAS DE JDBC

El API JDBC se encuentra en dos paquetes:

- El paquete de [Link], contiene las funcionalidades del lado cliente.


- El paquete [Link], agrega las capacidades del lado de servidor.

En esta API, existen clases e interfaces básicas que se encuentran en cualquier programación de
base de datos que involucre JDBC y estas son:

<<Interfaz>>
DriverManager Registers
Driver
0..n

Provides
0..n
<<Interfaz>> <<Interfaz>> Retirves <<Interfaz>>
Connection Statement ResultSet
1 Creates 0..n 1 0..n

Provides
Provides

<<Interfaz>> <<Interfaz>> <<Interfaz>>


DatabaseMetaData PreparedStatement ResultSetMetaData

<<Interfaz>>
CallableStatement

Gráfico 3. Jerarquía de clases JDBC


La relación que existe entre las clases e interfaces del API JDBC, está en que:
- El DriverManager es usado por la aplicación para obtener conexiones a la base de datos,
ya que éste carga el controlador requerido directamente.
- Internamente la interfaz Driver crea las conexiones.

Curso de Java Standard Edition – J2SE 83


- La aplicación usa el objeto Connection para obtener objetos Statement y ejecutar
sentencias SQL.
- El resultado de las sentencias, es decir de los objetos Statement se reciben en la aplicación
mediante los objetos ResultSet.
- Los datos del objeto ResultSet son utilizados en la aplicación.
- El objeto Connection agrega al objeto DatabaseMetaData.
- El DatabaseMetaData, tiene la información acerca de la base de datos para un
determinado objeto Connection.
- El objeto ResultSet agrega al objeto ResultSetMetaData.
- El ResultSetMetaData, tiene la información acerca de los datos que contiene un
ResultSet.
- El PreparedStatement hereda de Statement, y representa una extensión a la
funcionalidad que poseen los objetos Statement.
- El CallableStatement hereda de PreparedStatement, y esta permite hacer invocaciones a
Procedimientos almacenados en la base de datos.

Todas las clases con acceso a Base de Datos en la API JDBC, lanzan SQLException, la cual
necesita ser capturada y manejada.

4. ACCESO A BASES DE DATOS

Como hemos visto, en el trabajo con bases de datos en Java existen cuatro pasos básicos: cargar el
controlador, realizar la conexión, realizar las peticiones sobre la base de datos y por último se debe
cerrar la conexión. Ahora, veremos como hacer cada una de estas tareas.

4.1. CARGAR EL DRIVER

Los fabricantes de sistemas de bases de datos proveen sus propios controladores para poder
conectarse con la base de datos. Para cargar el controlador, necesitamos usar el método forName
especificado en la clase Class con el nombre del controlador como argumento. Los objetos de la
clase Class son construidos automáticamente por la JVM cuando se cargan las clases. Para cargar un
controlador de base de datos, incluimos la siguiente sentencia antes de hacer cualquier acceso a la
base de datos.

[Link](“nombre del controlador”);

El nombre del controlador es específico a cada base de datos. Veamos como cargar el controlador
para diversos manejadores de bases de datos:

- Microsoft Access y SQL Server: [Link](“[Link]”);


- IBM DB2 Universal DataBase: [Link](“[Link].DB2Driver”);
- MySQL: [Link](“[Link]”);

Al invocar a [Link], automáticamente se crea una instancia de la clase Driver y la registra


con DriverManager. No se está creando una instancia explícita del controlador, sino que una vez que
el controlador esté cargado, este estará disponible para hacer la conexión a un DBMS. Cuando el
Driver indicado en el método forName() es inválido se arroja la excepción
ClassNotFoundExcepcion.

Curso de Java Standard Edition – J2SE 84


4.2. REALIZAR LA CONEXIÓN

Las aplicaciones usan la clase DriverManager para establecer la conexión con el DBMS. La clase
DriverManager es responsable de buscar o rastrear las diferentes implementaciones JDBC que
pueden existir en un sistema. La aplicación requiere que DriverManager le dé una conexión de base
de datos.

La clase DriverManager provee un método llamado getConnection(), el cual tiene tres argumentos:
- Un URL de base de datos.
- Identificación del usuario.
- Clave de usuario.

[Link](databaseURL, user, password);

Un URL de base de datos es un simple Localizador Uniforme de Recursos (Uniform Resources


Locator) estándar de Internet. El URL consiste de tres partes, separadas por dos puntos:

protocol:<subprotocol>:<subname>

La fuente de datos de JDBC es el protocol. El subprotocol es específico a una implementación


JDBC. Normalmente contiene el nombre del DBMS y la versión. El subname es específico al DBMS y
le dice al controlador a dónde necesita conectarse la aplicación, es decir representa un DSN
(Nombre de la Fuente de Datos - Data Source Name) de la base de datos. Por ejemplo:

jdbc:odbc:Sample
donde,

- jdbc, es el protocol
- odbc, es el subprotocol
- Sample, es el subname

Ahora veamos como conectarnos a los manejadores de bases de datos:

ƒ Microsoft Access
[Link](“[Link]”);
Connection conn;
String databaseURL = “jdbc:odbc:Sample”;
conn = [Link](databaseURL,””,””);

ƒ Microsoft SQL Server


[Link](“[Link]”);
Connection conn;
String databaseURL = “jdbc:odbc:Sample”;
conn = [Link](databaseURL,”user1”,”xyz”);

ƒ IBM DB2 Universal DataBase


[Link](“[Link].DB2Driver”);
Connection conn;
String databaseURL = “jdbc:db2://Sample:8000”;
String user = “admin”;

Curso de Java Standard Edition – J2SE 85


String password = “sql”;
conn = [Link](databaseURL,user,password);

ƒ MySQL Server
[Link](“[Link]”);
Connection conn;
String databaseURL = "jdbc:mysql://localhost:3306/test”;
String user = “root”;
String password = “sql”;
conn = [Link](databaseURL,user,password);

Un objeto Connection es una simple sesión de base de datos. Podemos tener cualquier número de
objetos Connection en un programa.

4.3. EJECUTAR PETICIONES

Habiendo establecido una conexión a base de datos, usando el método getConnecticon() de la clase
DriverManager, se está en posición de ejecutar peticiones sobre esa base de datos. Dichas
peticiones, se refieren a ejecutar sentencias SQL sobre la base de datos, bien sean sentencias:

- DDL (Data Define Language: CREATE, ALTER, DROP)


- DCL (Data Control Language: GRANT, REMOVE)
- DML (Data Manage Language: INSERT, UPDATE, DELETE)
- DQL (Data Query Language: SELECT)

Para ejecutar las sentencias SQL mencionadas anteriormente es necesario hacer uso de objetos
Statement, PreparedStatement y ResultSet.

- Objetos Statement: La interfaz Statement provee métodos para hacer llamadas a las
sentencias SQL. En este caso, es indiferente a que DBMS esté conectado los métodos
funcionan igual para todos, ya que una simple interfaz es provista por el JDBC para acceder a
la información de cualquier base de datos.

La interfaz Statement provee los métodos:


o excecuteUpdate(): para ejecutar sentencias DML. Este método retorna el número de
filas afectadas por la sentencia ejecutada, bien sea INSERT, UPDATE o DELETE.
o executeQuery(): para ejecutar sentencias DQL. Este método devuelve los resultados
(filas) para las sentencias SELECT.

Para ejecutar sentencias SQL, primero se declara un objeto Satatement y a través del
objeto Connection creamos una sentencia usando el método createStatement().
[Link](“[Link]”);
Connection conn;
String databaseURL = “jdbc:odbc:Sample”;
conn = [Link](databaseURL,”user1”,”xyz”);
Statement sentencia = null;
int filas = 0;
sentencia = [Link]();
nro= [Link](“INSERT INTO Tab VALUES(‘Enero’,10)”);

Curso de Java Standard Edition – J2SE 86


- Objetos PreparedStatement: La especificación JDBC provee una clase adicional, derivada
de la clase Statement para facilitar al programador la realización de programas sotisficados
de base de datos.

Observemos el siguiente fragmento de código:

//Código para conectarse a la base de datos


Statement sentencia = null;
int nro = 0;
String mes = “ENERO”;
int dia = 10;
sentencia = [Link]();
nro= [Link](“INSERT INTO Tabla VALUES(” + mes+ “, ” + dia + “)”);

Podemos ver que, en la sentencia SQL se han empleado variables en lugar de constantes
como valores; de igual forma, también se pueden colocar expresiones dentro de una
sentencia que va a ser ejecutada por un objeto Statement.

nro= [Link](“INSERT INTO Tabla VALUES(” + mes+ “, ” + dia + “)”);

El API JDBC de Java, permite crear una sentencia SQL una sola vez y aplicarla cada que
queramos ejecutarla. La clase PreparedStatement, permite construir las sentencias SQL
requeridas una vez y ejecutarlas cualquier número de veces en la aplicación. Un
PreparedStatement es una llamada a una base de datos precompilada que requiere que los
parámetros sean definidos.

Cuando se crea un PreparedStatement, la sentencia SQL es dada como argumento. La


sentencia SQL debe ser enviada al DBMS inmediatamente donde es compilada una vez. De
este modo, el objeto PreparedStatement contiene una sentencia SQL precompilada, lo que lo
diferencia de los objetos Statement, en los que la sentencia se compila cada vez que se
ejecuta. En los PrepareStatement, los valores de la sentencia SQL se dan cada vez que la
aplicamos y siempre podrán tener valores diferentes.

Para ejecutar sentencias SQL usando el objeto Statement cada vez, damos el nombre de la
columna y los valores. Cuando usamos el objeto PreparedStatement no podemos especificar
los valores cuando se crea el objeto, ya que en el momento de construcción de la sentencia
los valores no serán conocidos. Sólo proveemos los poseedores de lugares usando el símbolo
? y después se substituirá cada símbolo con el valor deseado.

Veamos el siguiente fragmento de código para entender como funcionan los


PreparedStatement.

//Código para conectarse a la base de datos


PreparedStatement sentencia = null;
String SQL = “INSERT INTO Tab (mesFecha, diaFecha) VALUES (?,?)”;
String mes = “FEBRERO”;
int dia = 20;
sentencia = [Link](SQL);
[Link](1 , mes);
Curso de Java Standard Edition – J2SE 87
[Link](2 , dia);
[Link]();

Usamos el método prepareStatement() en lugar de createStatement(). En el fragmento


anterior, la sentencia SQL INSERT es el argumento del método prepareStatement(). Las
únicas diferencias notables aquí son los símbolos ?, que representan los parámetros de
entrada, en lugar de los valores reales. Los valores reales se dan cuando se ejecuta la
sentencia SQL. Los métodos setXXX() de la clase PreparedStatement enlazan los
parámetros de entrada con los valores. De esta manera “FEBRERO”será colocado en
mesFecha y 20 guardado en diaFecha. Es de hacer notar que en este caso se ejecuta el
método execute(), en vez de excecuteUpdate(); pero si se tratase de una sentencia SELECT
se ejecutaría igualmente el método executeQuery().

La principal diferencia entre crear un objeto Satatement y objeto PrepareStatement está en la


forma como se aplican las sentencias SQL.

- Objetos ResultSet: El objeto Statement, como vimos anteriormente, también puede


retornar los resultados de una sentencia DQL (SELECT). El método de Statement,
excecuteQuery() retorna los resultados de una sentencia SELECT. La sentencia puede
retornar una o más filas, las cuales se capturan en un ResultSet.

[Link](“[Link]”);
Connection conn;
String databaseURL = “jdbc:odbc:Sample”;
conn = [Link](databaseURL,”user1”,”xyz”);
Statement sentencia = null;
ResultSet resultados = null;
sentencia = [Link]();
resultados = [Link](“SELECT mes, dia FROM Tab”);

Como el método executeQuery(), puede devolver varias filas, puede ser necesario
desplazarnos dentro de ese conjunto de filas. Para ello, emplearemos el método next()
provisto en la clase ResultSet. Este método nos permite iterar a través del ResultSet. Dicho
método retorna true, si existe un registro activo o false en caso contrario. Ees de hacer
notar que para obtener la primera fila del ResultSet, es necesario emplear el método next()
ya que el mismo no está posicionado en ningún registro cuando se obtienen los datos.

while([Link]())
[Link](“\n Deslazándose en el cursor…”);
[Link](“\n No hay más datos en el cursor…”);

En el uso anterior del objeto ResultSet no se ha recuperado ninguna información de las filas
resultado, solo nos desplazamos por ellas. Para recuperar la información de las filas, se
utilizan los métodos getXXX() de la clase ResultSet. Cada campo de información disponible
en una fila es de algún tipo de dato. Necesitaremos hacer una correspondencia entre los
tipos de datos del DBMS con los métodos getXXX(). Hay un número de métodos getXXX
disponibles en la clase ResultSet, algunos de los más comunes son:

o getInt(), getShort(), getLong(), getFloat(), getByte()


o getString(), getDate(), getTime()

Curso de Java Standard Edition – J2SE 88


Todos son métodos sobrecargados que aceptan un entero o una cadena como argumento. El
argumento entero es el número de la columna en la sentencia y el argumento de cadena es
el nombre de la columna dada en la tabla. Cuando se especifica un número de columna como
argumento, se hace corresponder en el mismo orden como las columnas fueron especificadas
en la sentencia SELECT.

while([Link]()) {
[Link]([Link](1));
[Link]([Link](“dia”));
[Link]([Link](“mes”));
[Link]([Link](2));
}

- Soporte de Cursores: El API JDBC provee soporte limitado de cursores (ResultSet). Permite
que una aplicación obtenga un cursor asociado con el resultado de un Query a través del
método executeQuery(); pero el movimiento del cursor ocurre, por omisión, sólo con
dirección hacia delante. Por lo que, es necesario activar la navegabilidad del cursor.

Para que un ResultSet sea scrollable (navegable), hay que pasarle dos argumentos, bien
sea al createStatement() o al método prepareStatement(). Los argumentos a pasar son:

o Tipo de resultado: El tipo de resultado, puede ser cualquiera de las variables de


clase definidas en ResultSet:

MÉTODO DESCRIPCIÓN

TYPE_FORWARD_ONLY El cursor se puede mover solo hacia delante.

El objeto ResultSet es navegable, pero no


TYPE_SCROLL_INSENSITIVE
sensitivo para hacer cambios por otros.

El objeto ResultSet es navegable, pero


TYPE_SCROLL_SENSITIVE
sensitivo a hacer cambios por otros.

Tabla 1. Tipos de resultado

o Concurrencia de resultado: La concurrencia de resultado, puede ser cualquiera


de las variables de clase definidas en ResultSet:

TIPO SIGNIFICADO

CONCUR_READ_ONLY El objeto ResultSet no puede ser actualizado

CONCUR_UPDATABLE El ResultSet puede ser actualizado.

Tabla 2. Concurrencia de resultado

Una vez que el objeto ResultSet se hace “scrollable”, entonces el cursor se puede mover y
apunta a filas específicas, donde se puede actualizar, borrar, etc. Algunos de los métodos
disponibles en ResultSet para el movimiento del cursor se listan a continuación:

Curso de Java Standard Edition – J2SE 89


MÉTODO RETORNO DESCRIPCIÓN
next() boolean Para moverse a la siguiente fila del resultado
previous() boolean Para moverse a la fila anterior
first() boolean Para moverse a la primera fila del ResultSet
last() boolean Para moverse a la última fila del ResultSet
getRow() int Retorna el número de la fila actual
Absolute(int row) boolean Ir a una fila especifica del ResultSet
Inserta una fila en el Objeto ResultSet y en la
insertRow() void
base de datos.
deleteRow(int row) void Elimina una fila del ResultSet.
Tabla 3. Métodos para ResultSet “scrollable”

[Link](); [Link](“\n Última fila…”);


[Link](); [Link](“\n Primera fila…”);
[Link](); [Link](“\n Segunda fila…”);
[Link](); [Link](“\n Primera fila…”);
[Link](“\n La fila actual en el cursor es: “ + [Link]());

La información de las filas de un ResultSet, pueden ser actualizadas utilizando los métodos
updateXXX() de la clase ResultSet., donde XXX corresponde a un tipo de dato presente el
DBMS. Algunos de los métodos updateXXX más comunes son:

o updateInt(columna, int dato), updateShort(columna, short dato)


o updateLong(columna, long dato), updateFloat(columna, float dato)
o updateByte(columna, byte dato), updateString(columna, String dato)
o updateDate(columna, Date dato), updateTime(columna, Time dato)

Todos son métodos que trabajan sobre la fila actual. Estos métodos están sobrecargados y
aceptan un entero o una cadena como argumento para representar la columna. Si el
argumento es entero, indica el número de la columna en la sentencia, pero si el argumento
es cadena, representa el nombre de la columna dada en la tabla.

[Link](1,”Marzo”);
[Link](“dia”,18);
[Link](“mes”,”Abril”);
[Link](2,19);

4.4. CERRAR LA CONEXIÓN

Como hemos visto la conexión a la base de datos se hace a través de la clase DriverManager, la cual
le da a la aplicación un objeto Connection que representa la conexión. De ese objeto Connection, se
pueden obtener muchos objetos Statement y ResultSet para manipular la información de la base de
datos.

Al terminar de trabajar con una base de datos, es buena práctica de programación cerrar los objetos
Connection, Statement y ResultSet que se tengan asociados a la misma, para de esta manera liberar

Curso de Java Standard Edition – J2SE 90


el recurso. Cuando se cierra un objeto Connection, los objetos Statement y ResultSet dependientes
de éste, también se cierran automáticamente. Esto se realiza a través del método close.

[Link](); // Donde res es un objeto ResultSet


[Link](); // Donde stmt es un objeto Statement o PrepareStatement
[Link](); // Donde Conn es un objeto Connection

5. CLASES DE SOPORTE JDBC

Existen otras clases e interfaces de soporte provistas por JDBC para ayudar a la funcionalidad del
API JDBC. Todas estas clases se definen en el paquete [Link].

5.1. SQLEXCEPTION
Extiende de la clase [Link], esta clase provee más información relacionada a errores
de la base de datos. Usamos esta clase ampliamente en todos los programas Java que utilicen JDBC.
Esta clase incluye información acerca de:

- La cadena SQLState, que describe el error ocurrido.


- El código de error específico del proveedor de base de datos, que es normalmente un
número que puede ser encontrado en la documentación de la base de datos.

Esta excepción debe ser obligatoriamente capturada y manejada por todo programa que emplee las
funcionalidades de la API JDBC de Java.

5.2. DATE, TIME, TIMESTAMP

Todas estas clases heredan de la clase [Link]. Ellas extienden para proveer niveles de
granularidad a la información ya existente en la clase Date. Son necesarias para proveer
compatibilidad con los campos tipo fecha de los manejadores de bases de datos.
5.3. TYPES

La clase [Link], define constantes para identificar tipos genéricos SQL, llamados tipos
JDBC. Esta es una clase abstracta. LA misma no añade funcionalidades a los métodos ya definidos
en la clase Object. Algunas variables de clase, que esta clase contiene son:

- ARRAY
- BIT
- BINARY
- CHAR
- CLOB
- DATE
- INTEGER
- NUMERIC
- REAL
- VARCHAR

Curso de Java Standard Edition – J2SE 91


6. EJEMPLO COMPLETO DE UN PROGRAMA CON JDBC

El siguiente es un programa que ilustra como es el proceso de acceso a Bases de Datos utilizando la
API JDBC. Este programa se conecta con una base de datos en MySQL.

/**
* Programa Base de Datos
* @date: 26/09/2005
* @author: Ronel J. Rivas R.
*/

package database;

import [Link].*;
import [Link].*;

public class JExampleDB {


Connection conn;
Statement stmt;
PreparedStatement prep;
ResultSet res;

public JExampleDB() {
super();
}
public void cerrarConexion() throws SQLException {
[Link]();
}
public void consultarTabla() throws SQLException {
// Crear la sentencia SQL
stmt = [Link]();
String SQL = "SELECT * FROM Ejemplo";
res = [Link](SQL);
// Mostrar el resultado por pantalla
while ([Link]()) {
[Link]([Link](1)+" - ");
[Link]([Link]("mes"));
}
// Liberar los recursos
[Link](); [Link]();
}
public void crearConexion(String URL, String user, String passw) throws SQLException {
conn = [Link](URL, user, passw);
}

Curso de Java Standard Edition – J2SE 92


public int crearTabla() throws SQLException {
// Crear la sentencia SQL
stmt = [Link]();
String SQL = "CREATE TABLE Ejemplo (DIA INTEGER CONSTRAINT clave PRIMARY KEY, MES TEXT)";
int nro = [Link](SQL);
// Liberar el recurso
[Link]();
return nro;
}
public int insertarStatement(int miDia, String miMes) throws SQLException {
// Crear la sentencia SQL
stmt = [Link]();
String SQL = "INSERT INTO Ejemplo VALUES(" + [Link](miDia) + ",'" + miMes + "')";
int nro = [Link](SQL);
// Liberar el recurso
[Link]();
return nro;
}
public int insertarPreparedStatement(int miDia, String miMes) throws SQLException {
// Preparar la sentencia SQL
String SQL = "INSERT INTO Ejemplo (dia,mes) VALUES(?,?)";
prep = [Link](SQL);
[Link](1, miDia);
[Link](2, miMes);
// Ejecutar la sentencia
int nro = [Link]();
// Liberar los recursos
[Link]();
return nro;
}
public static void main([Link][] args) {
JExampleDB appDB = new JExampleDB();
try {
// (1) Cargar el driver para Microsoft Access
[Link]("[Link]");

// (2) Crear la conexión


String databaseURL = "jdbc:mysql://localhost:3306/test ";
String user = "root";
String password = "sql";
[Link](databaseURL, user, password);

// (3) Ejecutar peticiones


[Link]();

Curso de Java Standard Edition – J2SE 93


[Link](1, "Enero");
[Link](2, "Febrero");
[Link]();

// (4) Cerrar la conexión


[Link]();

} catch (ClassNotFoundException e) {
[Link]("ERROR: No se encuentra el Driver para el DBMS...");
} catch (SQLException e) {
[Link]("ERROR: No se pudo ejecutar la sentencia...");
}
}
}

Curso de Java Standard Edition – J2SE 94


..
..
..
..
.
TEMA VII: Interfaces Gráficas

OBJETIVOS:

ƒ Describir las tecnologías para la creación de interfaces gráficas de usuario en Java.

ƒ Escribir programas Java que presenten GUI (Interfaces Gráficas de Usuario), empleando la
tecnología SWING.

CONTENIDO:

ƒ Fundamentos de las interfaces gráficas

ƒ Construcción de interfaces gráficas en Java

ƒ Administradores de diseño

ƒ Manejo de eventos

............................
95
Curso de Java Standard Edition – J2SE 95
El objetivo de este tema es introducir los aspectos básicos de diseño y construcción de una interfaz
gráfica de usuario (GUI – Graphical User Interface) y presentar cómo se proporciona el
funcionamiento de dicha interfaz. Con este propósito se presenta el modelo de objetos de los
componentes gráficos y la programación basada o dirigida por eventos.

1. FUNDAMENTOS DE LAS INTERFACES GRÁFICAS

Hasta el momento las aplicaciones creadas sólo han presentado y leído información textual para
realizar la interacción con el usuario (aplicaciones de consola o en modo texto). El lenguaje de
programación Java proporciona distintos paquetes con bibliotecas de clases que implementan los
elementos gráficos y posibilitan la creación de interfaces gráficas de una forma sencilla. Este
conjunto de paquetes se denomina Java Foundation Classes (JFC). La JFC o Clases
Fundamentales de Java, proporcionan una rica colección de clases de interfaz de usuario.

Las JFC son un grupo de APIs usadas para desarrollar la interfaz gráfica de usuario y estas son:
o Abstract Windows Toolkit (AWT): es el principal conjunto de herramientas usado por
Java para crear interfaces de usuario. Proporciona la base sobre la que descansa el resto de
la construcción del JFC. El propósito principal de AWT es soportar ventanas de Applet.
o API 2D: proporciona gráficos de 2 dimensiones mejorados, texto y capacidades de
imágenes para programas Java, a través de extensiones a AWT. Este amplio paquete de
presentación soporta arte de líneas, texto e imágenes, para desarrollar interfaces de usuario
ricas, programas de dibujo y editores de imágenes.
o Swing: es el conjunto de componentes más ligeros construidos sobre AWT. Swing
proporciona reemplazos ligeros para los componentes pesados de AWT, en adición de una
multitud de componentes adicionales de los que carece AWT. Swing también dispone de
una infraestructura notable para implementar interfaces gráficas de usuario como los
componentes de aspecto (Look and Feel) de diferentes plataformas.
o Accesibilidad: el JFC contiene numerosas herramientas de accesibilidad, que trabajan
junto con el API de accesibilidad.

Es de hacer notar, que en el curso se estudiaran sólo los componentes Swing y sus
componentes gráficos más frecuentes, así como breves ejemplos de su uso.

1.1. CREACIÓN DE UNA INTERFAZ GRÁFICA

Los pasos básicos para la creación de una interfaz gráfica de usuario son los siguientes:
o El diseño y composición de la apariencia de la interfaz gráfica de la aplicación.
Esto implica la elección de una ventana principal (contenedor) en la que se van a incluir el
resto de los elementos gráficos de interacción (componentes). El diseño se completa con la
elección del resto de los componentes gráficos (botones, etiquetas, menús, etc.) que se
añaden a la ventana principal, su disposición y la forma en que van a interactuar.
o Creación de componentes. Significa escribir el código que crea los componentes y la
apariencia de la interfaz.
o Manejo de eventos. Esto es escribir el código que proporciona el comportamiento de
dicha interfaz como respuesta a las interacciones de los usuarios. Cada una de las acciones
del usuario sobre la interfaz (Ejemplo: hacer clic sobre un botón), se traduce en la creación
de un evento en Java. Por tanto hay que proporcionar los manejadores de eventos para
responder a las interacciones de los usuarios.
o Visualización. Una vez visualizada la interfaz, la aplicación queda a espera de las
interacciones del usuario que provocarán la ejecución de los manejadores de eventos.

Curso de Java Standard Edition – J2SE 96


1.2. LOS ELEMENTOS DE UNA INTERFAZ GRÁFICA

Cómo se ha visto en los temas anteriores, en Java prácticamente todas las cosas son objetos.
Esta circunstancia sigue siendo válida en la creación de interfaces gráficas. Las ventanas son
objetos, todos los componentes gráficos de interacción contenidos en una ventana son objetos y
como resultado de las acciones del usuario se generan eventos que también son objetos. En
Java una interfaz gráfica se construye componiendo distintos objetos que
implementan elementos gráficos de interacción (botones, campos de texto, etiquetas,
etc.).

La creación de un componente gráfico supone la instanciación o una especialización de una de


las clases estándar proporcionadas por el lenguaje. Por omisión, los objetos de estas clases
tienen la particularidad de que saben como mostrarse a sí mismos en la pantalla. Además, los
componentes gráficos como cualquier otro objeto, tienen unas características y un
comportamiento que viene dado por sus atributos y métodos.

Finalmente, en Java las interfaces gráficas están compuestas básicamente por tres elementos:

o Componentes gráficos: jerarquía de clases que implementan los componentes


gráficos disponibles para una interfaz.
o Administradores de Diseño: la jerarquía de clases que gestionan la apariencia
del diseño la interfaz gráfica.
o Listeners o Manejadores de Eventos: jerarquía de clases de eventos que
representan las interacciones de los usuarios con los componentes gráficos y la
forma como son manejados.

2. COMPONENTES GRÁFICOS - SWING

Swing es un conjunto de bibliotecas de clases que implementan los elementos o componentes


gráficos para la creación de interfaces gráficas de usuario. Swing posee la característica
fundamental, de que casi todos sus componentes están codificados completamente en Java, de
modo que su comportamiento es el mismo para todas las plataformas.

Swing, en comparación con las otras tecnologías para la creación de interfaces gráficas, presenta
diversas ventajas y funcionalidades, entre las que cabe destacar las siguientes:

o Los componentes Swing son JavaBeans. Los componentes son unidades autocontenidas
y reusables. Los componentes pueden ser manipulados visualmente usando herramientas de
construcción para aplicaciones visuales. La tecnología de componentes se incorporan a la
plataforma Java a través del concepto de JavaBean. Las características que distinguen a un
JavaBean de una simple clase Java son: Introspección (todas sus variables son privadas),
persistencia (permiten guardar y restaurar su estado - Serialización), personalización (se
configuran visualmente) y manejo de eventos (utilizan los eventos para comunicarse con otros
objetos). Esto permite que los componentes Swing sean fácilmente integrados en
herramientas de diseño de componentes.

o Nuevos componentes y nuevas funcionalidades. Swing incorpora clases para crear


cuadros de diálogo estándar, añadir bordes sofisticados a los componentes, visualizar tablas y
árboles, manipular texto con formato, etc., así como también permite cualquier tipo de
anidamiento o inclusión de un componente dentro de otro, características que no estaban
disponibles en AWT.

Curso de Java Standard Edition – J2SE 97


o Aspecto y comportamiento configurable. Las aplicaciones pueden tener el aspecto y el
comportamiento que el programador desee y no el que fija la plataforma en la que se
ejecutan. Por ejemplo, en Windows además de botones con el mismo aspecto que las del
sistema operativo se pueden crear botones con aspecto metálico o con apariencia Mac. Esto
se denomina en inglés puggable Look and Feel, y significa que Swing contiene
implementaciones estándares de aspecto para los sistemas operativos más populares, lo que
permite a un programa ser ejecutado sin modificación en cualquier tipo de computadora y
siempre verse y sentirse como un programa escrito específicamente para el sistema operativo
en el que se está ejecutando. A la vez, también se puede implementar un programa para
siempre verse igual, sin importar sobre qué sistema operativo se ejecute.

o Arquitectura Modelo-Vista-Controlador (MVC). Esta es quizás la característica más


importante de Swing. En MVC un elemento tiene tres partes: un modelo que gestiona los
datos, una vista que gestiona cómo se muestran esos datos y un controlador que determina
qué modificaciones hay que hacer cuando se interacciona con el elemento. En Swing se utiliza
una adaptación de esta arquitectura, de modo que la vista y el controlador se agrupan en el
componente, pero el modelo se mantiene separado.

CAMBIO
Evento
COMPONENTE

VISTA ACTUALIZACIÓN
MODELO
(Clases Entidad)
CONTROLADOR
(Listener) ACTUALIZACIÓN

CAMBIO

Gráfico 1. Modelo MVC de Swing

Por ejemplo, como los modelos gestionan y almacenan los datos existe la posibilidad de
compartir un mismo modelo entre varios componentes. Cada uno de los componentes puede
modificar el modelo y dicha modificación se reflejará de forma automática en el resto de los
componentes que comparten dicho modelo.

CAMBIO CAMBIO

Evento ACTUALIZACIÓN Evento


VISTA ACTUALIZACIÓN VISTA
MODELO
JCombo

Atributo: Nombre Atributo: Nombre


(Clases Persona)
JList

CONTROLADOR ACTUALIZACIÓN CONTROLADOR


ACTUALIZACIÓN
(ActionPerform) (ActionEvent)

CAMBIO CAMBIO

Gráfico 2. Modelo MVC de Swing entre componentes

o Accesibilidad. Todos los componentes Swing son compatibles con los dispositivos de ayuda
para personas discapacitadas y permiten utilizar interfaces alternativas, tales como braille y
sintetizadores de voz.

El hecho de que el conjunto de herramientas de componentes Swing esté construido en la


arquitectura MVC y con aspectos y comportamientos configurables, lo hacen más complejo que las
herramientas de interfaz de usuario tradicionales, como la utilizada en visual Basic o Delphi. Sin
embargo, cuando la arquitectura de Swing es entendida, los beneficios son mayores que el esfuerzo
extra requerido para aprender y usar sus capacidades.

Curso de Java Standard Edition – J2SE 98


2.1. JERARQUÍA Y TIPOS DE COMPONENTES GRÁFICOS

Como Swing presenta una gran cantidad de clases gráficas no es posible ni presentarlas todas ni
describirlas de forma completa. Se trabajará con las clases más utilizadas, estructuradas por
grupos, y sus métodos más importantes. Las clases gráficas se presentan estructuradas en los
siguientes grandes grupos: clases básicas, contendores (contenedores de alto nivel e
intermedios) y componentes atómicos.

o CLASES BÁSICAS: proporcionan el soporte y las funcionalidades básicas para el resto de los
componentes. La raíz de todos los elementos gráficos en Java es la clase abstracta
[Link] y su subclase [Link]. La clase
[Link], es la clase base para prácticamente todos los componentes
Swing. A continuación se describen las clase básicas:

o [Link]: esta clase abstracta define la funcionalidad básica de todos


los componentes gráficos en Java. Como la presentación gráfica es responsabilidad
de cada uno de los componentes, en esta clase se definen distintos métodos
relacionados con los efectos visuales y con su respuesta a acciones.
[Link], proporciona un gran número de métodos de utilidad, los
cuales se describen brevemente los más utilizados:

MÉTODO FUNCIONALIDAD
void paint(gGraphics)
void repaint() Dibujo y actualización del componente en la pantalla.
void update(Graphics)
boolean isVisible()
Comprueba o establece si el componente es visible
void setVisible(true)
boolean isEnabled() Permite conocer si un componente está activado y
void setEnabled() activarlo o desactivarlo
Point getLocation()
Point getLocationOnScreen() Devuelve o establece la posición del componente
void setLocation(Point) respecto al componente padre o respecto a la pantalla
void setLocation(int, int)
Dimension getSize()
void setSize(int, int)
Obtiene o establece el tamaño de un componente, en
void setSize(Dimension)
píxeles o como un objeto Dimension
int getWidth()
int getHeight()
Obtiene la alineación del componente. Las constantes
float getAligmentX() correspondientes son:
float getAligmentY() CENTER_ALIGMENT, LEFT_ALIGMENT, RIGHT_ALIGMENT,
TOP_ALIGMENT Y BOTTOM_ALIGMENT
Color getForeground()
Color getBackground() Obtiene o establece el color de fondo o de primer
void setForeground(Color) plano del componente
void setBackground(Color)
Container getParent() Obtiene el contenedor padre del componente
String getName() Obtiene o establece el nombre del componente según
void setName(String) la cadena proporcionada

Curso de Java Standard Edition – J2SE 99


o [Link]: esta clase abstracta implementa un contenedor genérico y
proporciona sus funcionalidades básicas. Un contenedor es un objeto que permite
agrupar uno o más componentes de forma que se puedan tratar como una unidad.
Proporciona métodos para añadir y eliminar componentes o para definir el tipo de
presentación que se realiza de los componentes en la pantalla (Layout Managers).
Los contenedores mantienen una lista de los objetos que contienen y por omisión
los objetos aparecen en el orden en que se han añadido, la cual será utilizada por
los Layout Managers. Container proporciona los siguientes métodos:

MÉTODO FUNCIONALIDAD
void add(Component) Añade un componente en el contenedor, por omisión
void add(Component, int) al final de la lista salvo que se indique un índice.
Component getComponentAt(int,int) Obtiene el componente que contiene un determinado
Component getComponentAt(Point) punto (x,y)
Component [] getComponents() Obtiene todos los componentes del contenedor
void remove(Component) Elimina un componente, dado su identificador o por
void remove(int) su posición en la lista de componentes (o para el
void removeAll() primer componente), o todos los componentes.
void setLayout(LayoutManager) Establece u obtiene el administrador de diseño que
LayoutManager getLayout() utiliza el contenedor.

o [Link]: es la clase base de casi todos los componentes de


interacción que incorpora Swing, excepto los contenedores de alto nivel. Es una
especialización de Conteiner, de modo que prácticamente todos los componentes
Swing se pueden anidar unos dentro de otros. Proporciona muchas de las
funcionalidades básicas de los contenedores intermedios y los componentes
atómicos de Swing, tales como la gestión de bordes sofisticados, la inclusión de
ayudas contextuales, soporte para la presentación en pantalla, o la mejora de la
visualización gráfica (mediante un búfer doble). Component proporciona los
siguientes métodos:

MÉTODO FUNCIONALIDAD
void setBorder(Border) Establece u obtiene el borde que muestra un
Border getBorder() componente alrededor de sus límites.
Establece si un componente es opaco o no
void setOpaque(boolean)
(transparente).
Establece el texto a mostrar como pista o ayuda
contextual del componente que se muestra en una
void setToolTipText(String)
ventana emergente cuando el ratón se detiene sobre
un objeto particular de la pantalla.

void paintComponent(Graphics) Dibuja el componente. Es necesario rescribirlo para


implementar un dibujo personalizado. Solicita que se
void repaint(Rectangle) redibuje un área especifica del componente

void setPreferredSize(Dimension) Establece las recomendaciones de tamaño preferido,


mínimo y máximo para un componente. Estos datos
void setMinimunSize(Dimension)
sólo son recomendaciones y pueden ser ignorados por
void setMaximunSize(Dimension) el Layout Manager.
void setAligmentX(float)
Establece la alineación del componente
void setAligmentX(float)

Curso de Java Standard Edition – J2SE 100


o CONTENEDORES: un contenedor es tipo especial de componente que está formado por uno
o más componentes (o por otros contenedores). La particularidad principal que aportan es
que todos los componentes agrupados dentro de un contenedor se pueden tratar como
una única entidad. Los contendores en Java están representados por la clase
[Link]. Existen dos tipos de contenedores: de alto nivel e intermedios.

ƒ CONTENEDORES DE ALTO NIVEL: los contenedores de alto nivel proporcionan la estructura


y funcionalidad básica de una ventana, así como el espacio para que se muestren el
resto de los componentes que están contenidos dentro de ella y que conforman la
interfaz de usuario. En Swing los contenedores de alto nivel son especializaciones de la
clase [Link].

[Link]

[Link]

[Link] [Link] [Link]

[Link] [Link]

Gráfico 3. Jerarquía de clases de los contenedores de alto nivel

A continuación se describen los contenedores de alto nivel:

o [Link]: esta encapsula un objeto genérico ventana, sin borde ni barra


de menús, que proporciona las funcionalidades básicas a todas las ventanas. Son las
especializaciones de esta clase las que permiten crear las ventanas principales de la
aplicación y dan soporte a los cuadros de diálogo con el usuario.

MÉTODO FUNCIONALIDAD
Ajusta el tamaño de la ventana según el tamaño
void pack()
preferido y disposición de sus componentes.
void toFront()
Coloca la ventana delante o detrás de otras ventanas.
void toBack()
Destruye la ventana así como sus componentes y
void dispose()
libera los recursos asignados a ella.
boolean isShowing() Obtiene si la ventana es visible.
void show() Hace que la ventana sea visible.

o [Link]: se emplea para crear la ventana principal de la aplicación.


Es una subclase de [Link], que a su vez es una especialización de
[Link]. Es una ventana con marco que incluye los controles habituales de
control (cerrar, minimizar y maximizar). Tiene un panel raíz superior (JRootPane)
que gestiona el interior de la ventana. En este panel raíz están incluidos, el panel
de contenido (siempre presente) y, si existe, la barra de menús (JMenuBar). Los
componentes gráficos no se añaden al JFrame directamente sino a su panel de
contenido.

Curso de Java Standard Edition – J2SE 101


A continuación se describen sus principales métodos:

MÉTODO FUNCIONALIDAD
JFrame() Constructores que crean una ventana, inicialmente oculta y a
JFrame(String) la que se le puede asignar un título.
String getTitle()
Obtiene o establece el titulo de la ventana.
void setTitle(String)
void setResizable(boolean)
Establece o determina si la ventana puede cambiar de tamaño.
booleann isResizable()
JRootPane createRootPane()
Crea, obtiene o establece el panel raíz de la ventana. Este
JRootPane getRootPane()
panel gestiona el panel de contenido y la barra de menús.
void setRootPane(JRootPane)
Container getContentPane() Obtiene o establece el panel de contenido de la ventana.
void setContentPane(Container) Contiene a todos los componentes gráficos de la ventana.
JMenuBar getMenuBar()
Obtiene o establece la barra de menús de la ventana.
void setMenuBar(JMenuBar)
Obtiene o establece el comportamiento de la ventana cuando
int getDefaultCloseOperation() el usuario trata de cerrarla. El parámetro debe ser una de las
void setDefaultCloseOperation(int) constantes:JFrame.DO_NOTHING_ON_CLOSE,
JFrame.HIDE_ON_CLOSE ó JFrame.DISPOSE_ON_CLOSE.

A continuación se incluye el código de creación de una ventana principal de una


aplicación, con una etiqueta:

package interfacesGraficas;

import [Link].*;

public class EjemploJFrame extends JFrame {


public EjemploJFrame(){
// AGREGAR LOS COMPONENETES A LA VENTANA
JLabel etiqueta = new JLabel(“Ventana JFrame”); // Crea el componente
getContentPane().add(etiqueta); // Agrega el componente

// ESTABLECER PROPIEDADES GENERALES DE LA VENTANA


setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setTitle(“Ejemplo de JFrame”);
setSize(300,200);
}
public static void main(String[] args) {
EjemploJFrame ventana;
ventana = new EjemploJFrame(); // Crea el objeto ventana
[Link](true); // Muestra la ventana
}
}

Gráfico 4. Ejemplo de ventana JFrame

Curso de Java Standard Edition – J2SE 102


o [Link]: es la base raíz de las ventanas secundarias que
implementan cuadros de diálogo Swing. Se denominan ventanas secundarias porque
dependen de una ventana principal y si la ventana principal se cierra, se minimiza o
se maximiza, las ventanas secundarias realizan la misma operación de forma
automática. Al igual que JFrame, incorpora un panel raíz, con sus componentes
panel de contenido y menús. Estas ventanas pueden ser modales o no. JDialog
provee los mismos métodos de JFrame y agrega los siguientes:

MÉTODO FUNCIONALIDAD
JDialog(JFrame) Constructores en los que se indica la ventana
JDialog(JFrame, boolean) principal (JFrame), si es modal o no y el titulo.
JDialog(JFrame, String) Existen los mismos constructores en donde la
JDialog(JFrame, boolean, String) ventana principal es un JDialog.

Establece la posición de la ventana en relación al


void setLocationRelatiiveTo(Component)
componente indicado.

A continuación se incluye el código de creación de una ventana emergente a una


ventana de una aplicación, con una etiqueta:
package interfacesGraficas;

import [Link].*;

public class EjemploJDialog extends JFrame {


public EjemploJDialog(){
// Agregar los componentes a la ventana
JLabel etiqueta = new JLabel(“Ventana JFrame”); // Crea el componente
getContentPane().add(etiqueta); // Agrega el componente
// Establecer propiedades generales de la ventana
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setTitle(“Ejemplo de JDialog”);
setSize(300,200);
//CREAR LA VENTANA EMERGENTE
JDialog ventanaEmergente;
ventanaEmergente = new JDialog(this); // Crea la ventana emergente
[Link](JDialog.DISPOSE_ON_CLOSE);
[Link](“Ventana Emergente”);
[Link](150,150);
[Link](true); // Muestra la ventana
}
public static void main(String[] args) {
EjemploJDialog ventana = new EjemploJDialog(); // Crea el objeto ventana
[Link](true); // Muestra la ventana
}
}

Gráfico 5. Ejemplo de ventana JDialog

Curso de Java Standard Edition – J2SE 103


ƒ CUADROS DE DIÁLOGO ESTÁNDAR: Swing incorpora distintos componentes que
implementan diferentes tipos de cuadros de diálogo estándar, pero que no son
especializaciones de JDialog.
JComponent

JOptionPane JFileChooser

Gráfico 6. Jerarquía de clases de los cuadros de diálogo estándar

A continuación se describen las principales clases de cuadro de diálogo estándar:

o [Link]: esta clase se utiliza para crear los cuadros de diálogo


más habituales, en los que se pide un valor al usuario o en los que se muestra un
mensaje de error o advertencia. Todos los cuadros de diálogo que implementa
JOptionPane son modales (bloquean la interacción del usuario con otras ventanas).
La forma más sencilla de uso de la clase es mediante la invocación de alguno de sus
métodos estáticos para crear cuadros de diálogo. A continuación se muestran dichos
métodos:

MÉTODO FUNCIONALIDAD
static int showMessageDialog(Component, Object) Muestra un cuadro de diálogo modal que
presenta información al usuario y tiene un
static int showMessageDialog(Component, Object,
botón “Aceptar”. Los argumentos especifican
String, int)
el componente padre, el mensaje, el título, el
static int showMessageDialog(Component, Object, tipo de mensaje y el icono del cuadro de
String, int, Icon) diálogo.
static int showConfirmDialog(Component, Object)
static int showConfirmDialog (Component, Object, Muestra un cuadro de diálogo modal que
String, int) realiza una pregunta al usuario. Los
static int showConfirmDialog (Component, Object, argumentos especifican el componente padre,
String, int, int) el mensaje, el título, el tipo de opción, el tipo
static int showConfirmDialog (Component, Object, de mensaje y el icono del cuadro de diálogo.
String, int, int, Icon)
static int showInputDialog(Object)
static int showInputDialog(Component, Object) Muestra un cuadro de diálogo modal en el
que solicita una entrada al usuario. Los
static int showInputDialog (Component, Object, argumentos especifican el componente padre,
String, int) el mensaje, el título, el tipo de mensaje y el
static int showInputDialog (Component, Object, icono del cuadro de diálogo.
String, int, Icon)
Muestra un cuadro de diálogo modal
personalizado. Los argumentos especifican el
static int showOptionDialog (Component, Object, componente padre, el mensaje, el título, el
String, int, int, Icon, Object[],Object) tipo de opción, el tipo de mensaje, el icono,
las opciones y la opción predeterminada del
cuadro de diálogo.

Mediante el parámetro tipo de mensaje se pueden proporciona el comportamiento


del cuadro del diálogo: Los tipos de mensaje predeterminados son:

- JOptionPane.ERROR_MESSAGE - JOptionPane.PLAIN_MESSAGE
- JOptionPane.INFORMATION_MESSAGE - JOptionPane.WARNING_MESSAGE
- JOptionPane.QUESTION_MESSAGE

Curso de Java Standard Edition – J2SE 104


Mediante el parámetro tipo de opciones se pueden proporcionar los botones que se
deben incluir. Las opciones predeterminadas son:

- JOptionPane.DEFAULT_OPTION - JOptionPane.OK_CANCEL_OPTION
- JOptionPane.YES_NO_OPTION - JOptionPane.YES_NO_CANCEL_OPTION

Todos los métodos de la clase JOptionPane, devuelven cual es el botón pulsado, en


los valores representados por las constantes:

- JOptionPane.YES_OPTION - JOptionPane.OK_OPTION
- JOptionPane.NO_OPTION - JOptionPane.CLOSED_OPTION
- JOptionPane.CANCEL_OPTION

Ejemplo: Creación de cuadros de diálogo estándar con JOptionPane:


package interfacesGraficas;
import [Link].*;

public class EjemploJOptionPane extends JFrame {


public EjemploJOptionPane (){
// Agregar los componentes a la ventana
JLabel etiqueta = new JLabel(“Ventana JFrame”); // Crea el componente
getContentPane().add(etiqueta); // Agrega el componente
// Establecer propiedades generales de la ventana
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setTitle(“Ejemplo de JOptionPane”);
setSize(300,200);
//CREAR LOS CUADROS DE DIALOGO
// Mensaje de Error
[Link](this, // Ventana principal
“Error: Debe introducir todos los campos”, // Mensaje
“Error de entrada de datos”, // Titulo
JOptionPane.ERROR_MESSAGE); // Tipo mensaje Gráfico 7. Cuadro de dialogo Mensaje

// Mensaje de confirmación
int opc = [Link](this,
“¿Desea Agregar el Registro?, // Mensaje
“Mensaje de confirmación”, // Titulo
JOptionPane.YES_NO_OPTION); // Tipo Opciones
Gráfico 8. Cuadro de dialogo de Confirmación
// Cuadro de opción personalizado
Object[] textoOpciones = {“Sí adelante”,”Ahora no”, “No sé que hacer”};
int op = [Link](this,
“¿Desea realizar la operación ahora?”, // Mensaje
“Mensaje de Confirmación”, // Titulo
JOptionPane.YES_NO_CANCEL_OPTION, // Tipo opciones
JOptionPane.QUESTION_MESSAGE, // Tipo de Mensaje
null, // Icono
Gráfico 9. Cuadro de dialogo Personalizado
textoOpciones, // Opciones
textoOpciones[0]); // Opción principal
}
public static void main(String[] args) {
EjemploJOptionPane ventana = new EjemploJOptionPane ();
[Link](true);
}
}

Curso de Java Standard Edition – J2SE 105


o [Link]: un selector de archivos permite la selección interactiva
por parte del usuario de un archivo o directorio, bien a partir de una lista que se le
proporciona o bien introduciendo directamente su nombre. Un selector de archivos
muestra todos los archivos y directorios no ocultos de una posición determinada del
sistema de archivos. Si sólo se está interesado en algún tipo de archivos se puede
modificar la presentación aplicando filtros.

MÉTODO FUNCIONALIDAD
JFileChooser() Constructores. Mediante los argumentos se
JFileChooser(String) establece el directorio actual
Muestra el selector de archivos abrir o guardar.
int showOpenDialog(Component) Devuelven como resultado si el usuario ha
int showSaveDialog(Component) aceptado o no la operación (APPROVE_OPTION ó
CANCEL_OPTION).
void setSelectedFile(File) Establece u obtiene el archivo o directorio
File getSelectedFile() seleccionado
Estable u obtiene el mo de selección. Por omisión
void setFileSelectionMode(int) sólo se pueden seleccionar archivos (FILES_ONLY),
int getFileSelectionMode() pero se puede cambiar a solo directorio
(DIRECTORIES_ONLY) o ambos (FILES_AND_DIRECTORIES)
boolean getControlButtonsAreShown() Obtiene o establece si se muestran o no los
void setControlButtonAreShown(boolean) botones de control predeterminados del selector

Ejemplo: en el siguiente código se crea un selector de archivos y se muestra en la


salida estándar el nombre del archivo seleccionado o si se canceló la operación:

package interfacesGraficas;
import [Link].*;
import [Link].*;

public class EjemploJFileChooser extends JFrame {


public EjemploJFileChooser (){
// Agregar los componentes a la ventana
JLabel etiqueta = new JLabel(“Ventana JFrame”); // Crea el componente
getContentPane().add(etiqueta); // Agrega el componente
// Establecer propiedades generales de la ventana
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setTitle(“Ejemplo de JOptionPane”);
setSize(300,200);

//SE CREA EL SELECTOR DE ARCHIVOS


JFileChooser selector = new JFileChooser();
[Link](JFileChooser.DIRECTORIES_ONLY);
int opc = [Link](this);
if(opc == JFileChooser.APROVE_OPTION) {
File archivo = [Link]();
[Link](“Archivo seleccionado: ” + archivo);
} else
[Link](“Operación cancelada por el usuario”);
}
Gráfico 10. Selector de archivos
public static void main(String[] args) {
EjemploJFileChooser ventana = new EjemploJFileChooser ();
[Link](true);
}
}

Curso de Java Standard Edition – J2SE 106


ƒ CONTENEDORES INTERMEDIOS: los contenedores intermedios no generan una ventana
independiente y su propósito es agrupar otros componentes para mejorar la gestión de
la interfaz (por ejemplo, presentación o gestión de eventos). Ofrecen diferentes
funcionalidades, desde la simple agrupación de componentes (JPanel) hasta la gestión
de componentes en múltiples capas (como JTabbedPane).

JComponent

JPanel JScrollPane JSplitPane JTabbedPane JToolBar

Gráfico 11. Jerarquía de clases de los contenedores intermedios

A continuación se describen los principales contenedores intermedios:

o [Link]: es un contenedor simple de propósito general, hereda de


JComponent, no posee ninguna característica gráfica sofisticada. JPanel sirve para
agrupar a otros componentes. Habitualmente se utiliza para dividir una zona de
pantalla en secciones. Inicialmente estos paneles no son visualizables, salvo por el
color de su fondo, pero es sencillo añadirles bordes. De forma predeterminada
JPanel emplea FlowLayout, como administrador de diseño.

MÉTODO FUNCIONALIDAD
JPanel() Constructores. Permite crear un panel para agrupar
componentes, además permite establecer el
JPanel(LayoutManager) administrador de diseño para el contenedor.
void add(JComponent)

o [Link]: proporciona un panel con la capacidad de incluir barra


de desplazamiento para mostrar su contenido. Por tanto, es muy adecuado para
presentar una información que esta contenida en otro componente y que no cabe
completamente en la zona de visualización que tiene asignada en la pantalla.

MÉTODO FUNCIONALIDAD
JScrollPane() Constructores. Se puede indicar el componente que
JScrollPane(Component) proporciona el contenido y la política de
JScrollPane(Component, int, int) presentación de las barras de desplazamiento.
Establece el componente que proporciona el
void setViewportView(Component)
contenido.
Establece u obtiene la política de presentación de la
barra de desplazamiento vertical. Las posibilidades
void setVerticalScrollBarPolicy(int) son: que se muestre cuando sea necesario
int getVerticalScrollBarPolicy() (VERTICAL_SCROLLBAR_AS_NEEDED), que se muestren
siempre (VERTICAL_SCROLLBAR_ALWAYS) y que no se
muestren nunca (VERTICAL_SCROLLBAR_NEVER).
Establece u obtiene la política de presentación de la
barra de desplazamiento horizontal. Las
void setHorizontalScrollBarPolicy(int) posibilidades son: que se muestre cuando sea
necesario (HORIZONTAL_SCROLLBAR_AS_NEEDED), que se
int getHorizontalScrollBarPolicy() muestren siempre (HORIZONTAL_SCROLLBAR_ALWAYS) y
que no se muestren nunca
(HORIZONTAL_SCROLLBAR_NEVER).

Curso de Java Standard Edition – J2SE 107


Ejemplo: A continuación se presenta el código que ayuda a crear un JScrollPane.

package interfacesGraficas;

import [Link].*;
import [Link].*;

public class EjemploScrollPane extends JFrame {


public EjemploScrollPane() {
// CREAR LOS COMPONENTES DE LA VENTANA
JPanel panel = new JPanel();
JLabel etq = new JLabel("Etiqueta");
[Link](etq);

JScrollPane scroll = new JScrollPane( );


[Link](JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
[Link](JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
[Link](panel);

// AGREGAR COMPONENTES A LA VENTANA


getContentPane().add(scroll);

// ESTABLECER PROPIEDADES GENERALES DE LA VENTANA


setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setTitle("Ejemplo de ScrollPane");
setSize(150, 100);
}

public static void main(String[] args) {


EjemploScrollPane ventana;
ventana = new EjemploScrollPane();
[Link](true);
}
}

Gráfico 12. Contenedor ScrollPane

o [Link]: es un contenedor que gestiona dos componentes


(normalmente dos paneles) colocados vertical u horizontalmente y diferenciados por
un separador que puede ser reposicionado por el usuario. El usuario puede decidir
cual es el tamaño asignado a cada uno de los componentes pulsando con el ratón
sobre el separador y arrastrándolo.

MÉTODO FUNCIONALIDAD
JSplitPane()
Constructores. Se le puede proporcionar la
JSplitPane(int)
orientación y los componentes de sus dos partes.
JSplitPane(int, Component, Component)
Establece u obtiene la orientación de la división. Por
void setOrientation(int) omisión aparece uno al lado del otro
int getOrientation() (HORIZONTAL_SPLIT) y se puede cambiar para que
aparezca uno encima de otro (VERTICAL_SPLIT)

Curso de Java Standard Edition – J2SE 108


void setDividerSize(int) Establece u obtiene el tamaño del separador en
int getDividerSize() píxels.
void setTopComponent(Component)
void setBottomComponent(Component)
void setLeftComponent(Component) Establece u obtiene el componente que aparece en
void setRigthComponent(Component) cada una de las zonas. Izquierda es equivalente a
Component getTopComponent() arriba y derecha es equivalente abajo para poder
Component getBottomComponent() cambiar posteriormente la posición del separador.
Component getLeftComponent()
Component getRigthComponent()
void setDividerLocation(double)
Establece u obtiene la posición del separador. Dicha
void setDividerLocation(int)
posición puede indicarse en porcentaje o en píxels.
int getDividerLocation()

Ejemplo: A continuación se presenta el código que ayuda a crear un JSplitPane.

package interfacesGraficas;

import [Link].*;
import [Link].*;

public class EjemploSplitPane extends JFrame {


public EjemploSplitPane() {
// CREAR LOS COMPONENTES DE LA VENTANA
JScrollPane panelIzquierdo = new JScrollPane();
[Link](JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JScrollPane panelDerecho = new JScrollPane();
[Link](JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

JSplitPane panelDividido = new


JSplitPane(JSplitPane.HORIZONTAL_SPLIT,panelIzquierdo,panelDerecho);
[Link](150);

// AGREGAR COMPONENTES A LA VENTANA


getContentPane().add(panelDividido);

// ESTABLECER PROPIEDADES GENERALES DE LA VENTANA


setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setTitle("Ejemplo de SplitPane");
setSize(300, 200);
}
public static void main(String[] args) {
EjemploSplitPane ventana;
ventana = new EjemploSplitPane();
[Link](true);
}
}

Gráfico 13. Contenedor JSplitPane

Curso de Java Standard Edition – J2SE 109


o [Link]: es contenedor que gestiona varios componentes (o
grupos de componentes, aunque habitualmente paneles) como una pila de fichas.
Los componentes se superponen completamente los unos a los otros de forma que
sólo uno de ellos es visible en cada momento. El usuario puede decidir cual de los
componentes se visualiza, seleccionando la solapa o lengüeta correspondiente a
dicho componente. El administrador de diseño por omisión es CardLayout.

MÉTODO FUNCIONALIDAD
JTabbedPane() Constructor. Se puede establecer la posición de
las solapas mediante las constantes TOP, BOTTOM,
JTabbedPane(int) LEFT y RIGTH.

Añade una nueva ficha o componente (con su


void addTab(String, Icon, Component, String) solapa) al contenedor. Los argumentos
void addTab(String, Icon, Component) proporcionan el texto de la solapa, su icono, el
void addTab(String, Component) componente a mostrar cuando se seleccione esa
solapa y la ayuda contextual para la solapa.
Igual que addTab(), pero indica el índice en la que
void insertTab(String, Icon, Component, String, int)
se añade la ficha en la lista de fichas.
int getSelectedIndex()
Component getSelectedComponent() Obtiene o establece el índice o la ficha
seleccionada. La selección de una ficha supone su
void setSelectedIndex(int) presentación automática en pantalka.
void setSelectedComponent(Component)
void removeComponent(Component) Elimina la ficha del componente o la del índice
void removeTabAt(int) correspondiente.
void setComponentAt(int, Component)
Component getComponentAt(int)
void setTitleAt(int, String) Establece u obtiene el componente, el titulo o el
icono asociado con la ficha situada en dicho
String getTitleAt(int) índice.
void setIconAt(int, Icon)
Icon getIconAt(int)

Ejemplo: A continuación se presenta el código que ayuda a crear un JTabbedPane.

package interfacesGraficas;

import [Link].*;
import [Link].*;

public class EjemploTabbedPane extends JFrame {


public EjemploTabbedPane() {

// CREAR LOS COMPONENTES DE LA VENTANA


JPanel panel1 = new JPanel();
[Link](new JLabel("Panel 1"));

JPanel panel2 = new JPanel();


[Link](new JLabel("panel2"), [Link]);

JTabbedPane panelSolapas = new JTabbedPane();


[Link]("Primero", panel1);
[Link]("Segundo", panel2);

Curso de Java Standard Edition – J2SE 110


// AGREGAR COMPONENTES A LA VENTANA
getContentPane().add(panelSolapas);

// ESTABLECER PROPIEDADES GENERALES DE LA VENTANA


setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setTitle("Ejemplo de TabbedPane");
setSize(300, 200);
}
public static void main(String[] args) {
EjemploTabbedPane ventana;
ventana = new EjemploTabbedPane();
[Link](true);
}
}

Gráfico 14. Contenedor JTabbedPane

o [Link]: esta clase implementa una barra de herramientas,


formada normalmente por botones o controles que incluyen iconos y que aparecen
organizados como una fila o una columna dependiendo de la zona de la pantalla
donde se coloque. El administrador de diseño predeterminado de una barra de
herramienta es BoxLayout.

MÉTODO FUNCIONALIDAD
JToolBar() Constructor que crea una barra de herramientas. Se
puede especificar el nombre y la orientación de la
JToolBar(String)
barra de herramientas. Los valores posibles son
JToolBar(int) HORIZONTAL o VERTICAL.

Añade un componente a la barra de herramientas.


Component add(Component)
Normalmente los componentes son botones.
Añade un separador al final de la barra de
void addSeparator()
herramientas
void setFloatable(boolean) Establece u obtiene si la barra de herramientas se
boolean isFloatable() puede desplazar o no.

Ejemplo: A continuación se presenta el código que ayuda a crear un JToolBar.

package interfacesGraficas;

import [Link].*;
import [Link].*;

public class EjemploJToolBar extends JFrame {


public EjemploJToolBar() {

// CREAR LOS COMPONENTES DE LA VENTANA

Curso de Java Standard Edition – J2SE 111


JButton boton1 = new JButton(new ImageIcon("images/Web/[Link]"));
JButton boton2 = new JButton(new ImageIcon("safe_easy_easier.jpg"));
JButton boton3 = new JButton(new ImageIcon("images/Web/[Link]"));

JToolBar barra = new JToolBar([Link]);


[Link](boton1);
[Link](boton2);
[Link]();
[Link](boton3);

// AGREGAR COMPONENTES A LA VENTANA


getContentPane().add(barra, [Link]);

// ESTABLECER PROPIEDADES GENERALES DE LA VENTANA


setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setTitle("Ejemplo de JToolBar");
setSize(350, 150);
}

public static void main(String[] args) {


EjemploJToolBar ventana;
ventana = new EjemploJToolBar();
[Link](true);
}

Gráfico 15. Contenedor JToolBar

Curso de Java Standard Edition – J2SE 112


ƒ COMPONENTES ATÓMICOS: un componente simple o atómico, es un objeto que tiene una
representación gráfica que se puede mostrar en la pantalla y con la que puede
interactuar el usuario. No están formados por otros componentes gráficos más simples.

JComponent

ImageIcon

JLabel

AbstractButton

JButton

JToggleButton

JRadioButton

JCheckBox

JMenu

JMenuItem

JRadioButtonMenuItem

JCheckBoxMenuItem

JMenuBar

JPopupMenu

JSeparator

JTextComponent

JTextField

JPasswordField

JTextArea

JEditorPane

JTextPane

JList

JComboBox

Gráfico 16. Jerarquía de clases de los componentes atómicos

A continuación se describen los componentes atómicos:

o [Link]: esta clase implementa la interfaz Icon, y genera un


icono a partir de una imagen en formato GIF o JPG. La imagen se especifica a
través de un objeto Image, un String o mediante un localizador uniforme de
recursos (URL).

MÉTODO FUNCIONALIDAD
Crea un icono desde un archivo especificado. Puede
incluir la ruta en donde se encuentra la imagen,
ImageIcon(String)
empleando como separador de directorios el carácter
‘/’.

Curso de Java Standard Edition – J2SE 113


void setDescription(String) Establece una descripción para el icono
String getDescription() Devuelve la descripción del icono

o [Link]: esta clase implementa una etiqueta que puede contener una
cadena de texto, un icono o ambos, y puede mostrarse en cualquier contenedor.
Una etiqueta es un campo de solo salida, es decir muestra su contenido que no es
ni seleccionable ni editable por el usuario. Se emplea par dar nombre (etiquetar) a
otros componentes de la interfaz gráfica. Una característica importante de las
etiquetas en Swing es que estas admiten varias líneas, con distintos tipos de fuente.

MÉTODO FUNCIONALIDAD
JLabel(String)
Constructores. Se puede especificar el texto, el icono
JLabel(String, int)
y la alineación horizontal del contenido en la etiqueta.
JLabel(Icon)
void setText(String)
Establece u obtiene el texto de la etiqueta.
String getText()
void setIcon(Icon)
Establece u obtiene el icono de la etiqueta.
Icon getIcon()

void setHorizontalAligment(int) Establece u obtiene la alineación horizontal del


contenido. Los valores posibles son: LEFT (por
int getHorizontalAligment() omisión), CENTER, RIGTH, LEADING y TRAILING.

void setVerticalAligment(int) Establece u obtiene la alineación vertical del


contenido. Los valores posibles son: CENTER (por
int getVerticalAligment() omisión), TOP y BOTTOM.

o [Link]: esta clase implementa la forma más habitual de botón


gráfico de interacción que sirve para ejecutar una acción haciendo clic sobre él.
También se puede activa mediante el teclado si se le ha asociado una combinación
de teclas

MÉTODO FUNCIONALIDAD
JButton(String)
Constructor, en el cual se puede especificar el texto
JButton(Icon)
del botón y el icono asociado.
JButton(String,Icon)
Selecciona el botón mediante programa (equivale a
void doClick()
que el usuario haga clck sobre el botón).
Icon getIcon()
Obtiene o establece el icono del botón.
void setIcon(Icon)
String getText()
Obtiene o establece el texto del botón.
void setText(String)
boolean isSelected() Obtiene o establece el estado del botón (seleccionado
void setSelected (bolean) o no seleccionado).
boolean getEnabled() Obtiene o establece el estado de activación del botón
void setEnabled(bolean) (Activado o desactivado).

o [Link]: Componente que permite mostrar y editar una única


línea de texto. Se utiliza para solicitar al usuario entradas de datos breves en forma
de texto. Utiliza principalmente los métodos heredados de la clase JTextComponent,
y representa una obtener y validar datos proporcionados por el usuario.

Curso de Java Standard Edition – J2SE 114


MÉTODO FUNCIONALIDAD
JTextField()
JTextField(String) Constructores. Se puede especificar un texto inicial y
JTextField(int) el número de caracteres que podrá contener.
JTextField(String,int)
void setText(String) Estable u obtiene el texto contenido en el
String getText() componente.
void setEditable(boolean) Establece u obtiene si el usuario puede editar el texto
boolean isEditable() contenido

o [Link]: esta clase implementa una casilla de verificación. Es una


especialización de un botón con estado o conmutador (JToggleButton) y, por tanto,
tiene dos estados posibles, seleccionada o no seleccionada que determina y
modifica su apariencia gráfica (normalmente mediante una cruz o marca de
selección).

MÉTODO FUNCIONALIDAD
Constructor. Permite establecer el texto de la casilla,
JCheckBox(String, Icon, boolean) un icono y el estado inicial (true – seleccionado,
false – no seleccionado)
boolean isSelected() Obtiene o establece el estado del botón (seleccionado
void setSelected (bolean) o no seleccionado).
boolean getEnabled() Obtiene o establece el estado de activación del botón
void setEnabled(bolean) (Activado o desactivado).

o [Link]: esta clase implementa los botones de radio o de


opción que son una especialización de un botón con estado o conmutador
(JToggleButton) caracterizados porque en un grupo de botones de opción sólo uno
de ellos puede estar seleccionado, es decir, que so mutuamente excluyentes de
modo que si se selecciona otro botón de radio distinto el anterior, deja de estar
seleccionado. Para conseguir este comportamiento de excusión mutua los botones
de radio se deben agrupar en un objeto de grupo de botones ButtonGroup. La
forma de agruparlos es crear el grupo de botones, crear los botones y añadirlos al
grupo mediante el método add() de ButtonGroup, como si se tratara de un
contenedor. Esta agrupación es únicamente lógica, por tanto para dar al usuario la
idea de que están relacionados normalmente se incluyen en algún contenedor
intermedio (por ejemplo, JPanel), y se le añade algún tipo de borde.

JRadioButton
MÉTODO FUNCIONALIDAD
Constructor. Permite establecer el texto del botón de
JRadioBox(String, Icon, boolean) opción, un icono y el estado inicial (true –
seleccionado, false – no seleccionado)
boolean isSelected() Obtiene o establece el estado del botón (seleccionado
void setSelected (bolean) o no seleccionado).
boolean getEnabled() Obtiene o establece el estado de activación del botón
void setEnabled(bolean) (Activado o desactivado).

Curso de Java Standard Edition – J2SE 115


ButtonGroup
MÉTODO FUNCIONALIDAD
ButtonGroup() Constructor que crea un grupo de botones
add(AbstractButton) Añade un botón al grupo de botones, de forma lógica

o [Link]: esta clase implementa un cuadro combinado


desplegable, en el que se agrupan las funcionalidades de una lista y un campo de
texto. El campo de texto y la lista de valores (su modelo) tienen una estrecha
relación de dependencia, de modo que si el usuario escribe texto en el cuadro la
lista se desplaza hasta la concordancia más próxima entre sus valores. Cuando el
usuario selecciona un elemento de esa lista, ese valor pasa automáticamente a
mostrarse como contenido del cuadro combinado. En la lista, además de valores
textuales se pueden incluir iconos. Tiene dos posibles formas de uso: la primeroa
forma es cuado se presenta una lista fija de posibles valores para que usuario las
elija; y la segunda es cuando el usuario también puede introducir un nuevo valor a
la lista.

MÉTODO FUNCIONALIDAD
JComboBox() Constructores. El contenido inicial de la lista de
JComboBox(Object [ ]) valores se puede hacer a partir de un arreglo de
JComboBox(Vector) objetos o de un Vector.
void addItem(Object) Añade un objeto al final de la lista de valores o lo
void insertItemAt(Object,int) inserta en una determinada posición.
Obtiene un elemento de una determinada posición o
Object getItemAt(int) el elemento actualmente seleccionado del cuadro
Object getSelectedItem() combinado. Tiene los métodos set correspondientes
para establecer estos valores.
void removeItemAt(int) Elimina un objeto de la lista de la posibles valores,
void removeItem(Object) dada una posición o un objeto especifico.
void setEditable(boolean) Establece u obtiene si un campo combinado
boolean isEditable() desplegable es editable o no
Establece el número máximo de filas que muestra
para realizar la elección. Para acceder al resto
void setMaximunRowCount(int)
presenta de forma automática barras de
desplazamiento.

Ejemplo: A continuación se presenta el código que ayuda a crear un JFrame con los
componentes gráficos de Swing vistos previamente.

package interfacesGraficas;

import [Link].*;
import [Link].*;

public class EjemploComponentesGraficos extends JFrame {

public EjemploComponentesGraficos() {

// CREAR LOS COMPONENTES DE LA VENTANA


JLabel jblNombre= new JLabel("Nombre:");
JTextField jtfNombre = new JTextField("",10);
JButton jbtBuscar = new JButton("Buscar");

Curso de Java Standard Edition – J2SE 116


JRadioButton jrbOpcA = new JRadioButton("Femenino", true);
JRadioButton jrbOpcB = new JRadioButton("Masculino");
ButtonGroup grupoOPC = new ButtonGroup();
[Link](jrbOpcA);
[Link](jrbOpcB);
Panel panelOPC = new Panel();
[Link]("Opciones");
[Link](jrbOpcA);
[Link](jrbOpcB);

JCheckBox chkOp1 = new JCheckBox("Femenino");


JCheckBox chkOp2 = new JCheckBox("Masculino");
Panel panelCHK = new Panel();
[Link]("CASILLAS");
[Link](chkOp1);
[Link](chkOp2);

String [] valores = new String[]{"Femenino","Masculino"};


JComboBox jcbSexo = new JComboBox(valores);

// AGREGAR COMPONENTES A LA VENTANA


getContentPane().setLayout(new FlowLayout());
getContentPane().add(jblNombre);
getContentPane().add(jtfNombre);
getContentPane().add(jbtBuscar);
getContentPane().add(panelOPC);
getContentPane().add(panelCHK);
getContentPane().add(jcbSexo);

// ESTABLECER PROPIEDADES GENERALES DE LA VENTANA


setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setTitle("Componentes Gráficos Swing");
setSize(330, 200);
}

public static void main(String[] args) {


EjemploComponentesGraficos ventana;
ventana = new EjemploComponentesGraficos();
[Link](true);
}
}

Grafico 17. Ejemplo de los componentes gráficos de Swing

o [Link]: esta clase implementa una lista de elementos que se presenta


en forma de columna. En esta lista el usuario puede realizar la selección de uno
(comportamiento predeterminado) o varios de sus elementos. Si la lista tiene
muchos elementos y, por tanto, pueden no caber en el espacio de visualización
asignado, debería incluirse dentro de un panel con barras de desplazamiento.

Curso de Java Standard Edition – J2SE 117


El contenido de una lista viene dado por su modelo de datos que debe implementar
la interfaz Java ListModel, aunque se proporcionan constructores y métodos que
crean automáticamente dicho modelo a partir de un arreglo de objetos o de un
Vector. Además, se proporciona una implementación predeterminada del modelo de
datos de la lista mediante la clase DefaultListModel. Esta clase permite modificar
el contenido de una lista de forma dinámica mediante los métodos addElement() y
removeElement().

MÉTODO FUNCIONALIDAD
JList(ListModel) Constructores. Permiten crear la lista de datos a partir
JList(Vector) de una modelo de datos, una Vector o un arreglo de
JList(Object []) objetos
void setListData(Vector)
Establece u obtiene el modelo de datos de la lista
void setListData(Object [ ])
(contenido)
ListModel getModel()
Establece u obtiene el modo de selección. Las
void setSelectionMode(int) posibilidades son: por omisión selección simple
(SINGLE_SELECTION), la selección de un único intervalo
int getSelectionMode() (SINGLE_INTERVAL_SELECTION) o la selección de intervalos
múltiples (MULTIPLE_INTERVAL_SELECTION)
int getSelectionIndex()
int getMinSelectionIndex() Obtiene el índice o valor seleccionado (o índices o
int getMaxSelectionIndex() valores dependiendo del modelo de selección que esté
int [ ] getSelectedIndices() activado). Estos métodos tienen sus métodos set
Object getSelectedValue() correspondientes para establecer estos valores.
Object [] getSelectedValues()
void clearSelection() Desactiva la selección actual o detecta si la selección
bolean isSelectionEmpty() es vacía.

o [Link]: esta clase es usada para mostrar y editar cuadriculas


regulares de dos dimensiones. En esta tabla el usuario puede realizar la selección de
una (comportamiento predeterminado) o varias de filas o columnas. Si la tabla tiene
muchos elementos y, por tanto, pueden no caber en el espacio de visualización
asignado, debería incluirse dentro de un panel con barras de desplazamiento.

El contenido de la tabla viene dado por su modelo de datos que debe implementar
la interfaz Java TableModel, aunque se proporcionan constructores y métodos que
crean automáticamente dicho modelo a partir de una matriz de objetos y de un
arreglos de objetos o a partir de dos objetos de Vector.

MÉTODO FUNCIONALIDAD
Constructor. Permite construir una tabla a partir de
JTable() una matriz que posee el contenido de la Tabla y de un
JTable(Object[][], Object[]) arreglo que contiene los encabezados de las columnas
de la tabla.
int getRowCount()
Devuelve el número de filas y columnas de la Tabla.
int getColumnCount()
Devuelve el nombre de la columna pasada por
String getColumnName(int) parámetro. Las filas y las columnas se numeran a
partir de cero (0).

Curso de Java Standard Edition – J2SE 118


int getSelectedColumn()
Devuelve el número o números de la(s) columna(s) o
int [ ] getSelectedColumns()
de la(s) fila(s) seleccionada(s) respectivamente. Si no
int getSelectedRow() hay nada seleccionada devuelve -1.
int [ ] getSelectedRow()

Nota: Es importante tener en cuenta que si ocurre un cambio en el modelo, tanto


de un JList o de un JTable, automáticamente se actualiza el contenido del mismo.

Ejemplo: A continuación se presenta el código que ayuda a crear un JFrame con una
Barra de Menú y los componentes gráficos de Swing JList y JTable.

package interfacesGraficas;

import [Link].*;
import [Link].*;
import [Link];

import [Link];

public class EjemploListaTabla extends JFrame {

public EjemploListaTabla() {

// CREAR LOS COMPONENTES DE LA VENTANA


JLabel jblLista = new JLabel("JLista:");
JLabel jblTabla1 = new JLabel("JTable 1:");
JLabel jblTabla2 = new JLabel("JTable 2:");

// Crear la Lista de elementos


Vector elementos = new Vector(5);
[Link]("Elemento 1");
[Link]("Elemento 2");
[Link]("Elemento 3");
[Link]("Elemento 4");
[Link]("Elemento 5");
JList jlLista = new JList(elementos);

// Crear la Tabla 1
String [][] contenido = new String[][]{
{"Celda 0","Celda 1","Celda 2"},
{"Celda 3","Celda 4","Celda 5"},
{"Celda 6","Celda 7","Celda 8"}
};
String [] columnas = new String[]{"Columna 1","Columna 2","Columna 3"};
JTable jtTabla1 = new JTable(contenido,columnas);

// Crear la Tabla 2
String [][] contents = new String[5][3];
String [] colums = new String[]{"Col1","Col2","Col3"};
contents[2][2] = new String("Celda (2,2)");
JTable jtTabla2 = new JTable(contents,colums);

// AGREGAR COMPONENTES A LA VENTANA


getContentPane().setLayout(new FlowLayout());
getContentPane().add(jblLista);
getContentPane().add(jlLista);
getContentPane().add(jblTabla1);

Curso de Java Standard Edition – J2SE 119


getContentPane().add(jtTabla1);
getContentPane().add(jblTabla2);
getContentPane().add(jtTabla2);

// Si se edita el Modelo, automáticamente se actualiza la vista


contents[3][0] = new String("Celda (3,0)");

// ESTABLECER PROPIEDADES GENERALES DE LA VENTANA


setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setTitle("Ejemplo de Listas y Tablas");
setSize(450, 250);
}

public static void main(String[] args) {


EjemploListaTabla ventana;
ventana = new EjemploListaTabla();
[Link](true);
}

Grafico 18. Ejemplo de JList y JTable

o [Link]: esta clase implementa una barra de menú que


habitualmente se añade al panel raíz de un contenedor, mediante el método
void setJMenuBar(JMenuBar) del contenedor. Para crear una barra de menús se
crea un objeto JMenuBar, al que posteriormente se le añaden los menús
desplegables (objetos JMenu).

MÉTODO FUNCIONALIDAD
JMenuBar() Constructor no necesita parámetros
Permite añadir un menú desplegable a una barra de
void add(JMenu)
menú.

o [Link]: esta clase implementa cada uno de los menús desplegables


asociados a las entradas o títulos de una barra de menús. Un menú desplegable
debe estar asociado a una barra de menú (JMenuBar). Para crear un menú
desplegable, al crearlo se le asigna su título y posteriormente se le añaden el resto
de los elementos de menú o cadenas de texto que se desean que aparezcan.

Permite además, crear menús en cascada, también llamados menús jerárquicos o


secundarios. Para crearlos simplemente hay que añadir un menú desplegable a otro
menú desplegable.

Curso de Java Standard Edition – J2SE 120


MÉTODO FUNCIONALIDAD
JMenu() Constructores. Se puede dar el titulo que se muestra
JMenu(String) en la barra de menú.
JMenuItem add(JMenuItem) Añade un elemento al final del menú desplegable.
JMenuItem add(String) También se puede añadir una cadena de texto.
void addSeparator() Añade un separador al final de un menú desplegable
JMenuItem insert(JMenuItem, int) Inserta un elemento, una cadena o un separador en
void insert(String, int) la posición indicada del menú. El índice del primer
void insertSeparator(int) elemento del menú es 0.
void remove(JMenuItem) Elimina un elemento del menú a partir del objeto o de
void remove(int) una posición especifica. Además permite eliminar
void removeAll() todos los elementos.

o [Link]: esta clase es la implementación de un elemento de un


menú desplegable. Un ítem de menú es esencialmente un botón situado la lista de
opciones de un menú. Cuando el usuario selecciona el botón (JMenuItem), la acción
asociada al ítem del menú es realizada.

MÉTODO FUNCIONALIDAD
JMenuItem(String) Constructores. Se puede especificar el texto y un
JMenuItem(String, Icon) icono al elemento del menú desplegable.
void setEnabled(boolean) Activa o desactiva el elemento del menú

Ejemplo: A continuación se presenta el código que ayuda a crear un JFrame con una
Barra de Menú.

package interfacesGraficas;

import [Link].*;

public class EjemploMenus extends JFrame {

public EjemploMenus() {
// CREAR LOS COMPONENTES DE LA VENTANA
JMenuItem itmOPC1 = new JMenuItem("Opcion 1");
JMenuItem itmOPC2 = new JMenuItem("Opcion 2");
JMenuItem itmOPC3 = new JMenuItem("Opcion 3");
JMenuItem itmOPC4 = new JMenuItem("Opcion 4");
JMenu mnu1 = new JMenu("Menu 1");
[Link](itmOPC1);
[Link](itmOPC2);
[Link](itmOPC3);
[Link](new JCheckBoxMenuItem("Opcion CHK"));
[Link](new JSeparator());
[Link](itmOPC4);

JMenu mnu2 = new JMenu("Menu 2");


[Link](new JMenuItem("Opcion 5"));
[Link](new JMenuItem("Opcion 6"));
[Link](new JMenuItem("Opcion 7"));

JMenuBar mnuBar = new JMenuBar();


[Link](mnu1);
[Link](mnu2);

Curso de Java Standard Edition – J2SE 121


// AGREGAR COMPONENTES A LA VENTANA
getRootPane().setJMenuBar(mnuBar);

// ESTABLECER PROPIEDADES GENERALES DE LA VENTANA


setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setTitle("Ejemplo de Menus");
setSize(450, 250);
}

public static void main(String[] args) {


EjemploMenus ventana;
ventana = new EjemploMenus();
[Link](true);
}
}

Grafico 19. Ejemplo de Menús en Java

Curso de Java Standard Edition – J2SE 122


3. LOS ADMINISTRADORES DE DISEÑO

Un administrador de disposición o diseño es un objeto auxiliar que colabora con la aplicación, y con
el sistema operativo en la ésta se ejecuta, para determinar la mejor manera de mostrar los
elementos gráficos en la ventana principal de la aplicación. Un administrador de disposición permite
una mayor flexibilidad y control para colocar los componentes gráficos dentro de un contenedor, a la
vez que proporciona portabilidad e independencia frente a la plataforma concreta en la que se
ejecuta. Por ejemplo, el programador no tiene que preocuparse sobre qué pasa si el usuario cambia
el tamaño de la ventana, el tamaño de la pantalla o si su aplicación se ejecuta en Windows o UNIX.

La administración de diseño es el proceso en el que se determina el tamaño y la posición de


los componentes gráficos de un contenedor. En este proceso se tiene en cuenta las
sugerencias de tamaño de cada componente (su tamaño mínimo, preferido y máximo) y, en la
mayoría de los casos el orden en el que se han añadido al contenedor. El administrador de
diseño actúa de forma automática cada vez que se ha realizado alguna modificación en
el contenedor que pueda producir un cambio en su presentación gráfica.

Cada contenedor (Conteiner) tiene asignado de forma predeterminada un administrador de diseño.


En el constructor de cada contenedor se crea y se asigna un administrador de disposición por
omisión, que puede ser cambiado por el programador.

o JPanel Æ FlowLayout
o JFrame Æ BorderLayout
o JDialog Æ BorderLayout
o JWindow Æ FlowLayout

Si el programador desea cambiar el administrador predeterminado, primero debe crear un


objeto del tipo de administrador deseado y después asociarlo al contenedor. La asociación se realiza
mediante el método del contenedor void setLayout(LayoutManager lay). El tipo de
administrador puede cambiar la forma en la que se añaden los componentes al contenedor.

Otra posibilidad es no utilizar un administrador de diseño y realizar una colocación


absoluta de los componentes dentro del contenedor. Para esto simplemente hay que especificar
que el administrador para dicho contenedor es null. No obstante, esta posibilidad no es muy
recomendable en la mayoría de los casos, ya que la aplicación puede no presentarse de forma
adecuada si se ejecuta en una plataforma diferente o si se cambia la resolución de la pantalla.

3.1. TIPOS DE ADMINISTRADORES DE DISEÑO

En las primeras versiones de Java, que sólo tenían AWT, se proporcionaban de forma estándar
cinco administradores de diseño:

o FlowLayout
o BorderLayout
o GridLayout Todos los administradores implementan la interfaz LayoutManager
o CardLayout
o GridBagLayout

Curso de Java Standard Edition – J2SE 123


o FlowLayout: es el administrador de disposición más simple que proporciona Java y es el
que se proporciona por omisión en los paneles (JPanel). Los componentes se colocan en una
fila de izquierda a derecha hasta ocupar el espacio horizontal completo asignado al
contenedor, según el orden en el que han sido añadidos. Si todos los componentes, no
caben en una sola fila, se sigue en la siguiente. Los componentes se dimensionan según el
tamaño que necesitan (su tamaño preferido) y dentro de cada fila se muestran centrados
por omisión.

Ejemplo: A continuación se presenta el código que ayuda a crear un JFrame con el


administrador de diseño FlowLayout, así como los elementos que administra.

package interfacesGraficas;

import [Link].*;
import [Link].*;

public class EjemploFlowLayout extends JFrame {


// Constructor de la Ventana
public EjemploFlowLayout() {
setTitle(“Administrador de Diseño: FlowLayout”);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(new JButton(“Botón 1”));
getContentPane().add(new JButton(“Segundo Botón”));
getContentPane().add(new JButton(“3 Botón”));
getContentPane().add(new JButton(“Bot. 4”));
getContentPane().add(new JButton(“Botón5”));
}
// Método principal
public static void main(String[] args) {
EjemploFlowLayout Flow = new EjemploFlowLayout();
[Link]();
[Link](true);
}
}

Grafico 20. Administrador de Diseño FlowLayout

El administrador FlowLayout proporciona tres constructores:


o public FlowLayout()
o public FlowLayout(int aligment)
o public FlowLayout(int algment, int horizontalGAP, int verticalGAP)

Es obligatorio que el argumento aligment tenga el valor [Link],


[Link] o [Link]. Los argumentos horizontalGAP y verticalGAP
especifican el número de píxeles presentes entre los componentes. Si no se especifica
ningún valor de espaciado (GAP), FlowLayout asume el valor de cinco (5 píxels) por omisión.

o BorderLayout: Es el administrador predeterminado de los contenedores de alto nivel


(JFrame y JDialog). Este administrador de disposición está basado en dividir el contenedor
en cinco zonas, una central y otras cuatro según los puntos cardinales. Los puntos

Curso de Java Standard Edition – J2SE 124


cardinales norte, sur, este y oeste se corresponden con las partes superior, inferior,
izquierda y derecha del contenedor. No es necesario utilizar todas las zonas, de modo que
las zonas ocupadas se reparten el espacio disponible. La zona central se considera
privilegiada y trata de ocupar la mayor parte del espacio del contenedor.

Al añadir un componente a un contenedor que utilice BorderLayout., se debe indicar la zona


en la que se quiere colocar el componente. Cada una de estas zonas están indentificadas
por la correspondiente constantes de clase: [Link], [Link],
[Link], [Link] y [Link]. El componente añadido
debe ocupar todo el espacio asignado a su zona y, por omisión, no se deja espacio entre las
distintas zonas. Si sólo se incluye un componente y no se indica la zona, se coloca en la
zona central y ocupa todo el espacio disponible.

Ejemplo: A continuación se presenta el código que ayuda a crear un JDialog con el


administrador de diseño BorderLayout, así como los elementos que administra.

package interfacesGraficas;

import [Link].*;
import [Link].*;

public class EjemBorderLayout extends JDialog {


public EjemBorderLayout() {
JButton b1, b2, b3, b4, b5;
b1 = new JButton(“Botón 1 (CENTER)”);
b2 = new JButton(“Segundo Botón (NORTH)”);
b3 = new JButton(“3 Botón (SOUTH)”);
b4 = new JButton(“Bot. 4 (EAST)”);
b5 = new JButton(“Botón5 (WEST)”);
// Se obtiene el panel de contenido
Container panelContenido = getContentPane();
// Se añaden los botones al panel de contenido
[Link](new BorderLayout());
[Link](b1, [Link]);
[Link](b2, [Link]);
[Link](b3, [Link]);
[Link](b4, [Link]);
[Link](b5, [Link]);
Gráfico 21. Administrador de Diseño BorderLayout
}
public static void main(String[] args) {
EjempBorderLayout Border = new EjemBorderLayout();
[Link](“Administrador de Diseño:
BorderLayout”);
[Link]();
[Link](true);
}
}

El administrador BorderLayout proporciona dos constructores: uno vacío BorderLayout() y


otro en el que se puede especificar en píxeles una separación horizontal y vertical entre las
zonas BorderLayout(int horizontalGAP, int verticalGAP).

o GridLayout: con este administrador los componentes se colocan en una matriz de celdas
(definida por el número de filas y columnas) que ocupa todo el espacio asignado al

Curso de Java Standard Edition – J2SE 125


contenedor. Todas las celdas son iguales y los componentes utilizan todo el espacio
disponible para cada celda.

Al añadir los componentes se va rellenando la matriz primero por filas, cuando una fila está
llena se pasa a la siguiente. Proporciona dos constructores, uno en el que solo se indican el
número de filas y el número de columnas de la matriz GridLayout(int filas, int cols) y
otro en el que además, se especifica en píxeles la separación horizontal y vertical entre
celdas GridLayout(int filas, int cols, int horizontalGAP, int verticalGAP). Por lo
menos uno de los argumentos que especifican el número de filas o columnas debe ser
distinto de cero. Por omisión no hay espacio de separación entre las celdas.

Ejemplo: A continuación se presenta un ejemplo que puede ubicar nueve botones en tres
filas y tres columnas.

package interfacesGraficas;

import [Link].*;
import [Link].*;

public class EjemploGridLayout extends JFrame {

public EjemploGridLayout() {
// Se obtiene el panel de contenido
Container panelContenido = getContentPane();
// Se añaden los botones al panel de contenido
[Link](new GridLayout(3, 3));
[Link](new JButton(“Botón 1”));
[Link](new JButton(“2 Botón”));
[Link](new JButton(“Botón 3”));
[Link](new JButton(“4 Botón”));
[Link](new JButton(“Botón 5”));
[Link](new JButton(“6 Botón”));
[Link](new JButton(“Botón 7”));
[Link](new JButton(“8 Botón”));
[Link](new JButton(“Botón 9”));
}
public static void main(String[] args) {
EjemploGridLayout Grid = new EjemploGridLayout();
[Link](“Administradores de Diseño: GridLayout”);
[Link]();
[Link](true);
}
}

Grafico 22. Administrador de Diseño FlowLayout

Curso de Java Standard Edition – J2SE 126


o CardLayout: este administrador de disposición permite gestionar distintos componentes
que ocupan un mismo espacio de forma que en cada momento sólo uno de ellos es visible.
Utiliza la idea de PILA en donde solo es visible el primer componente, de modo que para
visualizar los otros hay que ir poniéndolas sucesivamente en la parte superior. La ordenación
de la pila viene determinada por el orden en el que se han añadido los componentes. Estos
son los métodos de uso más frecuente en CardLayout:

METODO FUNCIONALIDAD
CardLayout() y CardLayout(int, int) Constructores. Se puede proporcionar la separación
void add(String, Object) Añade un componente al contenedor y le da nombre
void first(Container) Selecciona el primer componente, el último, el
void last(Container) siguiente o el componente anterior del mazo. Al ser
void next(Container) seleccionado se muestra automáticamente. El orden
void previous(Container) es según se han añadido al contenedor.
void show(Container, String) Muestra el componente cuyo nombre se proporciona

package interfacesGraficas;

import [Link].*;
import [Link].*;
import [Link].*;

public class EjemploCardLayout extends JFrame implements ItemListener{


JPanel cards;
public EjemploCardLayout() {
// Se obtiene el panel de contenido
Container panelContenido = getContentPane();
// Se añaden los botones al panel de contenido
[Link](new BorderLayout());
// Se crea y agrega el combo de selección de elementos
JPanel cp = new JPanel();
Choice c = new Choice();
[Link](“JButton”); [Link](“TextField”); [Link](“JLabel”); [Link](this);
[Link](c);
[Link]([Link], cp);
// Se crean y agregan los componentes a sobreponer
cards = new JPanel();
[Link](new CardLayout());
JPanel p1 = new JPanel(); [Link](new JButton(“Botón 1”));
JPanel p2 = new JPanel(); [Link](new TextField(“TextField”, 20));
JPanel p3 = new JPanel(); [Link](new TextArea(“JLabel”,20));
[Link](“JButton”, p1); [Link](“TextField”, p2); [Link](“JLabel”, p3);
Gráfico [Link] de Diseño CardLayout
[Link]([Link], cards);
}
public void itemStateChanged(ItemEvent ie) {
CardLayout c1 = (CardLayout) ([Link]());
[Link](cards, (String) [Link]());
}
public static void main(String[] args) {
EjemploCardLayout Card = new EjemploCardLayout();
[Link](“Administradores de Diseño: CardLayout”);
[Link](); [Link](true);
}}

Curso de Java Standard Edition – J2SE 127


o GridBagLayout: es el administrador de disposición más versátil y funcional, ya que permite
organizar los componentes tanto verticalmente como horizontalmente, aunque tengan
distinto tamaño. Con este propósito mantiene una malla dinámica rectangular de celdas,
donde las filas y columnas pueden tener distinto tamaño, en las que se sitúan los
componentes. Un componente puede ocupar varias celdas contiguas. La situación y espacio
ocupado por cada uno de los componentes se describe por medio de restricciones
(constrains). A cada componente se le asocia un objeto de la clase GridBagConstrains
que especifica las restricciones y que, junto con las indicaciones de tamaño del componente
(tamaño mínimo y preferido), determinan la presentación final del objeto en el contenedor.

CONSTRAINS DESCRIPCIÓN
Especifica la celda superior izquierda en el área de pantalla del
componente, donde la celda superior izquierda tiene la dirección gridx=0,
[Link] gridy=0. el valor por omisión, [Link] indica
[Link] que el componente debe simplemente colocarse a la derecha de (para
gridx) o justo debajo del (para gridy) componente que se añadió al
contenedor justo antes de que este componente fuera añadido.
Especifica el número de celdas en una fila (gridwidth) o columna
(gridheight) en el área de pantalla del componente. El valor
[Link]
predeterminado es 1. [Link] indica que el
[Link]
componente tiene que ser el último en su fila (gridwith) o columna
(wridheight).
Se utiliza cuando el área de pantalla del componente es mayor que el
tamaño solicitado del componente, a fin de averiguar si debe, y cómo,
redimensionar el componente. Los valores posibles para éste son:
[Link] (valor por omisión),
[Link] [Link] (para hacer suficientemente ancho
al componente para rellenar su área en forma horizontal),
[Link](para hacer suficientemente alto al
componente para rellenar su área en forma vertical) y
[Link] (para que rellene toda su área).
Especifica el relleno interno del componente dentro del diseño. Nos dice
cuánto más se necesita añadir al tamaño mínimo del mismo. El ancho del
[Link] componente debe ser al menos el ancho mínimo más ipadx*2 píxeles.
[Link] Esto es debido a que el relleno se aplica a ambos lados del componente.
En forma similar, la altura del componente debe ser al menos la altura
mínima más ipdy*2 píxeles.
Especifica el relleno externo del componente, la cantidad mínima de
[Link]
espacios entre el componente y los límites de su área de pantalla.
Se usa cuando el componente es más pequeño que su área de pantalla y
permite determinar dónde tiene que colocarse el componente, dentro del
área de pantalla. Los valores válidos son: GridBagConstraints..CENTER
(valor por omisión). Los otros valores válidos son:
[Link]
[Link], [Link],
[Link], [Link],
[Link], [Link],
[Link], [Link].
Permite determinar como distribuir el espacio, cuando se especifica el
comportamiento de cambio de tamaño. Si no especificamos un peso para
al menos un componente en una fila (weightx) y columna (weighty), todos
[Link]
los componentes que han sido ubicados se amontonarán en el centro del
[Link]
contenedor. Esto ocurre porque el GridBackLayout coloca todo el espacio
extra entre su malla de celdas y los límites del objeto contenedor, cuando
el peso es cero.

Ejemplo: El siguiente código genera tres componentes, administrados por GridBagLayout.:

Curso de Java Standard Edition – J2SE 128


package interfacesGraficas;

import [Link].*;
import [Link].*;

public class EjemploGridBagLayout extends JFrame {


public EjemploGridBagLayout() {
/** Se obtiene el panel de contenido * */
Container panelContenido = getContentPane();
GridBagLayout gb1 = new GridBagLayout();
[Link](gb1);
/** CREA UN CAMPO DE TEXTO * */
JTextField display = new JTextField(12);
// Añade las restricciones para el campo de texto
GridBagConstraints displayConstraints = new
GridBagConstraints();
[Link] = 0;
[Link] = 0;
[Link] = 4;
[Link] = 1;
[Link] = [Link];
// Añade el campo de texto
[Link](display, displayConstraints);
[Link](display);
/** CREA UN BOTÓN LIMPIAR * */
JButton clear = new JButton(“Limpiar”);
// Añade las restricciones para el Boton
GridBagConstraints clearConstraints = new
GridBagConstraints();
[Link] = 0;
[Link] = 1;
[Link] = 1; Gráfico 24. Administrador de Diseño
[Link] = 1; GridBagLayout
[Link] = [Link];
[Link] = new Insets(3, 3, 3, 3);
// Añade el boton
[Link](clear, clearConstraints);
[Link](clear);
/** CREA UN BOTÓN IGUAL * */
JButton equal = new JButton(“Igual”);
// Añade las restricciones para el Boton
GridBagConstraints equalConstraints = new
GridBagConstraints();
[Link] = 1;
[Link] = 1;
[Link] = 1;
[Link] = 1;
[Link] = [Link];
[Link] = new Insets(3, 3, 3, 3);
// Añade el boton
[Link](equal, equalConstraints);
[Link](equal);
}
public static void main(String[] args) {
EjemploGridBagLayout egbl = new EjemploGridBagLayout();
[Link](“Administradores de Diseño: GridBagLayout”);
[Link]();
[Link](true);
}
}

Curso de Java Standard Edition – J2SE 129


4. EVENTOS

El usuario se comunica con una aplicación con interfaz gráfica, mediante la interacción con dicha
interfaz (por ejemplo, se pulsa el ratón o se escribe texto). Como resultado de estas acciones se
generan eventos. El tratamiento o gestión de estos eventos, mediante la ejecución de un método o
métodos en el que se responde a la acción del usuario, es la forma de obtener la interactividad de la
aplicación. Este modo de programar se denomina programación dirigida por eventos.

4.1. MODELO DE DELEGACIÓN DE EVENTOS

En Java el tratamiento de los eventos se realiza mediante el Modelo de Delegación de


Eventos. La idea básica del modelo es que el tratamiento de un evento que ocurre en un objeto
(objeto fuente) no se realiza en ese mismo objeto, sino que se delega en otro objeto diferente
(objeto oyente). Este modelo se basa en la posibilidad de propagación o envío de eventos
desde el objeto fuente donde se producen a los objetos oyentes que los gestionan. La forma de
hacerlo es la siguiente:
o El objeto fuente registra qué objetos oyentes están interesados en recibir algún evento
específico, para comunicárselo una vez éste se produzca.
o Cuando ocurre el evento, el objeto fuente se lo comunica a todos los oyentes registrados.
o La comunicación entre la fuente y el oyente se realiza mediante la invocación de un
método del oyente, proporcionado como parámetro el evento generado.

Un evento es un objeto en el que se encapsula toda la información sobre la


interacción del usuario con los componentes de la interfaz gráfica. Por tanto, cuando un
oyente recibe un evento dispone de toda la información asociada a dicha interacción. Existe una
jerarquía de clases de eventos, en las que cada tipo de evento se representa mediante una clase
diferente.

Esta separación entre fuente y oyente facilita la creación de código robusto para la gestión de
eventos. Además, esto permite una separación clara entre el código propio de la aplicación
(modelo), el código que genera la interfaz (vista) y el código que gestiona la interfaz
(controlador).

Se pasa el EVENTO LISTENER


a los oyentes (CONTROLADOR)
ACCIÓN DEL
USUARIO
Procesa el evento
COMPONENTE
(VISTA)

Objeto Fuente
LISTENER 2
(CONTROLADOR)
Se pasa el EVENTO
a los oyentes Procesa el evento

Gráfico 25. Modelo de delegación de eventos

Es de hacer notar, que este modelo de tratamiento de eventos es simple pero muy versátil y fácil
de ampliar, ya que un objeto fuente puede tener registrados varios oyentes y un mismo oyente
puede estar registrado en varios objetos fuente.

Curso de Java Standard Edition – J2SE 130


4.2. EVENTOS, OBJETOS FUENTE Y OBJETOS OYENTE

En función de la interacción concreta que realice el usuario y dependiendo de qué tipo de


componente gráfico esté implicado se producirán uno o varios eventos. Dicho componente es el
objeto fuente en el que se crea un evento de la clase correspondiente, que se transmite al
oyente u oyentes que lo gestionan. Para poder gestionar el registro y eliminación de objetos
oyentes (Listeners) de cada evento concreto se proporcionan tres métodos:

o void set<TipoEvento>Listerner(Listener obj): establece un objeto oyente para el


TipoEvento.
o void add<TipoEvento>Listener(Listener obj): añade el objeto a la lista de oyentes.
o void remove<TipoEvento>Listener(Listener obj): elimina el objeto oyente
correspondiente.

Los eventos están representados en una jerarquía de clases cuya raíz es la clase
[Link]. Esta clase tiene como único atributo el objeto en el que se ha generado
el evento y proporciona el método Object getSorce(), para acceder a él. El resto de las clases
que la especializan representan tipos de eventos concretos y encapsulan toda la información
necesaria para dar respuesta a ese tipo de interacción (por ejemplo, qué botón del ratón se ha
presionado, el instante y la posición donde se ha producido, si se tenía presionado alguna trecla
modificadora tal como Ctrl. O AltGr, etc.). Esta información se obtiene mediante los métodos de
acceso correspondientes get<Atributo>().

Un objeto oyente o Listener aquel que gestiona, maneja o responde a un evento. Con este
propósito define uno o varios métodos que serán ejecutados automáticamente por la fuente de
eventos en respuesta a cada tipo de evento específico. En esta llamada automática al método
correspondiente del oyente se pasa como argumento un objeto de la clase de evento generada.

En el tratamiento o gestión de eventos hay que seguir tres pasos:

Crear una clase oyente del tipo de eventos que implemente la interfaz Java
n correspondiente.

Implementar en la clase oyente el método o métodos de la interfaz Java


o correspondiente.

Crear un objeto de la clase oyente y registrarlo como Listener de uno o más


p componentes gráficos en los que se desea proporcionar esa interacción con el usuario.

Ejemplo: A continuación se presenta un ejemplo sencillo en el que se crea una aplicación con
una interfaz gráfica para ilustrar la gestión de eventos.

La interfaz gráfica de la aplicación consta de una ventana principal en la que se presenta una
etiqueta y dos botones. La etiqueta y los botones se agrupan añadiéndolos a un panel
contenedor que después se añade al panel de contenido de la ventana principal.

En la aplicación se incluye una clase interna que actúa como oyente de eventos de tipo acción
(ActionListener) para gestionar las interacciones con los botones. En esta clase, como respuesta
a la pulsación por parte del usuario, el programa modifica el texto de la etiqueta indicando el
botón que ha pulsado. Nótese que se registra el mismo objeto oyente en dos objetos fuente
diferentes (los dos botones). Una clase interna es muy adecuada, ya que tenemos acceso
a todos los elementos de la clase en la que está definida (en este caso la etiqueta).
package interfacesGraficas;

Curso de Java Standard Edition – J2SE 131


import [Link].*;
import [Link].*;

public class EjemploEventos extends JFrame {


// Componentes de la ventana
JLabel etiqueta;
JButton botonHola;
JButton botonAdios;
JPanel panel;

public EjemploEventos() {
// Se crean los componentes de la ventana
etiqueta = new JLabel("Etiqueta inicial");
botonHola = new JButton("Hola");
botonAdios = new JButton("Adios");
panel = new JPanel();
// Se añaden los componentes al panel
[Link](etiqueta);
[Link](botonHola);
[Link](botonAdios);
// Añade el panel a la venta principal
getContentPane().add(panel);
// Se crea un objeto oyente de acción que se registra en los dos botones
OyenteAccion oyenteBoton = new OyenteAccion();
[Link](oyenteBoton);
p [Link](oyenteBoton);
}
public static void main(String[] args) {
EjemploEventos ventana = new EjemploEventos();
[Link]("Ejemplo simple de Eventos");
[Link](350, 70);
[Link](true);
}
/**
* CLASE INTERNA: Se crea la Clase Oyente de Eventos de acción (ActionListener)
*/
n class OyenteAccion implements ActionListener {
public void actionPerformed(ActionEvent evento) {
// Se obtiene el botón fuente del evento
JButton boton = (JButton) [Link]();
// Tratamiento del evento
o if ([Link]().equalsIgnoreCase("Hola"))
[Link]("Se ha presionado el botón HOLA");
else if ([Link]().equalsIgnoreCase("Adios"))
[Link]("Se ha presionado el botón ADIOS");
}
}

Gráfico 26. Ejemplo de manejo de eventos

Curso de Java Standard Edition – J2SE 132


4.3. JERARQUÍA Y TIPOS DE EVENTOS

Como se ha mencionado previamente, los eventos se organizan en una jerarquía de clases,


donde cada clase representa un tipo de evento o un grupo de eventos relacionados, cuya raíz es
[Link]. Esta clase deriva de la clase [Link] para tener en
cuenta los eventos generados por los componentes gráficos.

En el paquete [Link] se encuentran la mayoría de las definiciones de clases e


interfaces necesarias para la gestión de eventos generados en una interfaz gráfica sencilla. Con
la aparición de Swing este paquete se ha visto complementado por [Link], donde
se representan los eventos propios de las nuevas características propias de Swing.

Conceptualmente los eventos generados en los componentes gráficos se pueden clasificar en:
o Eventos de bajo nivel: éstos están relacionados con los aspectos físicos de la
interacción con los elementos de la interfaz. Representan las modificaciones en el sistema
de ventanas (por ejemplo cambio de tamaño, cambio de posición, obtención o pérdida del
foco) o las entradas producidas por el usuario (con el teclado o ratón).
o Eventos semánticos (o de alto nivel): representan la operación con un elemento de la
interfaz. Se denominan semánticos porque tratan de capturar el significado de la
interacción, por ejemplo seleccionar un elemento. No están relacionados con una clase
específica de componente, siendo aplicables a todos los componentes que implementen
un modelo de operación similar. No obstante, estos componentes no tienen que generar
dicho evento de la misma forma, por ejemplo, el evento ActionEvent se genera cuando
se hace clic sobre un botón o cuando se pulsa la tecla Intro en un campo de texto.

EVENTOS DE BAJO NIVEL


EVENTO DESCRIPCIÓN
ComponentEvent Cambios en el tamaño, posición o visibilidad de un componente
Cambio de foco (capacidad de un componente para recibir entradas
FocusEvent
desde el teclado)
KeyEvent Operación con el teclado
MouseEvent Operación con los botones del ratón o movimientos del ratón
WindowEvent Cambio de estado en una ventana
Cambio en la composición, visibilidad o posición de un elemento
AncestorEvent
superior (ancestro) de la jerarquía de composición
EVENTOS DE ALTO NIVEL
EVENTO DESCRIPCIÓN
ActionEvent Realización de una acción específica asociada al componente
ChangeEvent Cambio de estado del componente
ItemEvent Elemento seleccionado o deseleccionado
Cambio en la posición del cursor de inserción en un componente que
CaretEvent
gestiona texto
ListSelectionEvent Cambio en la selección actual en una lista

Curso de Java Standard Edition – J2SE 133


4.4. CLASES OYENTES DE EVENTOS (LISTENERS)

Un Listener es el objeto que es notificado siempre que se genera un evento. Tiene dos
requerimientos principales: el listener debe ser registrado con una o más fuentes para recibir
notificaciones cuando un evento específico se genere, y también debe implementar métodos para
recibir y procesar estas notificaciones.

Como se explico anteriormente, el modelo de delegación de eventos tiene dos partes: los objetos
fuente y los listeners. Los listeners se crean implementando una o más de las interfaces definidas
por el paquete [Link]. Cuando ocurre un evento, el fuente invoca al método apropiado
definido por el listener y le proporciona el objeto evento como su parámetro. A continuación se
listan algunos de los Listeners más importantes:

LISTENER DESCRIPCIÓN MÉTODOS


Define un método para recibir
ActionListener void actionPerformed(ActionEvent)
eventos de acción
Define dos métodos para
reconocer instancias cuando un void focusGained(FocusEvent)
FocusListener
componente adquiere o pierde el void focusLost(FocusEvent)
control del teclado (Foco)
Define tres métodos para void keyPressed(KeyEvent)
KeyListener reconocer cuándo se presiona, void keyReleased(KeyEvent)
libera o golpea una tecla void keyTyped(KeyEvent)

Define siete métodos para void mouseClicked(MouseEvent)


identificar instancias cuando el void mouseEntered(MouseEvent)
MouseListener ratón hace clic, entra a un void mouseExited(MouseEvent)
componente, sale del void mousePressed(MouseEvent)
componente, presiona o liber void mouseReleased(MouseEvent)
Define 2 métodos para cuando void mouseDragged(MouseEvent)
MouseMotionListener
se arrastra o se mueve el ratón void mouseMoved(MouseEvent)
Define un método de identificar
TextListener void textChanged(TextEvent)
cambios en los valores de texto
void windowActivated(WindowEvent)
Define siete métodos para void windowClosed(WindowEvent)
identificar instancias cuando una void windowDeactivated(WindowEvent)
WindowListener ventana se activa, se cierra, se void windowDeiconfied(WindowEvent)
restaura, se minimiza (iconiza), void windowInconfied(WindowEvent)
se abre o se sale de ella void windowOpened(WindowEvent)
void windowClosing(WindowEvent)

4.5. CLASES ADAPTADORAS DE EVENTOS

La mayoría de la interfaces oyentes están diseñadas para responder a varios eventos diferentes,
de modo que incluyen más de un método. Por ejemplo, el oyente de interacciones de ratón
(MouseListener) contiene cinco métodos relacionados con la operación de los botones y el
movimiento del mismo; esto provoca que la clase oyente deba implementarlos todos, aunque
sólo le interese alguno de ellos, y deje vacíos los otros (si no lo hace la clase sería abstracta).

Curso de Java Standard Edition – J2SE 134


Para simplificar la escritura de Listeners Java proporciona un conjunto de clases adaptadoras
abstractas, que incluyen las definiciones vacías de los métodos correspondientes. Así un oyente
se puede crear especializando un adaptador e implementando sólo el método que interese. En
Java se incluye una clase adaptadora por cada Listener que tiene más de un método.

CLASE ADPTADORA INTERFAZ LISTENER


FocusAdapter FocusListener
KeyAdapter KeyListener
MouseAdapter MouseListener
MouseMotionAdapter MouseMotionListener
WindowAdapter WindowListener

package interfacesGraficas;
import [Link].*;
import [Link].*;

public class EjemploAdapters extends JFrame {


public JLabel etiqueta;
public EjemploAdapters() {
// agregar el componente gráfico
etiqueta = new JLabel("Eventos:");
getContentPane().add(etiqueta);
// Registrar los oyentes de evento
addMouseListener(new MyMouseAdapter(this));
addMouseMotionListener(new yMouseMotionAdapter(this));
}
public static void main(String[] args) {
EjemploAdapters ventana = new EjemploAdapters();
[Link]("Ejemplo de Clases Adpatadoras");
[Link](300, 200);
[Link](true);
}
}
// Clase adaptadora para eventos de Acciones del Ratón
class MyMouseAdapter extends MouseAdapter {
EjemploAdapters fuente; // Objeto de referencia al fuente
public MyMouseAdapter(EjemploAdapters obj) {
fuente = obj;
}
// Maneja el click del ratón
public void mouseClicked(MouseEvent me) {
[Link]("Click del ratón...");
}
}
// Clase adaptadora para eventos de Movimiento del Ratón
class MyMouseMotionAdapter extends MouseMotionAdapter {
EjemploAdapters fuente; // Objeto de referencia al fuente
public MyMouseMotionAdapter(EjemploAdapters obj) {
fuente = obj;
} Gráfico 27. Ejemplo de Clases
// Maneja el arrastre del ratón Adaptadores de Evento
public void mouseDragged(MouseEvent me) {
[Link]("Ratón arrastrado...");
}
}

Curso de Java Standard Edition – J2SE 135


4.6. EVENTOS Y COMPONENTES GRÁFICOS

Los distintos componentes gráficos de una aplicación pueden generar o ser fuentes de eventos y
para cada uno de ellos se puede registrar un oyente correspondiente. Un evento que pueda
generar una clase determinada, también lo podrá generar cualquiera de sus especializaciones o
clases derivadas. Por ejemplo todos los componentes son capaces de generar FocusEvent,
KeyEvent, MouseEvent y MouseMotionEvent, ya que son los eventos generados por la clase
[Link] de la que son especializaciones los componentes gráficos.

En la Tabla siguiente se presentan los componentes de uso más frecuente junto con los eventos
que pueden generar.

COMPONENTE EVENTOS QUE PUEDE GENERAR


Swing ActionEvent ItemEvent ChangeEvent CaretEvent ListSelectionEvent
JButton X X X

JCheckBox X X X

JComboBox X X

JTextField X X

JRadioButton X X X

JList X

JTextArea X X

JMenuItem X X

JTabbedPane X

JToggleButton X X X

JPasswordField X X

JEditorPane X

Curso de Java Standard Edition – J2SE 136


APÉNDICE I: Herramientas y Utilidades de desarrollo - BÁSICAS

1. COMPILACIÓN Y EJECUCIÓN DE PROGRMAS JAVA (JAVAC/JAVA)

Para crear un programa fuente de Java se puede utilizar cualquier editor de texto, como Bloc de
Notas. Una vez copiado el programa, se guarda el archivo con el mismo nombre de la clase
(respetando mayúsculas y minúsculas) y con extensión .java. Adicionalmente, existen editores
especializados para Java, tales como JCreator, Eclipse, NetBeans, etc., que proporcionan un IDE que
facilita el proceso de creación de programas Java.

Se procede entonces a compilar el programa copiado usando el comando javac. Este comando
genera el código binario del programa en un archivo con el mismo nombre del programa copiado
pero con extensión .class. La sintaxis del comando es la que sigue:

javac [Link]

Para ejecutar el programa, simplemente se ejecuta el comando java. Dicho comando despierta a la
JVM y es esta la que se encarga de ejecutar el programa (interpretar su código binario). La sintaxis
del comando es la que sigue:

java NombreCompletoDeLaClase

En la grafica siguiente se describe el proceso de compilación y ejecución de programas Java:

PROGRAMA
FUENTE JAVA

(.JAVA)

COMPILACIÓN
(JAVAC)

CÓDIGO BINARIO
(.CLASS)

EJECUCIÓN
(JAVA)

RESULTADOS DE LA
EJECUCIÓN

Curso de Java Standard Edition – J2SE 137


1.1. EJEMPLO

Paso 1: Haga clic en el menú Inicio y seleccione Programas Æ Accesorios Æ Bloc de Notas.

Paso 2: Escriba el siguiente código.

package myPack;

/**
* Ejemplo de un programa Java simple
* @autor Ronel J. Rivas R.
* @version 1.0, Septiembre de 2005
*/

public class a {

/**
* Este método transforma una cadena a un entero
* @param cad String que representa la cadena a transformar
* @return Un int que representa el valor numérico de la cadena
*/
public static int strToInt(String cad) {
return [Link](cad);
}

/**
* Programa Principal
* @param args No utilizado
* @return Nada
*/
public static void main(String[] args) {
int r = 0;

for(int i=0; i<[Link]; i++)


r+=strToInt(args[i]);

[Link]("El resultado es " + r + ".");


}

Paso 3: Una vez copiado, haga clic en Guardar en el menú Archivo. Guarde el archivo con el
nombre [Link] en el directorio Z:\myPack (si no existe el directorio, créelo).

Paso 4: Abra una consola del sistema. Para ello, haga clic en el menú Inicio y seleccione Ejecutar.
Aparecerá un cuadro de diálogo donde debe escribir cmd. Se abrirá una consola del intérprete de
comandos de Windows. Cámbiese al directorio raíz (C:\), escribiendo cd\.

Paso 5: Escriba el siguiente comando para compilar el programa: javac [Link]

Paso 6: Se ha generado el código binario. Escriba el siguiente comando para ejecutar el programa:
java SumarEnteros 1 2 4 3

La salida podrá ser vista en el intérprete de comandos, y será algo como esto: El resultado es 10

Curso de Java Standard Edition – J2SE 138


2. EL DOCUMENTADOR DE JAVA (JAVADOC)

Java soporta tres tipos de comentarios.; los primeros dos son // y /* */, que permiten realizar una
aclaratoria dentro del código del programa. El tercer tipo es denominado comentario de documento,
y comienza con la sucesión de caracteres /** y finaliza con */. Los comentarios de documentación
le permiten insertar información acerca de su programa dentro de él mismo. Entonces, puede utilizar
el programa de utilidad javadoc para extraer ésta información y ponerla dentro de un archivo HTML.
Los archivos HTML generados por la aplicación javadoc, son idénticos a la documentación de la API
de Java.

2.1. ETIQUETAS javadoc

La utilidad javadoc reconoce las siguienteS etiquetas:

ETIQUETA SIGNIFICADO SINTAXIS


@autor Identifica al autor de una clase @autor nombreAutor
Especifica que una clase o miembro está
@deprecated @deprecated descripcion
deprecado
Especifica la ruta para el directorio raíz de la
{@docRoot} {@docRoot} ruta
documentación actual
@excepcion Identifica una excepción lanzada por un métodos @excepcion Excepcion Explicación
{@link nombre} nombre es el nombre
{@link} Inserta un vínculo en línea a otro tema de la clase o método al que se está
haciendo el hipervínculo
@param Documenta los parámetros de un método @param parámetro Explicación
Documenta un valor de retorno para un
@return @return Explicación
método
@see ancla: hipervínculo a un URL
@see [Link]#miembro: es un
@see Especifica un vínculo a otro tema
hipervínculo a un paquete, clase o
miembro
@serial Documenta un campo seriado por omisión @serial descripcion
Documenta los datos escritos por los métodos
@serialData @serialData descripcion
writeObject() o writeExternal()
Documenta un componente de
@serialField @serialField nombre tipo descripción
ObjectStreamField
Establece actualizaciones en la que se
@since @since actualización
introdujo un cambio específico
@throws Lo mismo que excepción @throws Excepcion Explicación
@version Especifica la versión de una clase @version número

Como se puede observar, todas las etiquetas de documentación comienzan con un signo @. En un
comentario de documentación, también se pueden utilizar otras etiquetas estándar
(<TAG></TAG>) de HTML. Sin embargo, algunas etiquetas tales como un título no pueden ser
empleadas, porque desorganizan la apariencia del archivo HTML producido por javadoc.

Curso de Java Standard Edition – J2SE 139


Puede utilizar los comentarios de documentación para documentar clases, interfaces, variables,
constructores y métodos. En todo caso, los comentarios de documentación deben preceder
inmediatamente al punto del código que esté siendo documentado.

Las siguientes son algunas sugerencias en el orden de las etiquetas de documentación, a la hora de
documentar su código:
- Clases e interfaces: @see, @author, @since, @serial, @version y @deprecated
- Variables: @see, @since, @serial, @serialfield y @deprecated
- Métodos y Constructores: @see, @since, @param, @exception, @throws, @return,
@serialData y @deprecated

2.2. FORMA GENERAL DE LOS COMENTARIOS DE DOCUMENTACIÓN

Después del /** inicial, la primera línea o líneas llegan a ser la descripción principal de su clase,
variable o método. Después de eso, puede incluir uno o más rótulos @ (Etiquetas). Cada rótulo @
debe arrancar al comienzo de la nueva línea, o a continuación de un asterisco (*) que está al
comienzo de la línea. Múltiples rótulos del mismo tipo deben ser agrupados juntos. Ejemplos de
Comentarios de Documentación para:

- Clase:
/**
* Esta clase dibuja un gráfico de barras
* @autor Ronel J. Rivas R.
* @version 1.0, Septiembre de 2005
*/
public class JBar {

}

- Variable:
/**
* Nombre del usuario, para ser utilizado en la verificación de acceso
* @see [Link]#password
*/
String userName;

- Método:
/**
* Este método introduce un número del usuario por teclado
* @param args Representa la entrada del usuario en forma de cadena
* @exception IOException En error de entrada
* @see IOException
* @return Un int que representa la entrada del usuario como número
*/
public int obtenerNumero(String args) throws IOException {

}

2.3. EJECUTAR EL javadoc

La forma de ejecutar el documentador de java es la siguiente:

javadoc [Link]

Curso de Java Standard Edition – J2SE 140

También podría gustarte