Sunteți pe pagina 1din 1025

BENEMRITA UNIVERSIDAD

AUTNOMA DE PUEBLA

FACULTAD DE CIENCIAS DE LA
COMPUTACIN

Programacin en
JAVA++

M. C. Eugenia Erica Vera Cervantes

CAPTULO I
JAVA

1.1 QU ES JAVA?

Sun describi a Java de la siguiente


forma:
Java: un lenguaje simple, orientado a
objetos, distribuido, interprete, robusto,
seguro, de arquitectura neutra, porttil,
de alto desempeo, de hilos mltiples y
dinmico.

Java es un lenguaje de programacin


orientado a objetos.

A diferencia de C++, Java se dise


desde un principio para estar orientado a
objetos. La mayora de las cosas en Java
son objetos; los primitivos tipos
numricos, carcter y booleano son la
nica excepcin. En Java, las cadenas se
representan con objetos, los hilos, etc.

Como

los programas de Java se


compilan en un formato de bytecode
de arquitectura neutral, una aplicacin
de Java se puede ejecutar en cualquier
sistema, siempre y cuando dicho
sistema instrumente la mquina virtual
de Java. Esto resulta muy importante
para las aplicaciones distribuidas en
Internet u otras redes heterogneas.

Para asegurar que los programas de Java


sean realmente independientes, de la
plataforma, hay una arquitectura nica
sobre la que se compilan todos los
programas en Java. Es decir, cuando se
compila para una plataforma en
Windows/Intel x86 se obtiene la misma
salida que la compilada en un sistema
Macintosh o Unix. El compilador no
compila para la plataforma de origen, sino
para una plataforma abstracta llamada
mquina virtual de Java, o JVM-Java
Virtual Machine.

Java tambin se le denomina


lenguaje distribuido. Esto significa,
simplemente, que proporciona un
soporte de alto nivel para redes. Por
ejemplo, la clase URL y las clases
relacionadas en el paquete java.net
hacen que la lectura de un archivo o
una fuente remota sea tan fcil como
leer un archivo local.

Java

se ha diseado para escribir


software robusto y muy confiable.

Una de las cosas que hace simple a Java

es la carencia de punteros y aritmtica


de puntero. Todos los accesos a arreglos
y cadenas se verifican al tiempo de
ejecucin. Las formas de los objetos de
un tipo a otro tambin se verifican al
momento de la ejecucin. La
recoleccin automtica de basura en
Java evita que la memoria tenga fugas,
as como la presencia de otros defectos
pernicios relacionados con la asignacin
y desasignacin de memoria.

El

manejo de excepcin es otra


caracterstica de Java que contribuye
a formar programas ms robustos.
Una excepcin es una seal de que
ha
ocurrido
una
condicin
excepcional, por ejemplo, un error
de no se puede encontrar el
archivo. Con esto puede simplificar
la tarea del manejo y recuperacin
de errores

Uno de los aspectos ms resonados de


Java es que se trata de un lenguaje
seguro. Proporciona varias capas de
controles de seguridad que protegen
contra cdigo malicioso; estas capas
permiten a los usuarios ejecutar con
comodidad programas desconocidos,
como los applet.

Java es un lenguaje de hilos mltiples;

proporciona soporte para varios hilos


de ejecucin que pueden manejar
diferentes tareas. Un beneficio
importante de los hilos mltiples es
que se mejora el desempeo
interactivo de las aplicaciones grficas
para el usuario.

1.2 JAVA VS C++

JAVA VS C++

Java se asemeja mucho a C y C++. Esta


similitud, evidentemente intencionada, es
la mejor herramienta para los
programadores, ya que facilita en gran
manera
su
transicin
a
Java.
Desafortunadamente, tantas similitudes
hacen que no nos paremos en algunas
diferencias que son vitales. La
terminologa utilizada en estos lenguajes,
a veces es la misma, pero hay grandes
diferencias
subyacentes
en
su
significado.

C tiene tipos de datos bsicos y


punteros. C++ modifica un poco este
panorama y le aade los tipos
referencia. Java tambin especifica sus
tipos primitivos, elimina cualquier tipo
de punteros y tiene tipos referencia
mucho ms claros.

Conocemos ya ampliamente todos los


tipos bsicos de datos: datos base,
integrados, primitivos e internos; que son
muy semejantes en C, C++ y Java;
aunque Java simplifica un poco su uso a
los desarrolladores haciendo que el
chequeo de tipos sea bastante ms rgido.
Adems, Java aade los tipos boolean y
hace imprescindible el uso de este tipo
booleano en sentencias condicionales.

1.3. JAVA ES
INDEPENDIENTE
DELAPLATAFORMA

La independencia de la plataforma es la
capacidad del programa de trasladarse
con
facilidad
de
un
sistema
computacional a otro.
Esta independencia de la plataforma es
una de las principales ventajas que tiene
Java sobre otros lenguajes de
programacin, en particular para los
sistemas que necesitan trabajar en
varias plataformas.

A nivel de cdigo fuente, los tipos


primitivos de datos Java, tiene tamaos
consistentes, en todas las plataformas
de desarrollo. Los fundamentos de
bibliotecas de Java facilitan la escritura
del cdigo, el cual puede desplazarse
de plataforma a plataforma sin
necesidad de volver a escribirlo.

Los archivos binarios Java, tambin son


independientes de la plataforma, y pueden
compilarse en mltiples plataformas sin
necesidad de volver a compilar la fuente,
esto se logra, ya que los archivos binario
Java, se encuentran en una forma llamada
Bytecode (conjunto de instrucciones
parecidas al lenguaje de mquina, pero
que no son especficas para un
procesador). El ambiente de desarrollo
Java tiene dos partes: un compilador y un
intrprete Java.

El compilador Java toma su programa


Java y en lugar de generar cdigos de
mquina para sus archivos fuente, genera
un bytecode. Para ejecutar un programa
Java debe utilizar un intrprete de
Bytecode el cual a su vez ejecuta su
programa Java. Puede ejecutar el
intrprete por si mismo o en el caso de los
applets puede recurrir a los visualizadores
que los ejecutan.

Interprete
Java

Compilador
Java
Cdigo de
Java

Pentium

Bytecode
de Java

PowerPC

SPARC

La desventaja de utilizar Bytecode se


halla en la velocidad de ejecucin,
puesto que los programas especficos
del sistema corren directamente en el
hardware en que se compilaron estos, ya
que los bytecodes deben ser procesados
por el intrprete.

1.4 SEGURIDAD EN JAVA

La seguridad es un aspecto importante


en Java, el visualizador baja el cdigo de
toda la red y lo ejecuta en el anfitrin del
usuario, se incluye varias capas de
seguridad tales como:

El

propio lenguaje Java incluye


restricciones cerradas de acceso a
memoria muy diferentes al modelo
de memoria que utiliza el lenguaje C.
Estas restricciones incluyen la
remocin de apuntadores aritmticos
y de operadores de conversin
forzada ilegales.

Una rutina de verificacin de cdigos

de Byte en el intrprete de Java


verifica que los cdigos de byte
(Bytecodes) no violen ninguna
construccin del lenguaje (lo que
podra suceder si utiliza un compilador
de Java alterado). Esta rutina de
verificacin se asegura de que el
cdigo no falsifique apuntadores,
memoria de acceso restringido u
objetos de acceso diferentes a los que
corresponden a sus definiciones.

Esta verificacin tambin asegura que


las llamadas al mtodo incluyen el
nmero correcto de argumentos del tipo
adecuado, y que no hay desbordamiento
de pilas.

Una verificacin del nombre de la


clase y de las restricciones de acceso
sobre la carga.

Una interfaz de sistema de seguridad


que refuerza las polticas de seguridad
en varios niveles.

Al nivel de acceso del archivo, si un

cdigo de byte intenta el acceso a un


archivo para el que no tiene permiso,
aparecer una caja de dilogo para
permitir que el usuario contine o
detenga la ejecucin.

Al

nivel de red, se tendrn


opciones
para
emplear
codificacin de clave pblica y
otras tcnicas de encriptacin para
verificar la fuente del cdigo y su
integridad despus de haber
pasado por la red. Esta tecnologa
de encriptacin ser la clave para
transacciones financieras seguras a
travs de la red.

Al momento de la ejecucin, puede

utilizarse la informacin sobre el


origen del cdigo de byte para
decidir lo que el cdigo puede hacer.
El mecanismo de seguridad puede
indicar si un cdigo de byte se
origin o no desde el interior de una
firewall (barrera de proteccin).
Tambin se puede definir una poltica
de seguridad que restrinja el cdigo
dnde no se confa.

1.5 ANIMACIN EN WEB

Principios de animacin
Los grficos animados son una reciente
adicin al rico contenido de multimedia
que est disponible en World Wide Web.
La creacin de animaciones efectivas
dentro de las limitaciones del entorno
Web puede ser una tarea agotadora para
el diseador Web.

Los principios bsicos de animacin


para medios de comunicacin tales
como la televisin o el cine, pueden ser
aplicados para las animaciones Web.

Las animaciones se crean a partir de


una secuencia de imgenes fijas. Las
imgenes se despliegan en una
secuencia tan rpida que el ojo las
percibe como movimiento continuo,
debido a un fenmeno denominado
persistencia de la visin. La
persistencia de la visin es la
tendencia del ojo y del cerebro a
continuar percibiendo una imagen an
despus de que haya desaparecido.

Este fenmeno es de gran importancia


ya que varios aparatos importantes para
la industria de la animacin lo
utilizaron, tal es el caso del rotoscopio,
el zeotropo, cinematgrafo, etc. para
producir animaciones
importantes.
Actualmente
se
utilizan
las
computadoras para producir una gran
variedad de animaciones y efectos para
pelculas y videos.

Animacin en Web
World Wide Web fue desarrollada a
principios de los 90 por Tim BernesLee. Inicialmente fue creada como una
forma de manejar
documentos de
hipertexto en redes clientes servidor
basadas en TCP/IP, por documentos
desplegados por software de cliente
denominador navegador.

Pronto, otros tipos de medios como los


grficos GIF y los archivos de audio
digital, fueron soportados por los
navegadores Web. Los grficos
animados son de las ltimas adiciones a
los tipos de medios soportados por
navegadores.

Existen diversas vas para aadir


grficos animados a pginas Web. Las
animaciones en lnea son aquellas que
aparecen directamente en una pgina
Web en su navegador, de manera muy
parecida a los archivos de imagen.
Tambin puede desplegar animaciones
desplegando animaciones auxiliares del
lado del cliente, que desplegaran
animaciones en ventanas separadas.

Las animaciones Web, son archivos de


computadora que necesitan transferirse
completamente a la mquina cliente
antes de que puedan empezar a
reproducirse. An los archivos de
animacin ms pequeos pueden ser
bastante largos y tardar mucho tiempo
en transferirse.

Transferencia
sincronizada

reproduccin

Algunos programas de animacin


utilizan formatos de datos propietarios
y una tcnica llamada streaming
(transferencia
o
reproduccin
sincronizada o en tiempo real ) como
medio para resolver los problemas en
la transferencia.

Streaming es la capacidad de algunos


medios cuyo formato o naturaleza est
basada en el tiempo, tales como la
animacin para comenzar antes de que
el archivo completo haya sido
transferido. El resto del archivo es
transferido desde el servidor en segundo
plano mientras la animacin o algn
otro medio basado en tiempo
se
reproduce en el cliente.

El streaming puede ser bastante difcil


de implantar debido a que los datos de
Internet se basan en paquetes y no
fueron diseados para la entrega de
datos continuos, sincronizados basados
en tiempo. Las interrupciones basadas
en el flujo de datos continuos pueden
causar tartamudeos y saltos en la
reproduccin de la animacin.

Formatos en la animacin
Otro problema con la animacin Web es
que cuando le ha llegado al usuario,
ste debe tener la aplicacin auxiliar o
plug-in apropiados para desplegar la
animacin.
Actualmente
existen
muchos formatos de animacin para
Web, con diferentes capacidades y usos.

La animacin GIF emplea una


extensin
especial
para
la
especificacin Gif y es soportada por la
mayora de los navegadores. Las
animaciones de Quick time utilizan el
formato de pelcula QuickTime
ampliamente soportado y de la
plataforma cruzada. Muchas de las
herramientas de autora para la
animacin
Web
pueden
hacer
conversiones entre estos dos formatos.

Las animaciones Java estn escritas en


el lenguaje de programacin Java, que
es de plataforma cruzada, mientras que
las animaciones
Shockwave estn
basadas
en
los
archivos
de
Macromedia Director. Otros formatos
de animacin propietarios incluyen
aquellos utilizados por los plug-ins de
Netscape de Totally Hip y de Future
Wave.

Animacin de un sitio Web con


Java
Con la llegada de Java, las pginas Web
dejaron de ser estticas, es decir, Java las
convierte en interactivas, interesantes y
atractivas. Java es una forma sencilla,
pero efectiva de empacar sonido y
animacin (que puede lucir como video)
sin plug-ins especiales. Java tambin
contiene otras capacidades importantes
tal es el caso de :

Java se ejecuta en la mayora de las


computadoras populares, sin importar
la plataforma, el nico requerimiento
es tener un navegador compatible,
como el HotJava de Sun
o el
Netscape Navigator.

Debido a los applets de Java son


realmente pequeos, se bajan con
rapidez del servidor y, se ejecutan en
la computadora cliente, son a su vez
rpidos y muy interactivos.

Ya que Java fue diseado de manera


especfica para Internet y se basa en
C++, es particularmente estable y
poderoso.

CAPTULO II
LENGUAJE JAVA

2.1 INSTRUCCIONES Y
EXPRESIONES

Una instruccin es lo ms sencillo que


se puede hacer en Java. Una
instruccin forma una sola operacin
Java. Todas las siguientes son
instrucciones Java sencillas:
int i =1;
import java.awt.Font;
System.out.println(Esta motocicleta es
+ color + + make);
m.engineState = true;

Algunas veces,
las instrucciones
regresan valores. Por ejemplo, cuando
sumamos dos valores o una prueba
para ver si un valor es igual al otro.
Este tipo de enunciados se llaman
expresiones.
Una instruccin puede ser escrita en un
solo rengln o en mltiples renglones
y el compilador Java lo entender
perfectamente.

Java tambin cuenta con instrucciones


compuestas, o bloques de instrucciones,
que pueden ser ubicadas en cualquier
parte en cualquier lugar donde pondra
una sola instruccin. Los enunciados de
bloques estn rodeados por llaves({}).

2.2 LA DECLARACIN
IMPORT (IMPORTAR)

La declaracin import hace que las


clases de Java estn disponibles para la
clase actual, bajo un nombre
abreviado. Las clases pblicas de Java
siempre estn disponibles va sus
nombres
totalmente
calificados,
siempre y cuando el archivo de la clase
en cuestin se pueda encontrar.

Hay dos formas de la declaracin


import:
import package.class;
import package.*;
La primera forma permite que la clase
especificada en el paquete especificado
se conozca por su nombre de clase
simplemente. Por ejemplo:

import java.awt.Graphics;
import java.awt.Color;
La segunda forma de la declaracin
import logra que todas las clases de un
paquete estn disponibles mediante su
nombre de clase. Por ejemplo:
import java.awt.*;

2.3 REGLAS DE ESCRITURA


DE UN PROGRAMA

Los

identificadores pueden iniciar


con una letra, un guin de subrayado(
_ ) o un signo de dlares ($), de
ninguna manera puede empezar con
un nmero. Despus del primer
carcter, los nombres pueden incluir
cualquier letra o nmero. Los
identificadores no pueden ser una
palabra clave de Java.

El lenguaje Java utiliza un conjunto

de caracteres Unicode. Esta es la


definicin del conjunto de signos que
no solo ofrece caracteres en el
conjunto estndar ASCII, sino
tambin varios millones de caracteres
para representar la mayora de los
alfabetos internacionales.

Esto significa que puede utilizar


caracteres acentuados y otros smbolos,
as como caracteres legales en nombre
de variables, siempre que cuenten con
un nmero de carcter Unicode sobre
00C0.
El lenguaje Java es sensible al
tamao de las letras, la cual significa
que las maysculas son diferentes de
las minsculas. La variable x es
diferente de X, rose no es Rose ni
ROSE.

Por convencin las variables Java


tienen nombres significativos, con
frecuencia formados de varias palabras
combinadas. La primera palabra est en
minsculas, pero las siguientes tienen
su letra inicial en maysculas.
Button the Button
Long reallyBigNumber;

Los espacios en blanco pueden hacer


que el cdigo sea ms fcil de leer.

Cada instruccin en Java termina con

un punto y coma, de no tenerlo, no se


compilar el programa Java.

Java tiene tres clases de comentarios.


Uno de ellos, los delimitadores /* y
*/, rodean comentarios en varias
lneas.

Estos comentarios no pueden anidarse,


no puede tener comentarios dentro de
los comentarios. Tambin puede
utilizar la doble diagonal (//) para una
solo lnea de comentario, donde todo el
texto hasta el final de la lnea se
ignora. El ltimo tipo de comentario
empieza con /** y termina con */.

El contenido de estos comentarios


especiales los emplea el sistema
Javadoc, pero a excepcin de ste, se
emplea de manera idntica que el primer
tipo de comentario. Javadoc se emplea
para generar la documentacin API del
cdigo.

2.4 VARIABLES Y TIPOS


DE DATOS

Las variables son lugares en la


memoria en donde pueden guardarse
valores; tiene un nombre, un tipo y un
valor. Antes de poder utilizar una
variable, primero debe declararla y a
partir de ah es factible asignarles
valores. De hecho Java posee tres
clases de valores: de instancia, de clase
y locales.

Las variables de instancia, se utilizan


para definir atributos o el estado de un
objeto en particular.
Las variables de clase son similares a
las variables de instancia, con la
diferencia de que sus valores se aplican
a todas las instancias de clase, en lugar
de tener diferentes valores para el
mismo objeto.

Las variables locales, se declaran y


utilizan dentro de la definicin de
mtodo, por ejemplo, para contadores de
ndice dentro de un ciclo, como variables
temporales, o para guardar valores que
solo necesita dentro de la definicin.
Tambin pueden usarse dentro de
bloques({}). Una vez que el mtodo o
bloque termina su ejecucin, la
definicin de variable y su mtodo dejan
de existir.

Aunque las tres clases de variables se


declaran en forma parecida, las variables
de clase y de instancia se accesan y se
asignan en formas poco diferente a las
variables locales

2.4.1 DECLARACION DE
VARIABLES

Para poder utilizar cualquier variable


dentro de un programa Java, debe
primero declararla. Las declaraciones
de variables consisten en un tipo y un
nombre de variable (identificador):
int miEdad;
string miNombre;
bolean estCansado;

La definicin de las variables pueden


ubicarse en cualquier lugar de la
definicin del mtodo, aunque por lo
comn se declaran al inicio de la
definicin antes de utilizarse:
public static void main (string args[ ]) {
int count;
String title;
Boolean isAsleep;
...
}

Se puede encadenar nombres de


variables con el mismo tipo:
int x, y, z;
String firstName, LastName;
Tambin se le puede dar a una
variable un valor inicial cundo se
declara:
String miNombre = Eric;
Boolean isAsleep = true;
int a = 4;

2.4.2 TIPOS DE
VARIABLES

Adems de los nombres de variables,


cada declaracin de variables debe de
tener su propio tipo, el cual define los
valores que esa variable puede contener.
El tipo de variable puede ser uno de
estos tres:

Uno de los ocho tipos de datos


primitivos
El nombre de una clase o interfaz
Un arreglo

Los ocho tipos de datos primitivos


manejan tipos comunes para enteros,
nmeros de punto flotante, caracteres y
valores boolanos. Se llaman primitivos,
porque estn integrados en el sistema y
no son objetos en realidad, lo cual hace
su uso ms eficiente.
Observe que estos tipos de datos son
independientes de la computadora, puede
confiar que su tamao y caractersticas
son consistentes en los programas Java.

Enteros
Existen cuatro tipos de enteros Java,
cada uno con un rango diferente de
valores, todos tienen signo.
Tipo Tamao
byte
8 bits
short 16 bits
int
long

Rango
-128 a 127
-32, 768 a 32, 767

32 bits

-2, 147, 483, 648 a 2, 147, 483,


647

64 bits

-9,223,372,036,854,775,808 a
9,223,372,036,854,775,807

Tambin puede forzar a un entero ms


pequeo a un long al agregarle una L o
l a ese nmero.
Los
enteros
tambin
pueden
representarse en sistema octal o
hexadecimal: un cero indica que un
nmero es octal (0777). Un 0x o 0X
inicial, significa que se expresa en
hexadecimal (0xFF, oXAF45).

Punto flotante
Los tipos de punto flotante contienen
ms informacin que los tipos enteros.
Las variables de punto flotante son
nmeros fraccionarios. Existen dos
subtipos de punto flotante : float y
double.
Puede forzar el nmero al tipo float al
agregarle la letra f o F a ese nmero
( 2.56f).

Tipo
Double
Float

Rango
-1.7x10-308 a 1.7x10308
-3.4x10-38 a 3.4x1038

Booleanos
El tipo booleano tiene dos valores:
True
y False (verdadero y falso).

Carcter
El tipo carcter representa un carcter
con base en el conjunto de caracteres de
Unicode. Este tipo se define con la
palabra
clave
char.
El
valor
correspondiente a un tipo de carcter
debe estar encerrado entre comillas
sencillas (). Se representa con un cdigo
de 16 bits, permitiendo 65,536 caracteres
diferentes: una magnitud mayor que la
del conjunto de caracteres ASCII/ANSI.

Los valores pueden aparecer en forma


normal como a,b,c o pueden
representarse con una codificacin
hexadecimal.
Estos
valores
hexadecimales comienzan con el
prefijo \u, a fin de que Java sepa que se
trata de un valor hexadecimal.
Por ejemplo, el retorno de carro en
hexadecimal es \u000d. El tipo char, al
igual que el booleano, no tiene un
gemelo numrico.

Sin embargo, el tipo char s puede


convertirse a enteros en caso necesario.
char coal;
coal =c;1
La siguiente tabla muestra los cdigos
especiales que pueden representar
caracteres no imprimibles, as como los
del conjunto de caracteres Unicode.

Escape
/n
/t
/b
/r
/f
//
/
/
/ddd
/xdd
/udddd

Significado
Lnea nueva
Tabulador
Retroceso
Regreso de carro
Alimentacin de forma
Diagonal inversa
Comilla sencilla
Comilla doble
Octal
Hexadecimal
Carcter Unicode

Cadenas y arreglos
Con excepcin de los tipos entero, de
punto flotante, booleano y carcter, la
mayora de los tipos restantes en Java
es un objeto. En esta regla se incluyen
las cadenas y los arreglos, los cuales
pueden tener su propia clase.

Las cadenas son slo una manera de


representar
una
secuencia
de
caracteres. Ya que no son tipos
integrados, tendr que declararlas
mediante la clase String. As como a
los tipos char se les da un valor entre
comillas sencillas (), a las cadenas se
les dan valores contenidos entre
comillas dobles (). Es posible unir
(concatenar) varias cadenas por medio
del signo ms (+).

Las cadenas no son simples arreglos


de caracteres como lo son en C o C++,
aunque
s
cuentan
con
las
caractersticas parecidas a las de los
arreglos. Puesto que los objetos de
cadena en Java son reales, cuenta con
mtodos que le permiten combinar,
verificar, y modificar cadenas con gran
facilidad.

Las siguientes instrucciones Java


declaran tres variables que usan los
tipos int, float y long:
class Class1 {
public static void main (String args[ ])
{
int test_score;
float salary;
long distancia_a_la_luna;}
}

Asignacin e inicializacin de
variables
Una vez que se ha declarado una
variable puede asignarle un valor
mediante el uso del operador de
asignacin =
Size =14;
tooMuchCaffiene = true;
int goo;
goo=100;
char coal;

El siguiente ejemplo asigna valores a


tres variables y luego muestra el valor
de cada una:
class Class1 {
public static void main (String args[ ]) {
int age = 35;
double salary = 25000.75;
long Distancia_a_la_luna=238857;

System.out.println("Employee age: " +


age);
System.out.println("Employee
salary: " + salary);
System.out.println("Distancia_a_la_lun
a: " +
Distancia_a_la_luna);
}
}

Las palabras reservadas Java no pueden


usarse para nombres de variables, a
continuacin se muestra una tabla con
las palabras reservadas que tienen un
significado especial para el compilar:

abstract boolean boolean boolean boolean boolean boolean

Char
Else

break
byte
generic case
In
cast
Outer catch
Short class
throws cons

break
byte
case
cast
catch
class
cons

break
byte
case
cast
catch
class
cons

break
byte
case
cast
catch
class
cons

break
byte
case
cast
catch
class
cons

break
byte
case
cast
catch
class
cons

volatile

continue

continue

continue

continue

continue

continue

2.5 EXPRESIONES Y
OPERADORES

Las expresiones son los enunciados que


regresan un valor. Los operadores son
smbolos especiales que por lo comn se
utilizan en expresiones. La aritmtica,
as como las pruebas de igualdad y
magnitud, son ejemplos comunes de
expresiones. Puesto que regresan un
valor 9223372036854775808.
Los operadores en Java incluyen a los
operadores aritmticos, varias formas de
asignacin, incrementos y decrementos,
as como operaciones lgicas.

Crear una aplicacin de consola


Una aplicacin de consola no dispone
de una interfaz de usuario grfica.
Puede utilizar las clases no grficas en
WFC o en la API de Java para
programar la aplicacin.
Para crear una aplicacin de consola:

1.En el men archivo, haga clic en


nuevo proyecto.
2.En la ficha nuevo, expanda la carpeta
Proyectos de Visual J++ y haga clic en
aplicaciones.
A
continuacin
seleccione el icono Aplicacin de
consola.
3.En la casilla nombre, escriba un
nombre para el proyecto.

4. En la casilla ubicacin. Escriba la


ruta donde se guardar el proyecto, o
bien haga clic en examinar para
desplazarse a la carpeta.
5. Haga clic en abrir. Aparecer una
vista contrada del proyecto en el
Explorador de proyectos.
6. En el explorador de proyectos,
expanda el nodo del proyecto. Un
archivo
con
el
nombre
predeterminado de Class1.java se ha
agregado al proyecto.

Para ver el cdigo fuente generado


haga doble clic en Class1.java en el
explorador de proyectos. La ejecucin
del proyecto empieza con la ejecucin
del mtodo main.
En el editor de texto agregue el
siguiente cdigo en el mtodo paint:

String str = El murcilago coma


felz;
System.out.println (la cadena es: +
str);
System.out.println (la longitud de la
cadena es +
str.length( ));
System.out.println ( la cadena en
maysculas es +
str.toUpperCase( ));

Para generar y ejecutar la


aplicacin:
1. En el men generar, haga clic en
Generar. Los mensajes o errores de
compilacin se muestran en la lista
de tareas, corrija los errores y
vuelva a generar el subprograma.

2. Para ejecutar la aplicacin desde el


entorno de programacin, haga clic
en la opcin iniciar del men
depuracin.
3. Para ejecutar la aplicacin desde la
lnea de comandos utilice JVIEW.
En el smbolo del sistema, escriba
jview Class1 desde el directorio del
proyecto.

2.5.1 ARITMETICAS

Java cuenta con 5 operadores para la


aritmtica bsica:
Operador

Significado

Ejemplo

+
*
/
%

Suma
Resta
Multiplicacin
Divisin
Mdulo

3+4
57
5*5
14 / 7
20 % 7

Cada operador toma dos operandos,


uno de cada lado del operador. El
operador de resta (-) puede tambin
emplearse para negar un operando
sencillo.
El siguiente listado es un ejemplo de
aritmtica sencilla:

class Class1 {
public static void main (String args[ ])
{
short x = 6;
int y = 4;
float a = 12.5f;
float b = 7f;

System.out.println(" x es " + x + ", y es " +


y);
System.out.println(" x + y = " + (x + y ));
System.out.println(" x - y = " + (x - y ));
System.out.println(" x * y = " + (x * y ));
System.out.println(" x % y = " + (x % y ));
System.out.println(" a es " + a + ", b es " +
b);
System.out.println(" a / b = " + (a / b ));
}
}

El resultado que
siguiente listado es:
x es 6, y es 4
x + y = 10
x-y=2
x/y=1
x%y=2
a es 12.5, b es 7
a / b = 1.78571

obtendr

del

El siguiente ejemplo, muestra el


resultado de varias operaciones
matemticas simples:
class Class1 {
public static void main (String args[ ])
{
System.out.println(" 5+7 = " +
(5+7));
System.out.println(" 12-7 = " +
(12-7));

System.out.println("1.2345 * 2 = " +
(1.2345 * 2 ) );
System.out.println(" 15 / 3 = " + (15 /
3 ));
}
}

Desbordamiento en las operaciones


aritmticas
Cuando se asigna un valor fuera de la
capacidad de la variable, ocurre un
error de desbordamiento. Cuando se
ejecutan operaciones aritmticas , es
necesario tener en cuenta estos errores.
Por ejemplo, el siguiente programa
multiplica cantidades muy grandes y las
guarda en una variable de tipo int.

Sin embargo, como el resultado de la


multiplicacin excede el valor ms
grande que una variable int puede
almacenar, se presenta un error de
desbordamiento.

class Class1 {
public static void main (String args[ ])
{
int result;
result = 2000000 * 3000000;
System.out.println(" 200 * 300 = " +
result);
}
}

Asignacin
La asignacin de variables es una
forma de expresin; de hecho, puesto
que una asignacin resulta de un valor,
se pueden encadenar de la siguiente
manera:
x = y = z = 0;
En este ejemplo, ahora las tres
variables tienen el valor de 0.

El lado derecho de una expresin de


asignacin, siempre se evala antes de
que se lleve a cabo la asignacin. Esto
significa que las expresiones como x =
x + 2 hacen lo correcto; le agregan 2 al
valor de x, y despus ese valor nuevo se
reasigna a x. De hecho esta clase de
operacin es tan comn que Java tiene
varios operadores para hacer una
versin corta, como se muestra en la
siguiente tabla:

Expresin

Significado

X+=Y
X-=Y
X*=Y
X/=Y

X=X+Y
X=X-Y
X=X*Y
X=X/Y

2.5.2 INCREMENTOS
Y
DECREMENTOS

Como en C y C++, los operadores ++ y


-- se utilizan para incrementar o
decrementar un valor en 1, a diferencia
de C y de C++, Java permite que el
valor a modificar sea de punto flotante.
Estos operadores se pueden fijar antes o
despus; es decir, el ++ o el -- puede
aparecer antes o despus del valor que
incrementa o decrece. Veamos los
siguientes ejemplos:

Expresin
Y = X++
Y = ++X
Z=X++ +Y
Z=X + --Y

Significado
Y=X
X=X+1
X=X+1
Y=X
Z = X +Y
X=X+1
Y = Y-1
Z=X+Y

1. current_count = count++;
La instruccin de asignacin indica a
Java que asigne el valor actual de
count a la variable current_count.
Adems el operador de incremento
sufijo le dice que aumente l valor
actual de count.

En este caso, el uso del operador sufijo


es equivalente a las dos instrucciones
siguientes:
current_count = count;
count = count +1;

Ahora usando la instruccin


asignacin con
el operador
incremento prefijo:

de
de

2. current_count = ++count;
Esta instruccin indica a Java que
primero incremente el valor de count y
luego asigne el resultado a la variable
current_count. Al usar el operador de
incremento prefijo, se logra que la
instruccin anterior sea equivalente a
las dos instrucciones siguientes:
count = count+1;
current_count = count;

El siguiente ejemplo ilustra el uso de


los operadores de incremento prefijo y
sufijo:
class Class1 {
public static void main (String args[ ])
{

int small_count = 0;
int big_count = 1000;

System.out.println ("small_count is " +


small_count);
System.out.println ("small_count is " +
small_count++);
System.out.println ("El valor final de
small_count es " +
small_count);
System.out.println ("big_count is "
+big_count);

System.out.println ("++big_count is "


+
++
big_count);
System.out.println ("El valor final de
big_count es " +
big_count);
}
}

El operador de sustraccin (--)


disminuye en 1 el valor de la variable.
Al igual que el operador de incremento
soporta el prefijo y el sufijo:
class Class1 {
public static void main (String args[ ])
{

int small_count = 0;
int big_count = 1000;

System.out.println ("small_count is "


+ small_count);
System.out.println ("small_count is "
+ small_count--);
System.out.println ("El valor final de
small_count es "
+ small_count);

System.out.println ("big_count is "


+big_count);
System.out.println ("--big_count is " +
-- big_count);
System.out.println ("El valor final de
big_count es " +
big_count);
}
}

2.5.3 COMPARACIONES

Java cuenta con varias expresiones


para probar la igualdad y la magnitud.
Todas estas expresiones regresan un
valor booleano. La siguiente tabla
muestra
los
operadores
de
comparacin:

Operador
==
!=
<
>
<=
>=

Significado
Igual
Diferente
Menor que
Mayor que
Menor o igual que
Mayor o igual que

2.5.4 OPERADORES
LGICOS

Las expresiones que dan como resultado


valores Bolanos, pueden combinarse al
utilizar
operadores
lgicos
que
representan las combinaciones lgicas
AND, OR, XOR y NOT.

Operador Significado

Forma

&

AND

Si usa &, ambos lados de la expresin se


evaluarn sin importar el resultado.

&&

AND
lgico.

Si emplea &&, y el lado izquierdo de la


expresin es falso, la expresin completa
regresar false, y nunca se evaluar el lado
derecho de la expresin.

OR

Evala ambos lados de la expresin sin


importar el resultado

||

OR
lgico.

Si la expresin izquierda es verdadera, la


expresin regresa true y nunca se evaluar el
lado derecho.

XOR
lgico.

Regresa true solo si sus operandos son


diferentes y falso en cualquier otro caso

NOT

Obtiene el negativo de una expresin.

class Class1 {
public static void main (String args[ ])
{
boolean usuario_dueo_de_perro
= true;
boolean usuario_dueo_de_gato
= true;
if (usuario_dueo_de_perro)
System.out.println("Los
perros
son grandiosos");

if (usuario_dueo_de_gato)
System.out.println ("Los gatos
son grandiosos");
if

((usuario_dueo_de_perro) &&
(usuario_dueo_de_gato))
System.out.println ("Los
perros y gatos son grandiosos");

if

((usuario_dueo_de_perro) ||
(usuario_dueo_de_gato))
System.out.println ("Las
mascotas son grandiosas");
}
}

2.5.5 OPERADORES DE BITS

Se
emplean
para
desempear
operaciones de bits en Java, los puede
observar en la tabla siguiente:
Operador
&
|
^
<<
>>
>>>

Significado
AND de bits
OR de bits
XOR de bits
Desplazamiento a la izquierda
Desplazamiento a la derecha
Llenado de ceros a la derecha

Operador Significado
~
Complemento de bits
<<=
Asignacin de desplazamiento
izquierda (X = X<<Y)

a la

>>=

Asignacin de desplazamiento a la derecha


(X = X>>Y)

>>>=

Asignacin de llenado de ceros hacia la


derecha (X = X>>>Y)

X&=Y
X|=Y
X^=Y

Asignacin AND (X = X&Y)


Asignacin OR (X + X|Y)
Asignacin XOR (X = X^Y)

El siguiente programa muestra todos


los operadores lgicos y lgicos
booleanos produciendo su tabla de
verdad.
class Class1 {
public static void main (String args[ ]) {

System.out.println ("AND lgico


(&&)");
System.out.println ("F && F: " +
(false && false) );
System.out.println ("F && T: " +
(false && true) );
System.out.println ("T && F: " + (true
&& false) );
System.out.println ("T && T: " + (true
&& true) );

System.out.println ("OR lgico ( || )");


System.out.println ("F | | F: " + (false ||
false) );
System.out.println ("F | | T: " + (false ||
true) );
System.out.println ("T | | F: " + (true ||
false) );
System.out.println ("T | | T: " + (true ||
true) );

System.out.println ("AND lgico


booleano (&)");
System.out.println ("F & F: " + (false
& false) );
System.out.println ("F & T: " + (false
& true));
System.out.println ("T & F: " + (true
& false) );
System.out.println ("T & T: " + (true
& true) );

System.out.println("OR
inclusivo
lgico booleano
(|)" );
System.out.println ("F | F: " + (false |
false));
System.out.println ("F | T: " + (false |
true));
System.out.println ("T | F: " + (true |
false));
System.out.println ("T | T: " + (true |
true));

System.out.println

("OR exclusivo
lgico
booleano
(^)");
System.out.println ("F ^ F: " + (false
^ false));
System.out.println ("F ^ T: " + (false
^ true) );
System.out.println ("T ^ F: " + (true ^
false));
System.out.println ("T ^ T: " + (true ^
true));

System.out.println ("NOT lgico (! )" );


System.out.println ("!F: " + (!false));
System.out.println ("!T: " + (!true) );
}
}

2.5.6

PRECEDENCIA DE
OPERADORES

La precedencia de los operadores


determina el orden en el cual las
expresiones se evalan, la cual en algunos
casos puede determinar el valor en general
de una expresin.
La precedencia especfica de los
operadores se muestra en la siguiente
tabla, los operadores que estn arriba en la
tabla se evalan primero, los de la misma
lnea tienen una precedencia similar y se
evalan de izquierda a derecha, con base
en la forma en que aparecen en la
expresin.

Operador
.[]()

Notas
Expresiones de grupo entres parntesis
( ); punto(.) se utilizan para el acceso a
mtodos y a variables dentro de los
objetos y clases; [] se usa para arreglos.

++ -- ! ~ Regresa verdadero o falso con base en


instanceof
que si el objeto es una instancia de la
clase nombrada, o cualquiera de la
superclases de esa clase.
New (tipo) El operador new se utiliza para crear
expresin
nuevas instancias de clases; ( ) en este
caso, es para seleccionar un valor a otro
tipo.

New (tipo) El operador new se utiliza para crear


expresin
nuevas instancias de clases; ( ) en este
caso, es para seleccionar un valor a otro
tipo.
* / %
+<<
>>
>>>

Multiplicacin, divisin, mdulo.


Suma, resta.
Desplazamiento hacia la izquierda y
derecha de bits

< > <= >= Pruebas de comparacin relacional.


= = !=
Igualdad
&
AND
^
XOR
|
OR

Siempre podr cambiar el orden de


evaluacin de las expresiones al utilizar
parntesis para las expresiones que
desee evaluar primero.

2.5.7

ARITMTICA
DE CADENAS

Una expresin especial en Java es el


uso del operador de suma (+) para
crear y concatenar cadenas. El
operador + cuando se utiliza con
cadenas y otros objetos, crea una solo
cadena que contiene la concatenacin
de todos sus operandos. Si cualquiera
de los operandos no es una cadena se
convierte en forma automtica en una
cadena, lo que hace mas fcil la
creacin de lneas de salida.

2.6

REFERENCIAS
EN JAVA

En Java no existe la declaracin de


objetos en pila. Todos los objetos se
crean explcitamente utilizando el
operador new, por ejemplo:
Door d = new Door ( );
Todos lo objetos Java se deben
crear explcitamente utilizando el
operador new. Los objetos Java
creados se asignan a variables de
objeto del mismo tipo.

En el ejemplo anterior se declara la


variable Door d, y despus se le asigna
un nuevo objeto Door creado por el
operador new. Se dice entonces, que la
variable tiene una referencia al objeto.
Cuando no se crea ninguna referencia a
un objeto, entonces la JVM (mquina
virtual de Java ) marca internamente el
objeto. El sistema Java elimina
peridicamente la asignacin de dichos
objetos marcados.

A esto se le llama recoleccin de basura y


es una de las caractersticas ms
agradables de la programacin en Java.
De este modo nunca hace falta destruir o
desasignar objetos en Java. La JVM lo
hace cuando se pierden todas las
referencias al objeto.
No existe nada parecido a los punteros en
Java. Todos los objetos se controlan a
partir de referencias.

Los parmetros que se pasan al


utilizar el operador new determinan
que constructor de clase se utiliza para
inicializar un objeto nuevo, como en
este ejemplo:

class MyProgram {
class Point {
int m_x;
int m_y;
public Point ( ){
this (0,0);
}
public Point ( int x, int y){
int m_x;
int m_y;
}
}

public static void main (String


astrArgs[ ]) {
Point origin = new Point ( );
Point p = new Point (5,5);
}
}

Punteros c/c++ y referencias java


Los punteros en C y C++ estn
orientados hacia un modelo fsico de
funcionamiento. Es decir, que el modelo
de punteros se mapea directamente sobre
el modelo hardware. Este modelo asume
cosas como el no movimiento, lo que
hace que mecanismos como la liberacin
automtica resulten mucho menos
eficientes o simplemente imposibles.

Cosas como la distribucin en redes y


la persistencia de objetos son muy
difciles de conseguir en C y C++.
Aunque no hay implementaciones en
Java, por ahora, para la persistencia y
la distribucin, la caracterstica opaca
de las referencias en Java hace que el
soporte para estas prestaciones sea
mucho ms simple.

C y C++ permiten el uso de punteros


de tal forma que podemos corromper
el sistema, cosa que no puede suceder
con las referencias en Java. Cualquier
intento de hacer esto sera abortado
por el compilador o por el sistema en
ejecucin (lanzando una excepcin). C
y C++ dejan la proteccin de memoria
al sistema operativo, que solamente
tiene el recurso de generar un error del
sistema cuando un puntero accede a
una posicin no vlida.

Por el contrario, con el uso de las


referencias, Java nos protege contra
nuestras
propias
tendencias
autodestructivas.

2.7 CONTROL DE FLUJO

Como en otros lenguajes, Java maneja


instrucciones condicionales y ciclos. Para
construirlos necesitamos saber que son los
bloques de instrucciones:
Un bloque de instrucciones es un grupo
de instrucciones agrupadas por llaves
({}). Puede utilizar un bloque en cualquier
lugar donde debera de ir una instruccin
individual, y el nuevo bloque crea otro
nuevo propsito local para los enunciados
que estn dentro de l.

Esto significa que se puede declarar y


usar variables locales dentro de un
bloque, y estas terminarn de existir
cuando termine la ejecucin de un
bloque. Por ejemplo, aqu se muestra
un bloque dentro de una definicin de
mtodo que declara una nueva variable
y. No podr emplear y fuera del
bloque en donde se declar

void testblock ( ) {
int x = 10;
{
// start of block
int y = 50;
System.out.println (inserta el
bloque :);
System.out.println (x: + x );
System.out.println (y: + y);
} // end of block
}

No es usual que los bloques se utilicen


en esta forma slo en una definicin de
mtodo, con declaraciones de variables
aleatorias dentro de ellos, otro uso
comn de un bloque de instrucciones se
encuentra en las estructuras de control
de flujo.
Los elementos indispensables para la
repeticin controlada por contador
son:

1. El nombre de una variable de control


( o contador de ciclos)
2. El valor inicial de una variable de
control
3. El incremento (o decremento) que se
aplicar a la variable de control en
cada repeticin del ciclo.
4. La condicin que prueba el valor
final de la variable de control.

2.7.1 CONDICIONALES if

El condicional if permite ejecutar


diferentes partes del cdigo con base
en una simple prueba, contiene la
palabra clave if, seguida de una prueba
booleana y de un enunciado a ejecutar
si la prueba es verdadera:

La diferencia entre los condicionales en


Java y C o C++ es que la prueba debe
regresar un valor booleano (falso o
verdadero).
El formato de la
instruccin if es la siguiente:
if (condicin_es_verdadera)
sentencia;

El siguiente ejemplo usa if para


comparar el valor almacenado en la
variable TestScore con 90. Si
TestScore es mayor o igual a 90, se
muestra un mensaje de felicitacin
indicando que obtuvo una A, de otra
manera, si el valor es menor de 90 el
programa termina.

class Class1 {
public static void main (String args[ ])
{
int TestScore = 95;
if (TestScore >= 90)
System.out.println("Felicidades
obtuviste una A");
}
}

Para lograr que se ejecute el conjunto


de instrucciones en el caso de la
condicin falsa, debe utilizarse else.
El formato de la instruccin else es
como sigue:
if (condicin_es_verdadera)
Sentencia;
else
Sentencia;

class Class1 {
public static void main (String args[ ])
{
int TestScore = 95;
if (TestScore >= 90){
System.out.println ("Felicidades
obtuviste una A");
System.out.println ("Tu puntuacin
es" + TestScore);
}

else
{
System.out.println

("Deberas
estudiar mas");

System.out.println ("Perdiste de tu
puntuacin" + (TestScore - 10) );
}
}
}

Cuando se lee informacin del teclado,


Java prueba si hay problemas durante la
entrada (por ejemplo, no hay mas datos a
introducir). Si ocurre un problema Java
genera una excepcin, la cual es un caso
excepcional durante la ejecucin de un
programa. Para ejecutar un programa que
reciba datos del teclado, puede hacerlo
indicndole al compilador que est
consiente de los problemas que pueden
ocurrir, esto se lograr incluyendo en el
programa las palabras clave throws
IOException.

El siguiente programa el usuario va a


teclear calificaciones de letra que se
introducen en el programa para calcular
el promedio en las calificaciones de un
grupo:
import java.io.*;
class Class1 {
public static void main (String args[ ] )
throws IOException {
int counter, grade, total, average;

// fase de inicializacin
total = 0;
counter = 1;
//fase de procesamiento
while (counter <= 10 ) {
System.out.print ("Teclee calificacin
de letra: " );
System.out.flush ( );
grade = System.in.read ( );

if (grade == 'A' )
total = total + 4;
else if (grade == 'B' )
total = total + 3;
else if (grade == 'C' )
total = total + 2;
else if (grade == 'D' )
total = total + 1;
else if (grade == 'F' )
total = total + 0;

System.in.skip ( 2 );
//Saltar el
carcter de nueva
lnea
counter = counter + 1;
}
//fase de terminacin
average = total / 10; //divisin entera
System.out.println ("El promedio del
grupo es " + average);
}
}

El operador condicional
Una alternativa para utilizar las
palabras claves if y else en un
enunciado condicional es usar el
operador condicional
tambin
conocido como el operador ternario.
El operador condicional es ms til
para condicionales cortos o sencillos,
y tiene esta apariencia:
test ? trueresult : falseresult

El test es una expresin que regresa


true o false, al igual que en la prueba
del enunciado if. En el siguiente
ejemplo, este condicional prueba los
valores de x y y, regresa al ms
pequeo de los dos y asigna ese valor
a la variable smaller:
int smaller = x < y ? x : y;

2.7.2 CONDICIONALES switch

Este condicional nos sirve para probar


alguna variable contra algn valor, y
si no coincide con ese valor, probarla
con otro y as sucesivamente.
switch (test) {
case valueOne:
resultOne;
break;
case valueTwo:
resultTwo;
break;
case valueThree:
resultThree;
break;

default: defaultresult;
}

En el siguiente ejemplo, se usa la


instruccin switch para mostrar un
mensaje, con base en la nota actual del
estudiante:
class Class1 {
public static void main (String args[ ] )
{
char grade = 'B';
switch (grade){

case 'A' :System.out.print("Felicidades


obtuviste una A");
break;
case 'B' :System.out.print("Bien,
obtuviste una B");
break;
case 'C' :System.out.print("Suficiente
obtuviste una C");
break;

case 'D' :System.out.print("No hay


excusas, estudia ms ");
break;
}
}
}

La desventaja de este tipo de pruebas, es


que no pueden trabajar con valores de
tipos deferentes de int, esto limita a
trabajar con if anidado para la utilizacin
de valores grandes como los que maneja
(long y float).
Tambin puede utilizar este condicional
cuando quiera que ms de una opcin
ejecuten la misma lnea de cdigo, esto lo
podr hacer al omitir la sentencia break, lo
que le permitir desplazarse hasta que
encuentre el condicional de paro.

switch (x){
case 2:
case 4:
case 6:
case 8:
system.out.println(x es un nmero
par.);
break;
default: system.out.println(x es
cualquier nmero.);
}

2.7.3 CICLOS for

Este ciclo repite una declaracin o un


bloque de enunciados un nmero de
veces hasta que una condicin se
cumple. Estos ciclos con frecuencia se
utilizan para una iteracin sencilla en
donde usted repite un bloque de
enunciados un cierto nmero de veces
y despus se detiene; aunque tambin
puede usarlos para cualquier clase de
ciclos. El ciclo for en Java tiene esta
apariencia:

for (initialization; test; increment){


staments
}

El inicio del ciclo for tiene tres partes:

1. initialization es una expresin que


inicializa el principio del ciclo. Si
tiene un ndice, esta expresin
puede declararla e inicializarla. Las
variables que se declararn dentro
del ciclo; dejan de existir despus
de acabar la ejecucin del ciclo.

2. test es la prueba que ocurre despus


de cada vuelta del ciclo. La prueba
puede ser una expresin booleana o
una funcin que regresa un valor
booleano. Si la prueba es verdadera
el ciclo se ejecutar, de lo contrario
el ciclo detiene su ejecucin.

3. increment es una expresin o


llamada de funcin. Por lo comn el
incremento se utiliza para cambiar el
valor del ndice del ciclo a fin de
acercar el estado del ciclo a false y
se complete.

La parte del enunciado del ciclo for


son los enunciados que se ejecutan
cada vez que se itera el ciclo, al igual
que con if puede incluir un solo
enunciado o un bloque. Cualquiera de
las partes de un ciclo for pueden ser
enunciados vacos, es decir, puede
incluir un solo punto y coma sin
ninguna expresin o declaracin, y esa
parte del ciclo se ignorar.

Es importante recordar que no debe de


colocar punto y coma despus de la
primera lnea del ciclo for:
for (i = 4001 ; i<=10;i--)
system.out.println(Hola);

En este caso como el primer punto y


coma termina el ciclo con enunciado
vaco, el ciclo no hace nada en
general, la forma correcta para la
ejecucin de este ciclo sera:

for (i = 4001 ; i<=10;i++)


system.out.println(Hola);

Ejemplos:

En el siguiente ejemplo el ciclo for


muestra los nmeros desde el 1 hasta el
valor contenido en la variable
EndCount:
public class Class1
{
public static void main (String[] args)
{
int count ;
int end_count = 10;

for (count = 1; count <=end_count ;


+)

System.out.print("" + count);
}
}

count+

El programa siguiente efecta


repeticiones de 1 hasta 10, mostrando
y sumando cada nmero a un gran
total:
public class Class1
{
public static void main (String[]
args)
{
int count ;
int total = 0;

for (count = 1; count <=end_count ;


count++)
{
System.out.println("Sumand
o " + count
+ "hasta "
+ total);
total = total + count ;
}
System.out.println("La suma total
es : " + total);
}

El ciclo for no tiene la limitacin de


incrementar solo en 1 la variable. El
siguiente applet, muestra cada quinto
nmero entre uno y cincuenta:
public class Class1
{
public static void main (String[] args)
{
int count, y ;

for (count = 0, y = 15; count <=50 ;


count += 5, y += 15)
{
System.out.println( " count: " +
count);
}
}
}

Dentro de un ciclo for no es obligatorio


que el conteo sea ascendente, el siguiente
Applet usa el ciclo for para mostrar en
forma descendente los nmeros del 1 al
10:
public class Class1
{
public static void main (String[] args)
{
int count, y ;

for (count =10, y = 15; count <=50 ;


count --, y += 15)
System.out.println( " count: " +
count);
}
}

Los ciclos for no estn restringidos a


usar valores de tipo int en las variables
de control de ciclos:
public class Class1{
public static void main (String[] args)
{
int x ;
char letter;
float value;
for (letter = 'A';letter <=
'Z' ;letter ++)

System.out.println(""+ letter );
for (value = 0; value
value += 0.1, x +=20)
System.out.println(""+ value);
}
}

<1.0;

2.7.4 CICLOS while y do

Al igual que los ciclos for, le


permiten a un cdigo de bloque Java
ejecutarse de manera repetida hasta
encontrar una condicin especfica.
Utilizar uno de estos tres ciclos solo es
cuestin de estilo de programacin
Los ciclos while y do son
exactamente los mismos que en C y
C++, a excepcin de que su condicin
de prueba debe ser un booleano.

Ciclos while
Se utilizan para repetir un enunciado
o bloque de enunciados, siempre que
una condicin en particular sea
verdadera. Los ciclos while tienen
esta apariencia:
while (condition) {
bodyOfLoop
}

La condition es una expresin


booleana. Si regresa true, el ciclo while
ejecutar los enunciados dentro del
bodyOfLoop, y despus prueba la
condicin de nuevo, repitindola hasta
que sea falsa.
Si la condicin es en un principio falsa
la primera vez que se prueba, el cuerpo
del ciclo while nunca se ejecutar. Si
necesita que el ciclo por lo menos una
vez, tiene dos opciones a elegir:

1. Duplicar el cuerpo del ciclo fuera


del ciclo while.
2. Utilizar un ciclo do.
El ciclo do se considera la mejor
opcin en ambas.

Ciclo do... while


El ciclo do es como while, excepto que do
ejecuta un enunciado o bloque hasta que la
condicin es false. La principal diferencia es
que los ciclos while prueban la condicin
antes de realizar el ciclo, lo cual hace
posible que el cuerpo del ciclo nunca se
ejecute si la condicin es falsa la primera
vez que se prueba. As los ciclos do ejecutan
el cuerpo del ciclo por lo menos una vez
antes de probar la condicin. Los ciclos do
se ven as:

do{
bodyOfLoop
} while (condition);

El siguiente programa muestra los


resultados obtenidos de un examen:
import java.io.*;
public class Class1{

public static void main (String args


[])
throws IOException
{
int passes = 0, failures = 0, student =
1,
result;
while (student <= 10 ){
System .out.print( "Teclee resultado
(1=
aprob, 2= reprob ): " );
System.out.flush ( );
result = System.in.read ( );

if (result =='1' )
passes = passes +1;
else
failures = failures + 1;

student = student + 1;
System.in.skip (2);
}

System.out.println ("Aprobados " +


passes );
System.out.println ("Reprobados " +
failures );
if ( passes > 8 )
System.out.println ("Aumentar la
colegiatutra " );
}
}

Programa que calcula el promedio de


un grupo.
import java.io.*;
public class Average{
public static void main (String args[ ] )
throws IOException
{
double average;
int counter, grade, total;

// fase de inicializacin
total = 0;
counter = 0;
//fase de procesamiento
System.out.print (Teclee
calificacin de letra, Z para
terminar: );
System.out.flush ( );
grade = System.in.read ( );

while (grade != 10 ) {
if (grade == A )
total = total + 4;
else if (grade == B )
total = total + 3;
else if (grade == C )
total = total + 2;
else if (grade == D )
total = total + 1;
else if (grade == F )
total = total + 0;

System.in.skip ( 1 );
//Saltar el
carcter de nueva
lnea
counter = counter + 1;
System.out.print(Teclee
calificacin de letra, Z para terminar:
);
System.out.flush( );
grade = System.in.read ( );
}

//fase de terminacin
if (counter != 0 ) {
average = (double) total / counter;
System.out.println (El promedio del
grupo es + average);
}
else
System.out.println( No se
introducieron calificaciones );
}
}

Como salir de los Ciclos


En todos los ciclos (for, while y do),
stos se terminan cuando la condicin
que prueba se cumple. Para salir de
manera anticipada del ciclo, puede
utilizar las palabras clave break y
continue.

El uso de continue es similar al de


break, a excepcin de que en lugar de
detener por completo la ejecucin del
ciclo, este inicia otra vez en la
siguiente iteracin. Para los ciclos do
y while, esto significa que la ejecucin
del bloque se inicia de nuevo. Para los
ciclos for la expresin de incremento
se evala y despus el bloque se
ejecuta .continue es til cuando se
desea tener elementos especiales de
condicin dentro de un ciclo.

Ejemplo que muestra el uso de la


instruccin break:
import java.io.*;
public class Class1{
public static void main (String args[ ] )
throws IOException
{
int count, xpos = 25;
for (count = 1; count <= 10;
count++) {

if (count ==5)
break;

// Romper el ciclo
slo si count ==5

System.out.println(Integer.toString
(count ));
}
System.out.print ("Me sal del ciclo
con count = " + count);
}

Ejemplo que muestra el uso de la


instruccin continue:
import java.io.*;
public class Class1{
public static void main (String args[ ])
throws IOException
{
int xPos = 25;
for ( int count = 1; count <= 10;
count++ ) {

if ( count ==5 )
continue; //saltarse el resto del
cdigo slo si count==5
System.out.println(Integer.toString (
count ));
}
System.out.println("Us
continue
para no I mprimir 5");
}
}

2.7.5

EXCEPCIONES

Java implementa excepciones para


facilitar la construccin de cdigo
robusto. Cuando ocurre un error en un
programa, el cdigo que encuentra el
error lanza una excepcin, que se
puede capturar y recuperarse de ella.
Java proporciona muchas excepciones
predefinidas.

try-catch-throw
try {
// Normalmente este cdigo corre
desde arriba del bloque hasta
// el final sin problemas. Pero
algunas veces puede ocasionar
// excepciones o salir del bloque con
una sentencia break,
// continue, o return.

sentencias;
} catch( AlgunaException e1 ) {
// El manejo de un objeto de
excepcion el de tipo AlgunaExcepcion
// o de una subclase de ese tipo.
sentencias;
catch( OtraException e2 ) {
// El manejo de un objeto de
excepcin e2 de tipo OtraExcepcion
// o de una subclase de ese tipo.
}

try (tratar)
La clusula try simplemente establece
un bloque de cdigo que habr de
manejar todas las excepciones y
salidas anormales(va break, continue
o propagacin de excepcin). La
clsula try, por s misma, no hace nada
interesante.

catch (atrapar)
Un bloque try puede ir seguido de cero
o ms clusulas catch, las cuales
especifican el cdigo que manejar los
distintos tipos de excepciones. Las
clusulas catch tienen una sintaxis
inusual: cada una se declara con un
argumento, parecido a un argumento de
mtodo. Este argumento debe ser del
tipo Throwable o una subclase.

Cuando ocurre una excepcin, se


invoca la primera clusula catch que
tenga un argumento del tipo adecuado.
El tipo de argumento debe concordar
con el tipo de objeto de excepcin, o
ser una superclase de la excepcin.
Este argumento catch es vlido slo
dentro del bloque catch, y hacer
referencia al objeto de excepcin real
que fue lanzado.

2.7.6

CONTROL GENERAL
DEL FLUJO

break [etiqueta]
continue [etiqueta]
return expr;
etiqueta: sentencia;
En caso de que nos encontremos con
bucles anidados, se permite el uso de
etiquetas para poder salirse de ellos, por
ejemplo:

uno: for( )
{ dos: for( )
{
continue;
// seguira
en el bucle interno
continue uno;
//
seguira en el bucle principal
break uno;
// se
saldra del bucle principal
}
}

Si se declara una funcin para que


devuelva un entero, es imprescindible
que se coloque un return final para salir
de esa funcin, independientemente de
que haya otros en medio del cdigo que
tambin provoquen la salida de la
funcin.

int func()
{

if ( a == 0 )
return 1;
return 0;

// es imprescindible
porque se retorna un
entero

CAPTULO III
APPLETS DE JAVA

3.1 APPLETS Y
APLICACIONES

Los programas Java comprenden dos


grupos
principales:
applets
y
aplicaciones.
Los applets, son programas Java que
se cargan en el World Wide Web y se
ejecutan mediante un visualizador Web
en la mquina del lector. Para
ejecutarse,
dependen
de
un
visualizador habilitado para Java, o
tambin, si emplea una herramienta
conocida como appletviewer.

Las aplicaciones Java son programas


ms generales escritos en lenguaje Java.
No requieren un visualizador para
ejecutarse, y de hecho Java puede
utilizarse para crear toda clase posible de
aplicaciones, como si utilizara un
lenguaje
de
programacin
ms
convencional.
Un programa Java puede ser una
aplicacin, un applet o ambos,
dependiendo de la manera en que escriba
y las capacidades que utilice el programa.

Como crear un applet Java


Crear applets es diferente de crear un
aplicacin sencilla, ya que las applets
Java se ejecutan y despliegan dentro de
una pgina Web con otros elementos de
pgina y, como tales, cuentan con
reglas especiales para el modo en que
debern comportarse. A causa de estas
reglas, en muchas ocasiones, crear un
applet puede ser ms complejo que
crear una aplicacin.

Por ejemplo, para realizar una applet


Hello World, en lugar de solo estar
habilitando para imprimir un mensaje,
tendr que crear otro para hacer
espacio para su mensaje y luego,
utilizar operaciones grficas para
pintar el mensaje en la pantalla.
En el siguiente ejemplo, crear ese
sencillo applet
HelloWorld, lo
colocar dentro de una pgina Web y
ver el resultado.

Primero, configure un ambiente para que


el visualizador con capacidad Java pueda
encontrar sus archivos HTLM y su cdigo
de applets en el mismo directorio. Aunque
no es un requerimiento, esto facilita la
bsqueda de cada elemento. En este
ejemplo utilizar un directorio llamado
HTLM que contiene todos los archivos
que necesitar.
mkdir HTLM
Ahora introduzca el siguiente listado:

import java.awt.Graphics;
public class
HelloWorldApplet
extends java.applet.Applet {
public void paint (Graphics g) {
g. drawString (Hola
mundo, 5, 25);
}
}

import java.awt.Graphics;
import java.applet.*;
public class
extends Applet {

HelloWorldApplet

public void paint (Graphics g) {


g. drawString (Hola
mundo, 5, 25);
}
}

Guarde este archivo dentro de su


directorio HTLM. Al igual que con las
aplicaciones Java dele un nombre a su
archivo que sea igual al de la clase. En
este caso el nombre del archivo ser
HelloWorldApplet.java.

Caractersticas
importantes
mencionar sobre las applets:

que

La lnea import al inicio del


archivo es, de alguna manera
anloga al enunciado #include en
C; esto le permitir al applet tener
acceso a las applets JDK para
crear las applets y dibujar grficos
en pantalla.

El

mtodo paint( ) despliega el


contenido de una applet en pantalla.
Aqu la cadena Hola Mundo se
dibuja. Los applets utilizan varios
mtodos estndares para tomar el
lugar de main ( ), los cuales incluyen
init ( ) para inicializar el applet, start
( ), para empezar la ejecucin, y
paint ( ) para desplegarla en la
pantalla.

Ahora compile el applet como lo hizo


en las aplicaciones anteriores.
De nuevo, tal como para las
aplicaciones deber contar con un
archivo
llamado
HelloWorldApplet.class
en
su
directorio HTLM.
Para incluir un applet en una pgina
Web, refirase a l en el archivo
HTLM para dicha pgina. A
continuacin crear un archivo HTLM
muy sencillo en el directorio HTLM.

<HTLM>
<HEAD>
<TITLE>Hola a todos! </TITLE>
</HEAD><BODY>
<P> Mi applet de Java dice:
<APPLET
CODE=HelloWorldApplet.class
WIDTH=150
HEIGHT
=25><APPLET>
</BODY>
</HTLM>

Puede referirse a
un Applet en sus
archivos
HTLM
con
la
etiqueta
<APPLET>.
Utilice el atributo CODE para indicar
el nombre de la clase que contiene
su applet.
Emplee los atributos WIDTH y
HEIGHT para sealar el tamao del
applet. El visualizador utiliza estos
valores para saber que tanto espacio
dejar en la pgina para el applet.
Aqu se crea una cuadro de 150 pixeles
de ancho por 25 de alto.

Guarde el archivo HTLM en su


directorio HTLM, con un nombre
descriptivo (por ejemplo, puede
nombrarlo con su mismo nombre de la
applet, HelloWorldApplet.htlm).
Podr hacer:

Un

visualizador que acepte applets


Java, como Netscape 2.0

La aplicacin appletviewer, la cual es


parte del JDK. Puesto que no es un
visualizador web no le permitir ver
la pgina web por completo, pero es
aceptable para experimentar con la
apariencia de una applet y su
comportamiento.

Si utiliza un visualizador con


capacidad Java, como Netscape para
ver los archivos de applets, use el
elemento Open Local... bajo el men
File para navegar hacia el archivo
HTLM que contiene el applet. Todava
no necesitar instalar nada en el
servidor Web, todo esto funciona en su
sistema local.

Si no cuenta con un visualizador Web


con capacidad Java integrada, puede
utilizar el programa appletviewer para
ver su applet Java. Para ejecutar este
programa, solo indique la ruta al
archivo HTLM en la
lnea de
comando:
Appletviewer
HTLM/HelloWorldApplet.htlm

Si utiliza el visualizador para ver el


applet observar algo similar a la
imagen mostrada en la figura. Si usa
un appletviewer, no ver el texto
alrededor del applet (Mi applet de Java
dice...), pero si podr ver Hola Mundo
Mi applet de Java dice: Hola Mundo!

3.2 FUNCIONES ESPECIALES

Init Cuando los applets sean ms


complejos, necesitarn inicializar
archivos de imgenes, audio, fuentes y
otros objetos. Debido a que estos
objetos, por lo general solo se
inicializan una vez, java permite
agrupar estas operaciones dentro de
una funcin especial llamada init.
public void init( )
{ // sentencias
}

Cada vez que se inicia el applet,


automticamente se llama a la funcin
init. Cuando se crea, la funcin init
solo se debe usar para inicializar las
variables. Es decir, cualquier tipo de
procesamiento debe efectuarse en otras
funciones, como start.

Start
Despus de que el
applet ejecuta la funcin init, este
llama la funcin especial start, cuyo
propsito es iniciar (start) el
procesamiento. En la mayor parte de
las applets, la funcin start crear uno
o ms threads de ejecucin, que a su
vez ejecutar el procesamiento del
applet. Las instrucciones siguientes,
muestran y ejecutan un ejemplo de la
funcin start, que crea y ejecuta un
thread (proceso):

Thread somoThread = null;


public void start ( );
{ if (someThread = = null)
{ someThread = new Thread (This);
someThread.start( );
} }
Es importante comprender que
despus de llamar a la funcin init, el
applet llama a start. De igual manera,
cuando el applet finaliza, llama a la
funcin stop.

Stop
Dependiendo del explorador
y del propsito de la pgina Web que
contiene el applet, habr ocaciones en
que el explorador detendr el applet si
el usuario cambia el foco activado de
la vista. Luego cuando regrese el foco
activo a la vista, el explorador
reiniciar la ejecucin del applet. Para
iniciar y detener el applet de esta
manera, el explorador utiliza las
funciones start y stop.

Cuando los applets son complejos,


aprovechan los threads (procesos) para
ejecutar diferentes tareas. Por ejemplo,
un proceso puede reproducir diferentes
sonidos de fondo, mientras que un
segundo rota el
logotipo de la
compaa y un tercero desplaza u7n
objeto animado alrededor de la
pantalla.

Cuando se usan mltiples procesos, se


hace necesaria una manera de
controlar el orden en el cual se
detienen cuando el explorador detiene
el applet. De no ser as, un objeto
continuar su movimiento a lo largo
de la pantalla despus de finalizar la
msica (o viceversa), haciendo que el
applet se detenga de manera
inadecuada.

Las instrucciones siguientes muestran


como puede usarse la instruccin stop
para detener uno o ms procesos:
public void stop ( )
{
if (somoThread != null)
{
someThread.stop ( );
somoeThread = null ;
}
}

En este caso, las instrucciones asignan


el valor null (nulo) a cada thread que la
funcin detiene. Al asignar este valor al
objeto thread, posteriormente Java
puede descartar este objeto como si
estuviera recogiendo la basura.
Si despus el explorador debe iniciar el
proceso, la funcin start puede evaluar
el valor null y crear e iniciar uno nuevo.
Lo importante es saber que el
explorador invocar la funcin stop
para detener el applet.

Paint
Cada vez que el explorador
necesita actualizar la ventana del
applet, ste llama la funcin paint. Por
ejemplo, cuando el explorador presenta
por primera vez el applet, ste
automticamente llama la funcin
paint. Lo mismo ocurre cuando el
usuario cambia el tamao o mueve la
ventana

Ejemplo:
public void paint (graphics g);
{
g.drawstring (hola, 5, 15);
}
Dentro de la funcin paint, el applet
debe
dibujar
cada
elemento
previamente escrito en la ventana.
Suponga que se dibuja un rectngulo y
el usuario minimiza la ventana.

Cuando esta se restaura, paint debe de


redibujar los contenidos previos (en
este caso lo rectngulo). En otras
palabras, ni el explorador ni Windows
guardan registro actualizado del
contenido de la ventana applets. Si por
ejemplo, existe una imagen de fondo,
paint debe de redibujarla. Si hay texto,
paint debe restaurarlo. Resumiendo, la
funcin paint tiene el control total del
contenido de la ventana applet.

Dependiendo
del
tipo
de
procesamiento que realice el applet, en
algunos ocasiones ser necesario
actualizar el contenido de la ventana.
En esos casos se llama la funcin
repaint que, a su vez, llama la funcin
paint.

Destroy Lafuncin
init
puede
inicializar las variables importantes;
con la funcin destroy se eliminan los
objetos al finalizar el applet. Por
ejemplo, puede utilizarse la funcin
destroy para liberar la memoria
reservada para guardar un arreglo:
public void destroy ( )
{
// sentencias
}

3.3 EJEMPLOS DE APPLETS

1)

El siguiente Applet imprime el


letrero Hola en color rojo.

import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
public
class
HelloAgainApplet
extends java.applet. Applet{
Font f= new Font ("TimesRoman",
Font.BOLD, 36);

public void paint (Graphics g)


{
g.setFont(f);
g.setColor(Color.red);
g.drawString("Hola", 5, 50);
}
}

2) El siguiente Applet muestra un


ejemplo de cmo concatenar
cadenas con el perador +
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
public class HelloNombre extends
java.applet. Applet{
Font f= new Font ("TimesRoman",
Font.BOLD, 36);
String name;

public void init ( ) {


this.name = getParameter("name");
if (name == null)
name = "Mara";
name = "Hello" + name + "!";
}
public void paint (Graphics g){
g.setFont(f);
g.setColor(Color.red);
g.drawString(name, 5, 50);
}
}

3) El siguiente Applet muestra un


ejemplo de la declaracin de variables
import java.awt.*;
import java.applet.*;
public class ShowVariables extends
Applet
{
int age = 35;
double salary = 25000.75;
long Distancia_a_la_luna= 878888;

public void paint (Graphics g)


{
g.drawString("Employee age:
" + age, 5, 25);
g.drawString("Employee
salary: " + salary, 5, 45);
g.drawString("Distancia_a_la_luna: " +
Distancia_a_la_luna, 5,65);
}
}

4) El siguiente Applet muestra un


ejemplo de las diferentes
operaciones.
import java.awt.*;
import java.applet.*;
public class
ShowMathOperations extends
Applet
{

public void paint (Graphics g)


{g.drawString(" 5+7 = " + (5+7), 5 , 25);
g.drawString(" 12-7 = " + (12-7), 5 ,
40);
g.drawString("1.2345 * 2 = " + (1.2345
* 2 ),5, 55);
g.drawString(" 15 / 3 = " + (15 / 3 ), 5
,70); }
}

5) El siguiente Applet muestra un


ejemplo de OverFlow en un nmero
entero.
import java.awt.*;
import java.applet.*;
public class MathOverFlow extends
Applet
{
public void paint (Graphics g){

int result;
result = 2000000 *
3000000;
g.drawString("200 * 300 =
" + result, 5 , 25);
}
}

6)

El siguiente Applet muestra un


ejemplo del uso del operador ++

import java.awt.*;
import java.applet.*;
public class PrefijoSufijo extends
Applet
{
public void paint (Graphics g)
{

int small_count = 0;
int big_count = 1000;
g.drawString ("small_count is " +
small_count, 5, 10);
g.drawString ("small_count is " +
small_count++, 5, 25);
g.drawString ("El valor final de
samall_count es " +
small_count, 5, 40);

g.drawString ("big_count is "


+big_count, 5, 60);
g.drawString ("++big_count is " + ++
big_count, 5, 75);
g.drawString ("El valor final de
big_count es " +
big_count, 5, 90);
}
}

7) El siguiente Applet muestra un


ejemplo del uso de la instruccin if
import java.awt.*;
import java.applet.*;
public class Perros_Gatos extends
Applet
{
public void paint (Graphics g)
{
boolean usuario_dueo_de_perro =
true;

boolean usuario_dueo_de_gato =
true;
if (usuario_dueo_de_perro)
g.drawString ("Los perros
son grandiosos", 5 ,15);
if (usuario_dueo_de_gato)
g.drawString ("Los gatos son
grandiosos", 5 ,30);
if ((usuario_dueo_de_perro) &&
(usuario_dueo_de_gato))
g.drawString ("Los perros y gatos

if
((usuario_dueo_de_perro) ||
(usuario_dueo
_de_gato))
g.drawString ("Las mascotas
son
grandiosas", 5 ,60);
}
}

8)

El siguiente Applet muestra el uso


de los operadores lgicos

import java.awt.Graphics;
import java.applet.Applet;
public
class
OperadoresLgicos
Class1 extends Applet {
public void paint (Graphics g)
{

g.drawString ("AND lgico (&&)",10 ,


25);
g.drawString ("F && F: " + (false &&
false), 10, 40 );
g.drawString ("F && T: " + (false &&
true), 10, 55 );
g.drawString ("T && F: " + (true &&
false), 10, 70 );
g.drawString ("T && T: " + (true &&
true), 10, 85 );

g.drawString ("OR lgico ( | | )",215 ,


25);
g.drawString ("F | | F: " + (false || false),
215, 40 );
g.drawString ("F | | T: " + (false || true),
215, 55 );
g.drawString ("T | | F: " + (true || false),
215, 70 );
g.drawString ("T | | T: " + (true || true),
215, 85 );

g.drawString ("AND lgico booleano


(&)",10 , 115);
g.drawString ("F & F: " + (false &
false), 10, 130 );
g.drawString ("F & T: " + (false &
true), 10, 145);
g.drawString ("T & F: " + (true &
false), 10, 160 );
g.drawString ("T & T: " + (true & true),
10, 175 );

g.drawString ("OR inclusivo lgico


booleano (| )",215 ,
115 );
g.drawString ("F | F: " + (false | false),
215, 130 );
g.drawString ("F | T: " + (false | true),
215, 145 );
g.drawString ("T | F: " + (true | false),
215, 160 );
g.drawString ("T | T: " + (true | true),
215, 175 );

g.drawString ("OR exclusivo lgico


booleano (^ )",10 ,
205 );
g.drawString ("F ^ F: " + (false ^
false), 10, 220 );
g.drawString ("F ^ T: " + (false ^
true), 10, 235 );
g.drawString ("T ^ F: " + (true ^
false), 10, 250 );
g.drawString ("T ^ T: " + (true ^
true), 10, 265 );

g.drawString ("NOT lgico (! )",215,


205 );
g.drawString ("!F: " + (!false), 215,
220 );
g.drawString ("!T: " + (!true), 215,
235 );
}
}

9)

El siguiente Applet muestra un


ejemplo del uso del for

import java.awt.*;
import java.applet.*;
public class VariableCount extends
Applet
{
public void paint (Graphics g)
{

int count ;
int end_count = 10;
for (count = 1; count
<=end_count ; count++)
g.drawString("" + count, count *10,
25);
}
}

10) El siguiente ejemplo calcula el


inters compuesto utilizando el
ciclo for, con los siguientes datos:
Una persona invierte $ 1000.00 en una
cuenta de ahorros que produce intereses
del 5%. Suponiendo que todos los
intereses quedan en depsito, calcule e
imprima la cantidad de dinero que habr
en la cuenta al final de cada ao durante
10 aos.

Utilice la siguiente frmula para calcular


dichas cantidades:

a= p(1 + r)2
donde
p es la cantidad original invertida
r es la tasa de inters anual
n es el nmero de aos
a es la cantidad del depsito de n-simo
ao.

Este problema implica un ciclo que


realiza el clculo indicado para cada
uno de los 10 aos que el dinero
permanece en depsito.
import java.awt.Graphics;
importa java.applet.Applet;
public class Interes extends Applet
{
public void paint (Graphics g)
{

double amount, principal = 1000.0,


rate = .05;
int yPos = 40;
g.drawString ( Ao, 25, 25 );
g.drawstring(Cantidad en depsito,
100, 25 );
for ( int year = 1; year <= 10;
year++ ){

amount = principal * Math.pow( 1.0 +


rate, year);
g.drawstring (Integer.toString(year ), 25,
yPos);
g.drawstring (Double.toString (amount ),
100, yPos);
yPos += 15;
}
}
}

CAPTULO IV
JAVA Y LA
PROGRAMACION
ORIENTADA A OBJETOS

Desde sus races, Java es un lenguaje


de programacin orientada a objetos
(OOP,
Object-Oriented
Programming). Resulta en extremo
importante, al aproximarse a Java,
entender este componente clave.

Java se desarroll pensando en una


herramienta
de
programacin
cliente/servidor, utilizada en especial en
redes; ahora bien, la orientacin a objetos
se adapta bastante bien a estas necesidades.
El cdigo orientado a objetos es
inherentemente reutilizable; el cdigo por
procedimientos tiende a ser mucho ms
rgido en su aplicacin. Es posible crear
objetos en un lugar, distribuirlos a travs
de una red y reutilizarlos siempre que se
requiera. Esto puede ahorrarle una gran
cantidad de tiempo y trabajo.

4.1 LA TERMINOLOGIA
DE LA OOP

Los tres trminos fundamentales


asociados con la OOP son objetos,
clases y mtodos.

4.1.1

OBJETOS

Un objeto es, primero que todo;


una abstraccin del mundo real.
Un objeto es, en trminos
computacionales, la representacin en
memoria
de
la
abstraccin
mencionada, y como tal, un ente
encapsulado que contiene Datos y
Mtodos, y que es capaz de recibir
mensajes.

La ilustracin que sigue representa un


modelo general de un objeto, el cual es la
piedra angular obvia de la programacin
orientada a objetos. Cada objeto contiene
variables de instancia especial del objeto.
Estas variables se accesan y manipulan a
travs de los mtodos del objeto; como
sugiere el modelo, los mtodos de un
objeto son el vehculo para interactuar
con otros objetos. Se crea una instancia
del objeto mismo a partir de una clase, la
cual es en esencia un anteproyecto.

Variables

La escritura de un objeto, consiste en


un conjunto de metodologas de
programacin que pretenden modelar
las caractersticas de objetos del mundo
real.

A su alrededor est rodeado por


objetos: autos, perros, gatos, caminos,
lo que sea. Cada objeto tiene un
estado, comportamiento e identidad
inherentes.
Por ejemplo: un gato tiene un estado,
digamos que el gato est echado,
limpindose, ese es el estado del gato.

Tambin tiene un comportamiento


inherente. Todos los gatos pueden correr,
saltar, comer, dormir, y toda una gran
variedad de cosas que hace que un gato
sea lo que es. Adems cada gato tiene
una identidad que lo diferencia de los
otros gatos. La identidad del gato Tom es
diferente a la del gato Vin.

Limpiarse
Permanecer
echado

Sucede lo mismo en el caso de los


objetos en el mundo de la programacin.
Los objetos proporcionan un modelo de
programacin y los objetos programados
tienen las mismas tres caractersticas
antes
mencionadas:
estado,
comportamiento e identidad. En este
caso, el estado del objeto est definido
por variables de instancia, que son
instancias del objeto y que se refieren
exclusivamente al objeto dado, amenos
que se defina lo contrario.

Las excepciones a esta regla son las


variables pblicas, las variables
protegidas y las variables consideradas
accesibles a las clases amistosas.
El comportamiento del objeto de
programacin est definido por sus
mtodos: lo que es capaz de hacer.
Estos mtodos afectan las variables de
instancia del objeto dndole un nuevo
estado.

De modo que si el gato se levanta y se


aleja tiene un nuevo estado. Este
carcter dinmico confiere a los
objetos su identidad. En otras
palabras, se pueden crear objetos
idnticos de la misma clase; cada uno
de ellos interactuar con otros objetos
a travs de los mtodos de la clase,
afectando sus valores de su variable de
instancia.

Debido a que estos objetos podran


reaccionar con diversos objetos de
distintas maneras, a travs del tiempo los
objetos mantendrn diferentes variables
de instancia y por lo tanto son nicos.

4.1.2

CLASES

El concepto ms importante de la
OOP es la clase. Las clases pueden
compararse como anteproyectos de
un edificio, pero no con el edificio en
s. Las clases son los anteproyectos de
los objetos.
En otras palabras, una clase es un
prototipo que define los mtodos y
datos que sern incluidos en un tipo
de objeto particular.

Otra forma de concebir las clases son como


patrones para hacer ropa. Una clase es a un
patrn como la pieza real de ropa es a un
objeto. Cuando los objetos se crean a partir
de una clase se denominan instancias de
clase en particular. Todos los artculos de
ropa hechos con el mismo patrn se
parecern
entre
s,
pudieran
estar
confeccionados de diferentes telas, pero
existe una relacin inherente entre ellos.
Sucede lo mismo entre las clases y los
objetos. Todos los objetos que son instancias
de una clase tienen algo en comn.

Por ejemplo, tal vez cuente con una clase


Tree que describe las caractersticas de
todos los rboles. La clase Tree sirve
como un modelo abstracto para el
concepto de un rbol; para alcanzar y
sujetar, o interactuar con l, o cortarlo
tendr que poseer una instancia concreta
del mismo. Por supuesto, en cuanto tenga
una clase rbol, puede crear muchas
instancias del mismo, y cada diferente
instancia
puede
tener
diversas
caractersticas, mientras todava se
comporte y se reconozca como rbol.

La figura siguiente ilustra la clase y las


instancias Tree.
rbol

Concreto
rbol
Clase rbol
(genrico)

rbol

4.1.3 MTODOS Y DATOS


(COMPORTAMIENTO
Y ATRIBUTOS

Cada clase que escribe con Java est,


por lo general, compuesta por dos
componentes:
atributos
y
comportamiento. En este ejemplo,
utilizaremos una clase terica llamada
Motorcycle.

Atributos (datos)
Los atributos son las caractersticas
individuales que diferencian a un
objeto de otro, y determinan la
apariencia, estado u otra cualidades de
ese objeto. Puesto que crearemos una
clase terica llamada Motorcycle,
entre sus atributos podemos describir
los siguientes:

Color: rojo, verde, plateado, caf.


Estilo: crucero, deportiva, estndar.
Fabricante: Honda,BMW, Butalco.
Los atributos de un objeto tambin
puede incluir informacin sobre su
estado; por ejemplo, puede contar con
caractersticas como condicin de la
mquina (apagada o encendida) o
velocidad actual seleccionada.

Los atributos se definen con


variables;
de
hecho,
puede
considerarlos como anlogos a las
variables globales del objeto
completo. Puesto que cada instancia de
una clase puede tener diferentes
valores para sus variables, a cada
variable se le llama una variable de
instancia.

Las variables de instancia definen los


atributos de un objeto. La clase define
el tipo de atributo, y cada instancia
guarda su propio valor para ese
atributo.
Cada atributo cuenta con una
correspondiente variable de instancia;
as que, al cambiar el valor de una
variable se combina el atributo de ese
objeto.

Las variables de instancia pueden fijarse


cuando se crea un objeto y permanecen
constantes durante la vida del objeto, o bien
se pueden habilitar para cambiar como se
desee al ejecutarse el programa.
Adems de las variables de instancia,
tambin se encuentran las variables de
clase, las cuales se aplican a todas las clase
y a todas sus instancias. A diferencia de las
variables de instancia, cuyos valores se
almacenan en la instancia, los valores de las
variables de clase se almacenan en la clase
misma.

Comportamiento (Mtodos)
El comportamiento de clase determina
que instancias de esa clase requieren
cambiar su estado interno, o cuando esa
instancia es llamada para realizar algo
por otra clase u objeto.
El comportamiento es la nica manera
de que los objetos, puedan hacerse algo a
si mismos o tener que hacerles algo. Por
ejemplo, en la clase Motorcycle podemos
encontrar algunos comportamientos:

Arrancar la mquina.
Detener la mquina.
Acelerar.
Cambiar de velocidades.
Frenar.

Para definir el comportamiento de un


mtodo, usted crea mtodos, las cuales tienen
una apariencia y un comportamiento igual al
de las funciones en otros lenguajes, pero se
definen dentro de una clase. Java no cuenta
con funciones definidas fuera de una clase
(como los tiene C++).

Los mtodos son funciones definidas


dentro de las clases que operan en las
instancias de esas clases.
Los mtodos no siempre afectan a un
solo objeto; los objetos tambin se
comunican entre s mediante el uso de
los mtodos. Una clase u objeto puede
llamar a otros mtodos en otra clase u
objeto para avisar sobre los cambios en
el ambiente o para solicitarle a ese
objeto que cambie su estado.

As como existen variables de instancia


y de clase, tambin hay mtodos de
ambos tipos. Los mtodos de instancia
(que son tan comunes que es normal
que se les llame solo mtodos) se
aplican y operan en una instancia de
clase; los mtodos de clase, se aplican y
operan en la clase misma.

4.1.4

CREACION DE
OBJETOS Y
CLASES.

Creacin de una clase


La declaracin completa de una clase
puede aparecer slo una vez en un
programa, tal y como en las estructuras.
Esta es la declaracin de una clase
simple:
public class Class1
{ int count;

void SetValue ( int value)


{
count = value;
}
int GetValue ( )
{
}
}

return count;

En el caso de los identificadores de


clase, se aplican las mismas reglas que
para cualquier otro nombre de tipo o
variable.
La variable count se define dentro del
cuerpo de la clase. Por tanto, count
recibe el nombre de variable miembro de
la clase.
La clase Class1 declara las funciones
SetValue(long) y GetValue(). Se
conocen como funciones miembro de la
clase.

Creacin de un nuevo objeto


Para crear un objeto nuevo, utilice new,
con el nombre de la clase de la cual
desea crear una instancia, seguido de
parntesis:
String str = new String ( );
Random r = new Random ( );
Motorcycle m2 = new Motorcycle ( );

Los parntesis pueden estar vacos, en


cuyo caso se crear el objeto bsico
ms simple, o bien, puede contener
argumentos que determinen los valores
iniciales de las variables de instancia, u
otras cualidades iniciales de ese objeto.
El nmero y tipo de argumentos que
puede utilizar con new, estn definidos
con la clase misma al emplear un
mtodo especial llamado constructor.

Ejemplo 1:
import java.awt.*;
import java.applet.*;
public class Class1 extends Applet {
public class Counter
{ int count;
void SetValue ( int value)
{
count = value; }
int GetValue ( )
{
return count; }
}

public void paint (Graphics g)


{
Counter a=new Counter();
a.SetValue (5);
g.drawString("El valor es= "
+ a.GetValue(), 5 , 30);
}
}

Ejemplo2:
Se toma la clase Date, la cual crea un
objeto de fecha.
import java.util.Date;
import java.awt.Graphics;
import java.applet.Applet;
public class Class1 extends Applet {
Date system, user;
public void init()
{

system = new Date();


user = new Date(96,6,4);
}
public void paint (Graphics g)
{
g.drawString("Fecha del
sistema:

+system.toString(),25,25);
g.drawString("Fecha del
usuario: "
+user.toString(),25,40);
}
}

Cuando emplea new suceden varias


acciones: se crea la nueva instancia de la
clase dada y se le asigna memoria, cuando se
crea el nuevo objeto, se llama a un mtodo
especial definido en la clase dada, el cual se
conoce como constructor.
Los constructores son mtodos especiales
para crear e inicializar nuevas instancias de
clase. Inicializan el nuevo objeto y sus
variables, crean cualquier otro objeto que
necesiten y realizan cualquier otra operacin
para inicializarse a si mismos.

El uso ms comn de constructor es


el de inicializar los datos de los
miembros del objeto. Las funciones
constructor tienen el mismo nombre
del objeto
clase. Las funciones
constructor se definen dentro del
applet, como se hara en cualquier
mtodo clase. La nica diferencia es
que no se especifica el tipo de valor
devuelto.

Cuando se declare un objeto pueden


pasarse parmetros a constructor,
como se muestra a continuacin:

Class_name object
(value,value2,value3);

Clases abstractas
Una de las caractersticas ms tiles de
cualquier lenguaje orientado a objetos es
la posibilidad de declarar clases que
definen como se utiliza solamente, sin
tener que implementar mtodos.
Esto es muy til cuando la
implementacin es especfica para cada
usuario, pero todos los usuarios tienen
que utilizar los mismos mtodos. Un
ejemplo de clase abstracta en Java es la
clase Graphics:

public abstract class Graphics {


public abstract void drawLine( int
x1,int y1,int x2,int y2 );
public abstract void drawOval( int x,int
y,int width, int height );
public abstract void drawArc( int x,int
y,int width, int height,int startAngle,int
arcAngle );
...
}

Los mtodos se declaran en la clase


Graphics, pero el cdigo que ejecutar el
mtodo est en algn otro sitio:
public class MiClase extends Graphics {
public void drawLine( int x1,int y1,int
x2,int y2 ) {
<cdigo para pintar lneas
-especfico de
la arquitectura->
}
}

Cuando una clase contiene un mtodo


abstracto tiene que declararse abstracta.
No obstante, no todos los mtodos de
una clase abstracta tienen que ser
abstractos. Las clases abstractas no
pueden tener mtodos privados (no se
podran implementar) ni tampoco
estticos. Una clase abstracta tiene que
derivarse obligatoriamente, no se puede
hacer un new de una clase abstracta.

Una clase abstracta en Java es lo


mismo que en C++ virtual func() = 0;
lo que obliga a que al derivar de la
clase
haya
que
implementar
forzosamente los mtodos de esa clase
abstracta.
Nota: La administracin de la
memoria en Java es dinmica y
automtica, cuando se crea un nuevo
objeto en Java, ste, en forma
automtica designa la cantidad de
memoria adecuada para ese objeto en

Acceso y configuracin de los


valores de instancia y de clase
Para obtener el valor de una variable
de instancia, utilice la notacin de
punto.
Con la notacin de punto, un nombre
de variable de instancia o de clase
tendrn dos partes: el objeto, al lado
izquierdo del punto, y la variable al
lado derecho.

Por ejemplo, si tiene un objeto asignado


a la variable myObject y ese objeto tiene
una variable llamada var, se referir al
valor de esta manera:

myObject .var;

Esta forma de tener acceso a las


variables es una expresin (regresa un
valor), as mismo son expresiones a
ambos lados del punto; puede anidar el
acceso a las variables de instancia . Si
var mantiene un objeto y este tiene su
propia variable de instancia llanmada
state, puede referirse a l de esta
manera:
myObject.var.state;
Las expresiones de punto se evalan de
izquierda a derecha.

Cmo cambiar valores


Para asignarle valor a una variable, slo
inserte un operador de asignacin al lado
derecho
de
la
expresin:
myObject.var.state = true;
Para obtener acceso a las variables de
clase, utilice la misma notacin de punto,
al igual que en las de instancia. Para
obtener o cambiar el valor de una clase,
puede usar la instancia o el nombre de la
clase al lado izquierdo del punto.

Llamar a un mtodo en los objetos


es similar a referirse a sus variables de
instancia; las llamadas a los mtodos
tambin utilizan la notacin de punto.
El objeto cuyo mtodo llama, est en el
lado izquierdo del punto; en tanto el
nombre de mtodo y sus argumentos se
encuentran al lado derecho del punto

Referencias a objetos
Al trabajar con objetos se hace uso
de las referencias a dichos objetos.
Cuando asigna objetos a las variables,
o los pasa a los mtodos como
argumentos, usted traslada referencias
a ellos , no los objetos mismos o las
copias de sos.

import java.awt.Point;
class ReferencesTest {
public static void main (String args[]){
point pt1,pt2;
pt1 = new Point(100, 100);
pt2 = pt1;
pt1.x = 200;
pt1.y = 200;
system.out.printl(Point1: + pt1.x + ,
+ pt1.y);
system.out.printl(Point2: + pt2.x + ,
+ pt2.y);
}
}

Se declaran dos variables de tipo


Point y asigna un nuevo objeto de
este tipo a pt1, despus asigna el
valor de pt1 a pt2.
La salida de este programa sera:
Point1: 200, 200
Ponit2: 200, 200

Como podr ver pt2 tambin se


modific, cuando se asigna el valor de
pt1 a pt2, de hecho crea una referencia al
mismo objeto al cual se refiere pt1. Si
cambia el objeto al que se refiere pt2,
tambin modificar al objeto que apunta
a pt1, ya que ambos se refieren al mismo
objeto.
pt1
pt2

Objeto punto
x:200
y:200

En Java no existen apuntadores


explcitos o aritmtica relacionada con
ellos, solo hay referencias. Sin
embargo con estas y con los arreglos
Java, posee la mayora de las
capacidades que tendra con los
apuntadores.

4.2
LAS
CARACTERISTICAS
DE LA OOP
(ENCAPSULAMIENTO,
POLIMORFISMO,
HERENCIA,
VINCULACION
DINAMICA)

Existen
principales:

cuatro

caractersticas

Encapsulamiento
Polimorfismo
Herencia
Vinculacin dinmica

Estos conceptos permiten integrar


todas las piezas y hacen de la OOP lo
que es. Proporcionan funcionalidad y
control en el diseo del programa.

4.2.1

ENCAPSULAMIENTO

El encapsulamiento es una forma de


ocultar y proteger informacin. Otra
forma de escribirlo es como un
empaquetado. Las clases realmente
ocultan o empacan sus datos de las
otras clases. El encapsulamiento
permite
a
los
programadores
descomponer grandes sistemas en
subsistemas
encapsulados
ms
pequeos que son ms fciles de
desarrollar y darles mantenimiento.

Para
darse
una
idea
del
encapsulamiento, imagine que tiene
problemas con su automvil, falla el
filtro del aceite y olvid remplazarlo. Al
paso del tiempo el aceite se ensucia
mucho ms, esto a su vez puede dar
lugar a otros problemas con el motor. El
motor
del
automvil
no
esta
encapsulado, es decir, el aceite no est
oculto o protegido del motor.

En programacin, el encapsulamiento
permite construir subsistemas (como un
motor virtual) que no pueden ser
manipulados o corrompidos por otros
subsistemas, a menos que se le otorgue
un permiso especial. Un error en alguno
no corromper a otro.
Cuando se crea una nueva clase en Java,
se puede especificar el nivel de acceso
que se quiere para las variables de
instancia y los mtodos definidos en la
clase:

public
Public void
CualquieraPuedeAcceder(){}
Cualquier clase desde cualquier lugar
puede acceder a las variables y
mtodos de instacia pblicos.

Ejemplo:
import java.awt.*;
import java.applet.*;
public class Class1 extends Applet
{
class PublicExample {
public int variable;
int funtion()
{return (1);}
}
}

Class2:
import java.awt.*;
public class Class2
{
public void paint(Graphics g)
{
Class1 objeto= new Class1();
objeto.variable=3; //Es posible
acceder

g.drawString("El valor de la funcin


es: " + objeto.funtion(),5,30);
g.drawString("El valor de la funcin
es: " + objeto.variable,5,30);
}
}

private
private String
NumeroDelCarnetDeIdentidad;
Las variables y mtodos de instancia
privados slo pueden ser accedidos
desde dentro de la clase. No son
accesibles desde las subclases.

Class1:
import java.awt.*;
import java.applet.*;
public class Class1 extends Applet
{

private int variable;


private int function()
{return (1);}

Class2:
import java.awt.*;
public class Class2
{
public void paint(Graphics g)
{
Class1 objeto= new Class1();
objeto.variable=3; //No es posible
acceder
g.drawString("El valor de la funcin es: "
+ objeto.funtion(),5,30);
g.drawString("El valor de la funcin es: "
+ objeto.variable,5,30); }

En este ejemplo Java mostrara el


siguiente error:
No se puede tener
miembro privado...

acceso

al

protected
protected void SoloSubClases(){}
Slo las subclases de la clase y nadie
ms puede acceder a las variables y
mtodos de instancia protegidos.

friendly (sin declaracin especfica)


void MetodoDeMiPaquete(){}
Por defecto, si no se especifica el
control de acceso, las variables y
mtodos de instancia se declaran
friendly (amigas), lo que significa que
son accesibles por todos los objetos
dentro del mismo paquete, pero no por
los externos al paquete. Es lo mismo
que protected.

Los mtodos protegidos (protected)


pueden ser vistos por las clases
derivadas, como en C++, y tambin, en
Java, por los paquetes (packages).
Todas las clases de un paquete pueden
ver los mtodos protegidos de ese
paquete. Para evitarlo, se deben
declarar como private protected, lo que
hace que ya funcione como en C++ en
donde slo se puede acceder a las
variables y mtodos protegidos de las
clases derivadas

4.2.2

POLIMORFISMO

El polimorfismo se refiere a la
naturaleza de los objetos. Los
mensajes enviados de un objeto a otro
dan por resultado un comportamiento
distinto entre los diversos objetos. El
comportamiento es dependiente de la
naturaleza del objeto dado. Este
polimorfismo contribuye a que los
objetos de la OOP sean reutilizables.

Por ejemplo, el gato tiene un sistema


nervioso, el cual recibe mensajes de las
diferentes partes del cuerpo y las enva al
cerebro. El polimorfismo, permite que el
objeto cerebro reciba una gran variedad
de mensajes sin tener que saber en
realidad cual est recibiendo. Puede
aceptar mensajes diferentes de todos los
tipos de objetos; el objeto cerebro no
requiere necesariamente de un mtodo
especfico por cada objeto del cual
pudiera recibir un mensaje.

4.2.3

HERENCIA

Uno de los aspectos ms extraordinario de


los seres vivientes es su capacidad de
generar descendencia con caractersticas
similares a sus progenitores.
La
naturaleza tardo millones de aos en
generar la vida tal como la conocemos, y
la suma de ese esfuerzo se transmite a
todos y cada uno de los descendientes de
toda y cada una de las especies. Este es el
resultado de la herencia. Ninguna forma
de vida, con su infinita complejidad, sera
posible sin la herencia.

Si la herencia condujo a resultados tan


impresionantes en la naturaleza
tambin debe ser de utilidad en el
software de computadora como una
forma de propagar cdigo para su uso
futuro y de reducir la complejidad del
cdigo. Est pensamiento abord a
cientficos en las dcadas de 1960 y
1970 dando origen al desarrollo de
lenguajes de programacin que
emplean diversas formas de herencia.

La herencia permite construir y


extender
continuamente
clases
desarrolladas por usted o por alguien
ms, bsicamente sin limite. Partiendo
de la clase ms simple, se pueden
derivar clases cada vez ms complejas
que no slo son fciles de depurar, sino
que tambin son simples por s solas.

Las clases pueden construirse en forma


incremental partiendo de clases bsicas
y simples mediante el uso de la
herencia. Cada vez que se deriva una
clase partiendo de una anterior, se
pueden heredar algunas o todas las
caractersticas de las clases primarias o
progenitoras, agregando nuevas segn
se necesiten. Un proyecto completo
puede tener calificaciones o cientos de
clases; pero estas clases se derivan a
menudo de algunas clases bsicas.

Reutilizacin
Reutilizacin es una palabra que se
escucha a menudo en el mundo de la
programacin orientada a objetos. Se
refiere a tomar una clase e instanciarla
directamente en sus programas o bien
utilizarla como una base nueva clase
que herede algunas de o todas sus
caractersticas. Derivando de una clase
de una clase base, usted efectivamente
reutiliza el cdigo de la clase de base
para satisfacer sus necesidades.

El concepto es paralelo al trabajo de la


naturaleza: DNA o ADN, podra ser
considerado como un material bsico,
del cual puede generar cualquier
criatura.
Todo organismo reutiliza
DNA o ADN, empleando una variedad
propia de l.
la facilidad de
reutilizacin en C++ se implica atraves
de la herencia.

La herencia, interfaces y paquetes,


son mecanismos para organizar clases
y el comportamiento de la clase.
Puesto que el comportamiento de las
clases Java utilizan todos estos
conceptos, las mejores bibliotecas de
clase que escriba para sus propios
programas tambin los usarn.

La herencia es probablemente la
caracterstica que da mayor poder al
concepto de clase, ya que permite
construir
y
extender
clases
desarrolladas bsicamente sin lmite.
Partiendo de la clase ms simple, se
pueden derivar cada vez ms
complejas que no solo son fciles de
depurar, sino que tambin son
simples por s solas.

Cada vez que se deriva una nueva


clase partiendo de una anterior, se
pueden heredar algunas o todas las
caractersticas de las clases primarias o
progenitoras, agregando nuevas segn
se necesiten. Esta derivacin ofrece
mucha flexibilidad a un bajo costo en
trminos de codificacin. Cuando se
tiene una clase de base slida solo es
necesario depurar los cambios
necesarios en las clases derivadas

Con la herencia todas las clases estn


arregladas dentro de una jerarqua
estricta. Cada clase tiene una
superclase, (la clase superior en la
jerarqua), y puede tener una o ms
subclases (las clases de abajo en esa
jerarqua). Se dice que las clases
inferiores en la jerarqua, heredan de
las clases ms altas.

4.2.3.1

JERARQUA
DE CLASES

Clase A

Clase B

Clase C

Clase D

Clase E

1.La clase A es la superclase de B


2.La clase B es la subclase de A
3.La clase B es la superclase de C, D y E
4.Las clases C, D y E son subclases de B

Las subclase heredan todos los mtodos y


variables de las superclases; es decir, en
cualquier clase particular, si la superclase
define un comportamiento que su clase
necesita, no se tendr que volver a definir
o copiar ese cdigo de alguna otra clase.
La clase, en forma automtica, obtiene ese
comportamiento de su superclase, y as
sucesivamente, hacia arriba de la
jerarqua. La clase se convierte en una
combinacin de todas las caractersticas
de las clases arriba de ella, en la jerarqua.

En la parte superior de la jerarqua de


clase Java esta es la clase Object; todas
las clases heredan de esta superclase.
Esta es la clase ms general en la
jerarqua,
ya
que
define
el
comportamiento heredado por todas las
clases en la jerarqua de clase Java. Cada
clase hacia abajo agrega ms informacin
y se vuelve ms apta para un propsito
especfico.

De esta manera, puede pensar en una


jerarqua de clase como la definicin
de conceptos demasiado abstractos
en lo alto de la jerarqua, y esas ideas
se convierten en algo mas concreto
conforme desciende de la cadena de
la superclase.

La subclasificacin, implica crear


alguna nueva clase que heredar de
alguna otra clase en la jerarqua. Al usar
la subclasificacin, solo es necesario
definir las diferencias entre la clase y su
padre; el comportamiento adicional est
disponible para su clase mediante la
herencia.

Para un conjunto grande de clases, es


necesario que estas clases no solo
hereden de la jerarqua de clases
existente, sino que tambin hagan por
si mismas una jerarqua. Esto puede
implicar una planeacin previa al
intentar organizar su cdigo Java,
aunque las ventajas son significativas,
una vez que estas se realizan:

Cuando desarrolla subclases en una

jerarqua,
puede
descomponer
informacin comn para mltiples
clases en superclases, y despus
volver a utilizar esa informacin de
esa superclase otra vez. Cada
subclase obtendr esa informacin
comn de esa superclase.

Cambiar

(insertar) una clase hacia


arriba en la jerarqua, de manera
automtica
modifica
el
comportamiento de las clases
inferiores, no hay necesidad de
cambiar o volver a compilar alguna
de las clases mas bajas, ya que
obtiene nueva informacin mediante
la herencia y no al copiar algo del
cdigo.

En la parte superior de la jerarqua se


encuentra la clase Object, la cual es la
raz de todas las clases Java. La clase
ms general a la cual pertenece una
motocicleta y un automvil puede
llamarse vehicle. Un vehculo por lo
general se define como aquello que
lleva a alguien de un lugar a otro, pero
en esta clase definir solo el
comportamiento que le permite a una
persona transportarse de un lugar A
aun lugar B, y nada ms.

Objeto

Vehculo

Vehculos movidos
por el hombre

Vehculos movidos
por motor

Ahora seamos ms especficos.


Con vehculos movidos por motor,
podra tener varias clases: Motorcycle,
Car, Truck entre otras; o podra
descomponer
ms
aun
el
comportamiento
y
tener
clase
intermedias para vehculos dos ruedas
y cuatro ruedas, con diferentes
comportamientos para cada uno, vase
la figura:

Vehculos de dos y de cuatro ruedas


Vehculos movidos
por motor

Vehculos movidos
por motor y de dos
ruedas

Motocicleta

Vehculos movidos por


motor y de cuatro ruedas

Motoneta

Motocicleta con
pedales

Con la subclase para los vehculos


movidos por motor y de dos ruedas
puede tener, al final, una clase para
motocicletas con pedales. En forma
opcional,
podra
definir
adicionalmente
motonetas
y
motocicletas con pedales, las cuales
son dos vehculos movidos por motor
y de dos ruedas, pero tienen diferentes
particularidades con relacin a las
motocicletas.

4.2.3.2 FUNCIONAMIENTO
DE LA HERENCIA

En las variables de instancia cuando


crea una nueva clase, obtiene una
ranura para cada clase definida en la
clase actual, y para cada variable
definida en todas sus superclases. De
esta manera, todas las clases se
combinan para formar una nueva
plantilla para el objeto actual, y
despus cada objeto llena el hueco de
la informacin adecuada para su
situacin.

Los mtodos operan de manera similar, los


objetos nuevos tienen acceso a todos los
nombres de su clase y de su superclases, pero
las definiciones de mtodos se eligen en
forma dinmica cuando se llama a un
mtodo. Si usted llama a un mtodo en
particular, Java primero revisa en la clase del
objeto al buscar la definicin de ese mtodo.
Si no est definida la clase del objeto, busca
en la superclase de la clase, y as en lo
sucesivo arriba de la cadena, hasta que
encuentra la definicin del mtodo. Vase la
figura:

Cmo se localizan los mtodos


Definicin
del mtodo

Clase

Clase

Clase

Clase

Clase

Objeto

El mensaje se enva al
objeto y se transmite
a las clases superiores
de la jerarqua hasta
encontrar
una
definicin
Objeto

Sobreponer un mtodo es la forma de


crear un mtodo en una subclase que
tenga la misma identificacin (nombre,
nmero y tipo de argumentos) de un
mtodo en una superclase. Ese nuevo
mtodo oculta el mtodo de la
superclase. Vase la figura:

Cmo sobreponer los mtodos


Definicin
inicial del
mtodo

Clase
El mtodo es
sobrepuesto
mediante esta
definicin

Clase

El mensaje se enva al
objeto y se transmite a
las clases superiores de
la
jerarqua
hasta
encontrar una definicin

Clase

Clase

Objeto

Objeto

4.2.3.3 HERENCIA SENCILLA


Y MULTIPLE

La forma en que hereda Java, se


llama herencia sencilla, lo que
significa que cada clase Java solo
puede tener una superclase.

Siempre que se construya una nueva


clase, se debe determinar si puede
utilizar una clase preexistente como
clase de base, si se encuentra una
clase
que
proporcione
el
comportamiento indicado, puede
heredar las caractersticas deseadas y
deshabilitar las no deseadas. Para
deshabilitar una funcin de la clase
progenitora o primaria, se emplea la
tcnica sobrecarga de funciones.

La sobrecarga de funciones se refiere


a cargar una funcin con ms de un
significado; es decir, que se cargan
uno o ms identificadores de
funciones sobre un identificador
previo. Tener ms de una funcin con
el mismo identificador implica que las
funciones sobrecargadas implica que
ya no pueden ser diferenciadas slo
por su identificador, se distinguen por
el nmero y tipo de argumentos.

La sobrecarga de funciones ofrece una


enorme flexibilidad y simplifica la
programacin, permitiendo trabajar con
un solo nombre de funcin para realizar
varias
tareas
similares.
Con
constructores sobrecargados se permite
que el usuario especifique qu
variables han de ser inicializadas de
manera explcita y cules deben de
asumir valores definidos.

Uno de los usos ms comunes de la


sobrecarga es la utilizacin de una
funcin para obtener un resultado,
aunque los tipos de parmetros sean
diferentes. Por ejemplo, suponga que
el applet tiene una funcin llamada
DaDeLaSemana, la cual devuelve el
da actual de la semana (0 para
domingo, 1 para lunes, ..., 6 para
sbado).

Se puede sobrecargar la funcin para


que devuelva el da de la semana
correcto si se pasa el da juliano (nmero
consecutivo del da en el ao, febrero 1
es el da juliano 32) como parmetro, o
si se especfica da, mes y ao:

Int DaDeLaSemana(int dia_juliano)


{
// sentencias
}
int DaDeLaSemana(int mes, int da,
int ao)
{
// sentencias
}

El siguiente Applet sobrecarga la


funcin AddValues. La primera
definicin suma dos valores de tipo int.
La segunda, suma tres valores. En la
etapa de compilacin Java determina la
funcin correcta que ha de emplearse:

import java.awt.*;
import java.applet.*;
public class OverloadAddvalues
extends Applet
{
int AddValues ( int a, int b)
{
return (a + b);
}
int AddValues ( int a, int b, int c)
{
return (a + b + c);
}

public void paint (Graphics g)


{
g.drawString(1+ 2 = +
AddValues (1,2 ), 5 , 15);
g.drawString(1+ 2 + 3 = +
AddValues (1,2, 3 ), 5 , 30);
}
}

De igual manera el Applet siguiente


sobrecarga la funcin ShowMessage.
La primera definicin despliega un
mensaje si no se pasan parmetros; la
segunda muestra el mensaje pasado y la
tercera escribe dos mensajes:

import java.awt.*;
import java.applet.*;
public class
OverloadShowMessage extends
Applet
{
int ShowMessage (Graphics g ,
String Message)
{
g.drawString (Message , 5 ,
15);
}

void ShowMessage (Graphics g,


String first, String second)
{
g.drawstring (first + second,
5 , 30);
}
public void paint (Graphics g)
{
ShowMessage (g, Java);
ShowMessage (g, Java ,
es realmente fcil );
}
}

En otros lenguajes de programacin


orientado a objetos, como C++, las clase
pueden tener ms de una superclase, y
heredan con variables y mtodos
combinados de todas las clases. A esto se le
llama herencia mltiple, la cual puede
ofrecer un poder enorme, en trminos de ser
capaz de crear clases que descomponen casi
cualquier comportamiento imaginable, pero
tambin pueden complicar en forma
significativa las definiciones de las clases y
el cdigo para producirlas. Java hace la
herencia ms simple al emplear slo la
herencia sencilla. 32

4.3 EJEMPLOS

El siguiente cdigo muestra la definicin


de una clase Point (punto) y las
definiciones de los mtodos de Point:
4:
5:
6:
7:
8:
9:

public class Point {


protected double x,y;
//constructor
public Point (double a, double b) {
setPoint(a,b);}

10: //fijar las coordenadas x,y del


Point
11: public void setPoint(double a,
double b)
12: {
13: x=a;
14: y=b;
15: }
16:
17: //obtener la coordenada x
18: public double getX() { return x;}

19:
20: //obtener la coordenada en y
21: public double getY() {return
y;}
22:
23: //convertir el punto en una
representacin String
24: public String toString()
25:
{return "[" + x "," + y
+"]";}
26: }

27:
28: //definicin de la clase Circle
29:
30: public class Circle extends
Point {
31: protected double radius;
32:
33: //constructor sin argumentos
34: public Circle()
35: {
36:
super(0,0);

37:
setRadius(0);
38: }
39:
40: //constructor
41: public Circle (double r, double
a, double b)
42: {
43:
super (a,b);
44:
setRaduis(r);
45: }
46:
47: //establecer el radio del circulo

48: public void setRadius(double r)


49: { radius = (r >= 0.0 ? r: 0.0);}
50:
51: //obtener el radio del circulo
52: public double getRaduis()
{return radius;}
53:
54: //calcular el area del circulo
55: public double area(){ return
3.14159*radius * radius;}
56:

57: //convertir el Circle en un


string
58: public String toString()
59: {
60: return "Centro = "+ "[" + x
+"," + y + "]" +
61: "; Radio = "+ radius;
62: }
63: }
64:
65: //mutacin de referncias de
superclasea referncias de subclase

66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:

import java.awt.Graphics;
import java.applet.Applet;
public class Test extends Applet{
private Point pointRef, p;
private Circle circleRef, c;
public void init()
{
p= new Point (3.5, 5.3);
c= new Circle (2.7,1.2,8.9);

77: }
78:
79: public void paint (Graphics g)
80: {
81:
g.drawString("Punto p: "+
p.toString(), 25,25);
82:
g.drawString("Circulo c: "
+ c.toString(),25,40);
83:
84:
85:
pointRef=c;
86: g.drawString("Circulo c (va
por ref):" +

87:
pointRef.toString(),25,70);
88:
89: //tartar un Circle como un
Circle con algo de mutacin
90: pointRef=c;
91: circleRef=(Circle)
pointRef;
//mutar super a sub
92: g.drawString ("Circulo c (va
circleRef):" +
93: circleRef.toString(),25,100);

94: g.drawString ("Area de c (va


circleRef):" +
94: circleRef.area(),25,115);
96:
97 :
98: //se refiere a un objeto Point
con una referncia Circle
99: circleRef=(Circle) p;
100: }
101: }

Las lneas 1-26 son la definicin de


una clase Point y las definiciones de
los mtodos de Point. En las lneas
27-63 aparece una definicin de la
clase Circle y sus mtodos; la clase
Circle hereda de la clase Point. Las
lneas 64-101 corresponden a un
programa que muestra la asignacin
de referncias de subclase a referncias
de superclase y la mutacin de
referencias de superclase a referencias
dede subclase.

Ejemplo
de
constructores
finalizadores en subclases
3:
4:
5:
6:
7:
8:
9:
10.

public class Point {


protect double x,y;
//constructor
public Point(double a, double b)
{
setPoint(a,b);
System.out.println
("Constructor de Point: " +

11:
toString());
12: }
13:
14: //finalizador
15: public void finalize()
16: {
17: System.out.println("Finalizador
de Point: " +
18: toString());
19: }
20:

21: //fijar las coordenadas del punto


Point
22: public void setPoint (double a,
double b)
23: {
24:
x=a;
25:
y=b;
26: }
27:
28: //obtener la coordenada x
29: public double getX() { return x;}
30:
31: //obtener la coordenada y

32: public double getY() { return


y;}
33:
34: //convertir el punto en un
coordenada string
35: public String toString()
36: {return "[" + x "," + y + "]";}
37: }
38:
39: //Definicin de la clase Circle
40:
41: public class Circle extends
Point {

42: protect double radius;}


43:
44: //constructor sin argumnetos
45: public Circle()
46: {
47: super(0,0);
48: setRadius(0);
49:
System.out.println("Constructor de
Circle:" +
50:
toString());

51: }
52:
53: //constructor
54: public Circle(double r, double
a, double b)
55: {
56: super(a,b);
57: setRadius(r);
58: System.out.println
("Constructor de Circle:" +
59:
toString());
60: }
61:

62:
63:
64:
65:

//finalizador
public void finalize ()
{
System.out.println
("Finalizador de circle: " +
66:
toString());
67: }
68:
69:
70: public void setRadius(double
r)
71: { radius = (r>=0 =? r:0);}
72:

73:
74: public double getRadius() {
return radius; }
75:
76:
77: puiblis doble ares()
78: { return 3.14159 * radius *
radius;}
79:
80:
81: public String toString()

82: {
83: return
"Centro=
"+
super.toString()+
84:
"; Radio= " + radius;
85: }
86: }
87:
88: //Demostracin de cundo se
invocan los constructores y
89: // finalizadores de la superclase y
la subclase.
90: import java.awt.Graphics;

91: import java.applet.Applet;


92:
93: public class Test extends
Applet{
94: private Circle circle1, circle2;
95:
96: public void init()
97: {
98: circle1 = new Circle (4.5, 7.2,
2.9);
99: circle2 = new Circle (10,5,5);
100: }
101:

102: public void start()


103: {
104: circle1 = null;
105: circle2 = null;
106:
107: System.gc(); //llamar al
recolector de basura.
108: }
109:
110: public void paint (Graphics g)
111: {
112: g.drawString(

113: "vea el resultado en la lnea de


comandos o en la consola de
Java",
114: 25,25);
115: }
116: }

La clase Pont lneas 1-37 contiene un


constructor, un fianlizador y otros
mtodos public y las variables de
ejemplar protegidas x y y . Tanto el
constructor como el finalizador imprimen
una indicacin de que se estn ejecutando
y luego exhiben el Point para el cual se
invocaron. La clase Circle (lneas 38-36)
se derivan de Point y contiene dos
constructores, un finalizador y otros
mtodos public y la variable de ejemplar
protegida radius (radio). 0

Tanto los constructores como el


finalizador imprimen una indicacin de
que se estn ejecutando y luego exhiben
el Circle para el cual se invocaron.
Adems el constructor Circle tambin
invoca el constructor Point mediante
super y pasa los valores a y b a fin de
inicializar las variables de ejmplar de la
superclase. El mtodo toString de
Circle invoca el toStrig de Point
mediante super (lnea 83).

El siguiente ejemplo da una muestra de


herencia con la jerarqua de Punto,
Crculo y Cilindro.
Se desarrolla la clase Point (Lneas 126 es la definicin de la clase) las
variables de ejemplar de Point son
protected. De este modo cuando se
derive la clase Circle de la clase Point,
los mtodos de la clase Circle podrn
hacer referncia directamente a las
coordenadas x y y en lugar de tener
que usar mtodos de acceso.

Las lneas 27 a 49 es un applet llamada


Test que prueba la clase Point. El
mtodo paint necesita usar los mtodos
getX y getY para leer los valores de
ejemplar protegidas de x y y.
1:
2: //definicin de la clase Point
3:
4: public class Point{
5: protected double x,y;
6:

7:
8:

//constructor
public Point(double a, double b){
setPoint(a,b);}

9:
10: //fijar las coordenadas x,y del
Point
11: public void setPoint(double a,
double b)
12: {
13:
x=a;
14:
y=b;
15: }
16:

17: //obtener la coordenada x


18: public double getX() {return x;}
19:
20: //obtener la coordenada y
21: public double getY() {return y;}
22:
23: //convertir el punto en una
representacin Sstring
24: public String toString()
25: {return "[" + "," + y + "]";}
26:}
27:

28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:

//applet para probar la clase Point


import java.awt.Graphics;
import java.applet.Applet;
public class Test extends Applet{
private Point p;
public void init()
{
p=new Point(7.2,11.5);
}

40: public void paint (Graphics g)


41: {
42: g.drawString("La coordenada X
es" + p.getX(),25,25);
43: g.drawString("La coordenada Y
es" + p.getY(),25,40);
44:
45: p.setPoint(10,10);
46: g.drawString("La nueva posicin
de p es "+
47: p.toString(),25,70);
48: }
49: }

En este ejemplo se utiliza la


definicin de la clase Point y las
definiciones de los mtodos de clase
para Point y Circle. Las lneas1-38
muestra la definicin de la clase
Circle con las definiciones de los
mtodos de Circle. Las lneas 39 65
muestran un applet de prueba Test. La
clase Circle extiende (extends) la
clase Point .

Esto significa que la interfz pblica con


Circle incluye los mtodos de Point,
adems de los mtodos getRadius
(obtener radio) area, toString (acadena)
de Circle y los dos constructores Circle.
Esta applet ejemplariza un objeto de la
clase Circle (lnea 49) y luego utiliza
mtodos get para obtener informacin
relativa al objeto Circle. El mtodo paint
de la applet Test hace referencia indirecta
a los datos protegidos de la clase Circle
mediante llamadas de mtodos.

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

//Definicin de la clase Circle:


public class Circle extends Point {
protected double radius;
//constructor sin aragumentos
public Circle()
{
super(0,0);
setRadius(0);

12: }
13:
14: //constructor
15: public Circle (double r, double
a, double b)
16: {
17:
super (a,b);
18:
setRaduis(r);
19: }
20:
21: //fijar el radio del circle
22: public void setRadius(double r)
23: { radius = (r >= 0.0 ? r: 0.0);}

24:
25: //obtener el radio del Circle
26: public double getRaduis()
{return radius;}
27:
28: //calcular el rea del Circle
29: public double area
30: (){ return 3.14159*radius *
radius;}
31: {
32: //convertir el Circle en String
33: public String toString()
34: {

35: return "Centro = "+


super.toString()
36: Radio=" + radius;
37: }
38:}
39:
40: Applet para probar la clase
Circle
41: import java.awt.Graphics;
42: import java.applet.Applet;
43:
44: public class Test extends
Applet{

45:
46:
47:
48:
49:
50:
51:
52:
53:
54:

private Circle c;
public void init()
{
c=new Circle(2.5,3.7,4.3);
}
public void paint (Graphics g)
{
g.drawString("La
coordenada X es" +
c.getX(),25,25);

55:
56:
57:
58:
59:
60:

g.drawString("La
coordenada Y es" +
c.getY(),25,40);
g.drawString("El radio es"
+ c.getRadius(),25,55);
c.setRadius(4.25);
c.setPoint(2,2);
g.drawString("La nueva
posicin y el radio de c son
",25,85);

61:
62:
63:
64: }
65:}

g.drawString
(c.toString(),40,100);
g.drawString("El rea es"
+ c.area(),25,115);

En este ejemplo se reutilizan las


definiciones de la clase Point y Circle. En
las lneas 1-35 se muestra la definicin de
la clase Cylinder y de la 36-66 son un
applet Test para probar a Cylinder. La
clase Cylinder extoiende la clase Circle
esto significa que la interfz publica con
Cylinder incluye los mtodos de Circle
adems del constructor Cylinder y los
mtodos setHeight y getHeigth area que
supedita al mtodo rea de Circle, volume
y toString de Cylinder.

1:
2: // Definicin de la clase Cylinder
3: public class Cylinder extends
Circle {
4: protected double height;
5:
6: //El constructor Cylinder llama al
constructor Circle
7: public Cylinder (double h,double
r, double a, double b)
8: {

9:
super (r,a,b);
10:
setHeight(r);
11: }
12:
13: //establecer la altura de
Cylinder
14: public void setHeight(double h)
15: {height=(h>=0? h:0);}
16:
17: //obtener la altura de Cylinder
18: public double
getHeight()
{return height;}
19:

20: //calcular el area del Cylinder


21: public double area()
22: {
23:
return 2*super.area()+
24:
2*3.14159*radius*height;
25: }
26:
27: //calcular el volmen de
Cylinder
28: public double volume(){ return
super.area()*height;}
29:

30: //convertir el Cylinder en un


String
31: public String toString()
32: {
33:
return super.toString()+";
Altura=" + height;
34: }
35:}
36:
37: //Prueba de la clase Cylinder
38: import java.awt.Graphics;
39: import java.applet.Applet;

40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:

public class Test extends Applet{


private Cylinder c;
public void init()
{
c=new Cylindere(5.7,2.5,1.2,2.3);
}
public void paint (Graphics g)
{

51:
52:
53:
54:
55:
56:
57:

g.drawString("La
coordenada X es" +
c.getX(),25,25);
g.drawString("La
coordenada Y es" +
c.getY(),25,40);
g.drawString("El radio es"
+ c.getRadius(),25,55);
g.drawString("La
altura
es" + c.getHeight(),25,70);
c.setHeight(10);
c.setRadius(4.25);

58:
59:
60:

c.setPoint(2,2);

g.drawString("La nueva
posicin, el radio y la
altura" +
61:
" de c son",25,100);
62: g.drawString(c.toString(),
40,115);
63: g.drawString("El rea es" +
c.area(),25,130);
64:
g.drawString("El volmen es"
+ c.volume(),25,145);
65: }
66: }

4.4 INTERFACES
Y PAQUETES

Una interfaz es una coleccin de


mtodos sin modificaciones reales que
indican que una clase tiene un conjunto
de comportamientos, adems de los que
la clase hereda de sus superclases.

Aunque una clase Java puede tener solo


una superclase, esa clase tambin puede
implantar
cualquier
nmero
de
interfaces. Al implantar una interfaz una
clase proporciona implantaciones de
mtodos para los nombres de mtodos
definidos por la interfaz. Si dos clases
muy diferentes implantan la misma
interfaz, ambas pueden responder a la
misma llamada del mtodo, aunque lo
que cada clase hace en respuesta a esa
llamada del mtodo puede ser muy
distinto.

Interfaces
Los mtodos abstractos son tiles
cuando
se
quiere
que
cada
implementacin de la clase parezca y
funcione igual, pero necesita que se
cree una nueva clase para utilizar los
mtodos abstractos. Las interfaces
proporcionan un mecanismo para
abstraer los mtodos a un nivel
superior.

Una interfaz contiene una coleccin


de mtodos que se implementan en
otro lugar. Los mtodos de una clase
son public, static y final.
La principal diferencia entre
interface y abstract es que un
interface proporciona un mecanismo
de encapsulacin de los protocolos de
los mtodos sin forzar al usuario a
utilizar la herencia.

Por ejemplo:
public interface VideoClip {
// comienza la reproduccin del
video
void play();
// reproduce el clip en un bucle
void bucle();
// detiene la reproduccion
void stop();
}

Las clases que quieran utilizar el


interface VideoClip utilizarn la
palabra implements y proporcionarn
el cdigo necesario para implementar
los mtodos que se han definido para
la interface:

class MiClase implements VideoClip {


void play() {
<cdigo>
}
void bucle() {
<cdigo>
}
void stop() {
<cdigo>
}

Al utilizar implementos para el interface


es como si se hiciese una accin de
copiar-y-pegar del cdigo del interface,
con lo cual no se hereda nada, solamente
se pueden usar los mtodos.
La ventaja principal del uso de interfases
es que una clase interface puede ser
implementada por cualquier nmero de
clases, permitiendo a cada clase
compartir el interfaz de programacin
sin tener que ser consciente de la
implementacin que hagan las otras
clases que implementen el interface.

Las clases e interfaces, a pesar de sus


diferentes definiciones, tienen demasiado
en comn. Las interfaces al igual que las
clases, se declaran en archivos fuente,
una interfaz en un archivo. Como las
clases se compilan en archivos .class
usando el compilador de Java. Y, en la
mayora de los casos en cualquier parte
en donde se pueda tener una clase (como
un tipo de datos para una variable, el
resultado de una conversin, etc.), puede
usar una interfaz.

Las interfaces completan y amplian el


poder de las clases, y ambas pueden ser
tratadas casi por igual. Una de las
pocas diferencias entre ellas es que no
se puede crear una instancia de una
interfaz : new solo puede crear una
instancia de una clase.

Implementacin
interfaces

uso

de

Con las interfaces podemos hacer dos


cosas: usarlas en las clases creadas por
uno mismo y definir la propia.
Para usar una interfaz, es necesario
incluir la palabra clave implements
como parte de la definicin de clase.

//java.applet.Applet es la superclase
public
class
Neko
extends
java.applet.Applet
implements Runnable{
.
}

Debido a que las interfaces no


proporcionan nada sino definiciones de
mtodos abstractos, es necesario
implementar esos mtodos en sus
propias clases, utilizando las mismas
firmas de mtodos de la interfaz. Una
vez que se incluye una interfaz se tiene
que implementar todos los mtodos en
esa interfaz, no se puede seleccionar y
elegir solo los mtodos que se necesita.

Al implementar una interfaz, se est


indicando a los usuarios de la clase que
se maneja toda la interfaz. Despus de
que la clase implementa una interfaz, las
subclases de su superclase heredarn
esos nuevos mtodos
(y pueden
anularlos o sobrecargarlos) tal como si su
superclase
los
tuviera
realmente
definidos. Si la clase se hereda de una
superclase que implementa una interfaz
dada no es necesario incluir la palabra
clave implements en su propia
definicin de clase.

Por ejemplo: para crear la nueva clase


Orange suponiendo que ya se tiene una
buena implementacin de la clase Fruit
y una interfaz, Fruitlike que representa
las frutas que estn disponibles. Se
desea que una naranja sea fruta, pero
tambin que sea un objeto esfrico que
pueda ser lanzado , girado, etc., para
expresarlo:

interface Fruitlike{
void decay();
void squish();
...
}
class Fruit implements Fruitlike{
private Color myColor;
private int daysTillRot;

interface Spherelike{
void toss();
void rotate();

}
class
Orange
extends
Fruit
implements Spherelike{
//lanzarla
(toss
())
pudiera
aplastarme (squish ()) (nicamente a
mi)
}

Aqu la clase Orange no necesita decir


implements FruitLike, debido a que el
extender Fruit, ya lo ha hecho. La
ventaja de esta estructura es que se
puede cambiar de opinin sobre la
clase que extiende Orange.(por
ejemplo, si se implementa una gran
clase Sphere), no obstante, la clase
Orange seguir comprendiendo las
mismas dos interfaces :

class
Sphere
implements
Spherelike{ // extiende a Object
private float radius;

}
class Orange extends Sphere
implements Fruitlike {
.// los usuarios de Orange no
necesitan saber nunca del cambio.

A diferencia de la jerarqua de clases


de herencia sencilla, se puede incluir
tantas interfaces como necesite en sus
propias
clases,
y
su
clase
implementar el comportamiento
combinado de todas las interfaces
incluidas. Para incluir interfaces
mltiples en una sola clase solo es
necesario separar sus nombres con
comas:

public
class
Neko
extends
java.applet.Applet
implements
Runnable,
Eatable,Soportable,Observable{
}
Al implementar interfaces mltiples
puede haber complicaciones, como es
el caso de que dos interfaces definen
el mismo mtodo, para resolver este
problema se puede hacer:

1. Si los mtodos en cada una de las


interfaces tienen firmas idnticas,
se implementa un mtodo en su
clase y esa definicin satisface a
ambas interfaces.
2. Si los mtodos tienen listas de
parmetros diferentes, se emplea la
sobrecarga de mtodos: se
implementan ambas firmas de
mtodos, y cada definicin
satisface su respectiva definicin
de interfaz.

3. Si los mtodos tienen la misma lista de


parmetros pero difieren en el tipo de
devolucin, no se puede crear un mtodo
que satisfaga ambos (la sobrecarga de
mtodos se asocia por listas de
parmetros, no por tipo de devolucin.
En este caso tratar de compilar una clase
que implemente ambas interfaces
producir un error de compilacin.
Incurrir en este problema sugiere que sus
interfaces tienen algunas fallas de diseo
que pudiera ser necesario reexaminar.

Creacin y extencin de interfaces.


Las interfaces se asemejan mucho a las
clases; se declaran en forma muy similar
y pueden organizarse dentro de una
jerarqua , aunque hay reglas que hay
que seguirse para declarar interfaces.
Para crear una nueva interfaz se puede
declarar como sigue:
public interface Growable {

Es lo mismo que la definicin de clase,


con la palabra interface remplazando la
palabra class. Dentro de la definicin de
la interfaz se tienen mtodos y
constantes. Las definiciones dentro de la
interfaz son mtodos public y abstract,
se pueden declarar como tales en forma
explcita, o se convertirn en mtodos
public y abstract si no se incluyen esos
modificadores. No se puede declarar
dentro de la interfaz un mtodo que sea
private o protect.

Las interfaces tambin pueden tener


variables, pero esas variables deben ser
declaradas public, static y final
(convirtindolas en constantes).
Las interfaces deben de tener
proteccin ya sea pblica o de paquete ,
al igual que las clases. Sin embargo las
interfaces sin el modificador public no
convierten sus mtodos de manera
automtica a public y abstract, ni sus
constantes a public.

Una interfaz no pblica tiene tambin


mtodos y constantes no pblicos que
solo pueden ser usados por clases y
otras interfaces en el mismo paquete.
Las interfaces, como las clases,
pueden pertenecer a un paquete
agregando el enunciado package a la
primera lnea del archivo de clase. Las
interfaces pueden adems importar
otras interfaces en el mismo paquete.

Mtodos dentro de las interfaces


Debido a que se usa el nombre de una
interfaz en cualquier parte en que pueda
utilizarse el nombre de una clase, al
definir que los parmetros del mtodo
sean del tipo interfaz, se puede crear
parmetros genricos que se apliquen a
cualquier clase que pudiera usar esta
interfaz.

Por ejemplo con la interfaz Fruitlike,


la
cual
define
mtodos
(sin
argumentos) para decay() y squish().
Podra tambin haber un mtodo para
germinatedSeed(), el cual tiene un
argumento: la propia fruta. El tipo de
argumento no puede ser simplemente
Fruit, ya pudiera haber una clase que
fuera Fruitlike (es decir, implementa la
interface Fruitlike) sin ser en realidad
una fruta.

La solucin es declarar el argumento en


la interfaz simplemente como Fruitlike:
public interface Fruitlike{
public abstract germinate(Fruitlike self)
{

}
}

Entonces para una implementacin real


de este mtodo en una clase, puede
tomar el argumento genrico Fruitlike y
convertirlo al objeto adecuado:
public class Orange extends Fruit {
public germinate (Fruitlike self){
Orange theOrange = (Orange) self;

}
}

Extencin de las interfaces


Al igual que las clases pueden organizarse
en una jerarqua. Cuando una interfaz se
hereda de otra, esa subinterfaz adquiere
todas las definiciones de mtodos y
constantes que defini su superinterfaz.
Para acceder una interfaz, se usa la palabra
clave extends, tal como lo hacen en una
definicin de clase.:
public interface Fruitlike extends Foodlike{

A diferencia de las clases, la jerarqua de


interfaces no tiene el equivalente de la
clase object; esta jerarqua no tiene raz en
ningn punto. Las interfaces pueden existir
de manera independiente, o heredarse de
otra interfaz. Adems la jerarqua de
herencia es de herencia mltiple, as que
una sola interfaz puede extender tantas
clases como necesite (separadas por comas
en la parte extendida de la definicin), y la
nueva interfaz contendr una combinacin
de todos los mtodos y constantes de su
madre

A continuacin se muestra una interface


denominada BusyInterface que hereda
de muchas otras interfaces:
public interface BusyInterface extends
Runnable,
Growable,
Fruitlike,
Observable{

En interfaces de herencia mltiple, las


reglas para manejar conflictos de
nombres de mtodos son las mismas
que para las clases que usan interfaces
mltiples; los mtodos que difieren
solo en el tipo de devolucin darn
como resultado un error de
compilacin.

Paquetes
Los paquetes en Java son una manera de
agrupar clases e interfaces relacionadas.
Permiten que grupos modulares de clases
estn disponibles slo cuando se
necesitan,
y
eliminan
conflictos
potenciales entre los nombres de clase, en
diferentes grupos de clase.
La palabra clave package permite
agrupar clases e interfaces. Los nombres
de los paquetes son palabras separadas
por puntos y se almacenan en directorios
que coinciden con esos nombres.

Import
Los paquetes de clases se cargan con la
palabra clave import, especificando el
nombre del paquete como ruta y nombre
de clase (es lo mismo que #include de
C/C++). Se pueden cargar varias clases
utilizando un asterisco.
import java.Date;
import java.awt.*;

Si un fichero fuente Java no contiene


ningn package, se coloca en el paquete
por defecto sin nombre. Es decir, en el
mismo directorio que el fichero fuente,
y la clase puede ser cargada con la
sentencia import:
import MiClase;

Paquetes de Java
El lenguaje Java proporciona una serie
de paquetes que incluyen ventanas,
utilidades,
un
sistema
de
entrada/salida general, herramientas y
comunicaciones. En la versin actual
del JDK, los paquetes Java que se
incluyen son:

java.applet
Este paquete contiene clases diseadas
para usar con applets. Hay una clase
Applet y tres interfaces: AppletContext,
AppletStub y AudioClip.
java.awt
El paquete Abstract Windowing Toolkit
(awt) contiene clases para generar widgets
y componentes GUI (Interfaz Grfico de
Usuario). Incluye las clases Button,
Checkbox, Choice, Component, Graphics,
Menu, Panel, TextArea y TextField.

java.io
El paquete de entrada/salida contiene
las clases de acceso a ficheros:
FileInputStream y FileOutputStream.
java.lang
Este paquete incluye las clases del
lenguaje Java propiamente dicho:
Object, Thread, Exception, System,
Integer, Float, Math, String, etc.

java.net
Este paquete da soporte a las conexiones
del protocolo TCP/IP y, adems, incluye
las clases Socket, URL y
URLConnection.
java.util
Este paquete es una miscelnea de clases
tiles
para
muchas
cosas
en
programacin. Se incluyen, entre otras,
Date (fecha), Dictionary (diccionario),
Random (nmeros aleatorios) y Stack
(pila FIFO).

This y super
Al acceder a variables de instancia de
una clase, la palabra clave this hace
referencia a los miembros de la propia
clase. Puede aadir otro constructor de
la forma siguiente:
public class MiClase {
int i;
public MiClase() {
i = 10;
}

// Este constructor establece el valor


de i
public MiClase( int valor ) {
this.i = valor; // i = valor
}
public void Suma_a_i( int j ) {
i = i + j;
}
}

Aqu this.i se refiere al entero i en la clase


MiClase.
Si se necesita llamar al mtodo padre dentro
de una clase que ha reemplazado ese mtodo,
se puede hacer referencia al mtodo padre con
la palabra clave super:
import MiClase;
public class MiNuevaClase extends
MiClase {
public void Suma_a_i( int j ) {
i = i + ( j/2 );
super.Suma_a_i( j );
}
}

En el siguiente cdigo, el constructor


establecer el valor de i a 10, despus
lo cambiar a 15 y finalmente el
mtodo Suma_a_i() de la clase padre
(MiClase) lo dejar en 25:
MiNuevaClase mnc;
mnc = new MiNuevaClase();
mnc.Suma_a_i( 10 );

CAPITULO V
ARREGLOS CONDICIONALES

5.1 ARREGLOS

Los arreglos son una forma de


organizar una lista de elementos. Cada
especio de arreglo guarda un elemento
individual y usted puede colocar los
elementos o cambiar el contenido de
esos espacios segn lo necesite.

Los arreglos pueden tener cualquier


tipo de valor de elemento, pero no
podr almacenar diferentes tipos en un
solo arreglo.

Para crear un arreglo Java siga los


siguientes pasos:
Declare una variable para guardar
el arreglo.
Cree un nuevo objeto del arreglo y
asgnelo a la variable de arreglo.
Guarde lo que desea en ese arreglo.

5.1.1 DECLARACIONES
DE VARIABLES DE
TIPO ARREGLO

El primer paso para crear un arreglo es


crear un variable que guarde el arreglo,
justo como lo hara con cualquier otra
variable. Las variables de arreglo
indican el tipo de objeto que el arreglo
contendr (as como lo que hace para
cualquier otro elemento y el nombre del
arreglo, seguido por corchetes vacos
([ ]). Los siguientes son enunciados con
de variables de arreglos comunes:

String difficultWords [];


Point hits [];
int temps[];

Tambin puede definir la variable del


arreglo colocando los corchetes despus
del tipo, en lugar de enseguida de la
variable.:

String[] difficultWords;
Point[] hits;
int[] temps;
Estos dos mtodos son correctos, pero
con frecuencia el segundo es ms
legible.
Cmo crear objetos de arreglo

El segundo paso es crear un objeto de


arreglo y asignarlo a esa variable.
Existen dos formas de hacerlo:

Usar new.
Inicializar de manera directa el
contenido de ese arreglo.

El primer paso implica el uso del


operador new para crear la nueva
instancia de un arreglo:
String[] names = new String[10];

Cuando crea objetos de arreglos mediante


el uso de new, todas sus casillas se
inicializan por usted (0 para arreglos
numricos, False para bolanos, /0 para
arreglos de caracteres y null para objetos).
Tambin puede crear e inicializar arreglos al
mismo tiempo; en lugar de utilizar new para
crear un objeto de arreglo distinto, encierre
los elementos del arreglo dentro de las
llaves, separados por comas:
String [] chiles =
anaheim, serrano};

{jalapeo,

Cada uno de los elementos dentro de la


llaves debe ser el mismo tipo y debe
coincidir con el tipo de la variable que
contiene ese arreglo.

5.1.2 ACCESO A LOS


ELEMENTOS DEL
ARREGLO

Una vez que tenga el arreglo con


valores iniciales, puede probar y
cambiar lo valores de cada casilla de
ese arreglo. Para obtener un valor
almacenado dentro de un arreglo, utilice
la expresin de arreglo subscript:

myArray [subscript];

Una vez que tenga un arreglo con


valores iniciales, puede probar
y
cambiar los valores de cada casilla de
ese arreglo. Puede obtener un valor
almacenado dentro de un arreglo, utilice
la expresin de arreglo subscript:

myArray[subscript];

La parte myArray de esta expresin es


una variable que contiene un objeto
de arreglo, aunque puede ser una
expresin que resulta en un arreglo. La
expresin subscript especifica la
casilla a consultar dentro del arreglo.
Los subndices de arreglo inicializan
con 0, como lo hacen en C y C++

5.1.3 CMO ACCEDER Y


CAMBIAR LOS
ELEMENTOS DE UN
ARREGLO

Para asignar un valor de un elemento a


una casilla del arreglo en particular,
ponga un enunciado de asignacin
despus de la expresin de acceso al
arreglo:
myArray[1] = 15:
sentence[0] = e;
sentence[10] = sentence[0];

Los elementos de un arreglo se pueden


inicializar en la declaracin del arreglo
continuando la declaracin con un signo
igual y una lista separada por comas (y
encerrada en llaves) de inicializadores.
En este caso, el tamao del arreglo queda
determinado por el nmero de elementos
de la lista de inicializadores. Por ejemplo
el enunciado:
Int n[]= {1, 2, 3, 4, 5 };
Crea un arreglo de cinco elementos.

Un aspecto importante a tener en cuenta


es que un arreglo de objetos en Java
consiste en un arreglo de referencias a
dichos objetos. Cuando asigna un valor a
una casilla en un arreglo, crea una
referencia a ese objeto, al igual que lo
hace para una variable comn. En el
momento en que desplace a los valores
dentro de los arreglos solo reasigna la
referencia; no copia el valor de una
casilla a otra. Los arreglos como ints o
flotas s copian los valores de una casilla

Los arreglos de referencia a objetos, al


contrario de los objetos mismos, son
tiles en extremo, ya que esto significa
que pueden tener referencias a mltiples
o a los mismos objetos tanto dentro
como fuera de los arreglos.

5.1.4

EJEMPLOS

1) El programa siguiente utiliza el


operador new para asignar
dinmicamente
espacio
de
almacenamiento a un arreglo de 10
elementos que inicialmente son cero,
y luego imprime el arreglo en forma
tabular.

Los primeros dos enunciados del mtodo


paint exhibe las cabeceras de columna
para las columnas que se imprimen en la
estructura for. La variable yPosition
sirve para determinar la posicin vertical
en la que el mtodo drawString
dibujar en la applet. Se utiliza el
mtodo String.valueOf para convertir
cada entero en una cadena que se pueda
exhibir en el applet. n.longth es la
estructura for que determina la longitud
del arreglo.

import java.awt.Graphics;
import java.applet.Applet;
public class Class1 extends Applet
{
int n[ ];
public void init()
{
n=new int[10];
}

public void paint (Graphics g)


{
int yPosition=25;
g.drawString("Elemento",25,yPosition);
g.drawString("Valor",1000,yPosition);
for (int i=0; i < n.length; i++)
{
yPosition +=15;
g.drawString(String.valueOf(i),25,yPosition)
;
g.drawString(String.valueOf(n[i]),100,yPosit
ion); }
}

2) El programa siguiente inicializa un


arreglo de enteros con diez valores
e imprime el arreglo en formato
tabular.
import java.awt.Graphics;
import java.applet.Applet;
public class Class1 extends Applet
{
int n[]={32, 27, 64, 18, 95, 14, 90,
70, 60, 37 };

public void paint (Graphics g)


{
int yPosition=25;
g.drawString("Elemento",25,yPosition)
g.drawString("Valor",100,yPosition);
for (int i=0; i < n.length; i++)
{
yPosition +=15;
g.drawString(String.valueOf(i),25,y
Position);
g.drawString(String.valueOf(n[i]),10
0,yPosition);
}
}
}

3)

El programa siguiente inicializa


los elementos de un arreglo s de
diez elementos con los enteros 2,
4, 6, ..., 20 e imprime el arreglo
en formato tabular. Estos nmeros
se generan multiplicando cada
valor sucesivo del contador del
ciclo por 2 y sumndole 2.
La instruccin
final int arraySize = 10;

utiliza el calificador final para declarar


una variable constante arraySize (tamao
de arreglo) cuyo valor es 10. Las
variables constantes se deben inicializar
con una expresin constante cuando se
declaran y no se pueden modificar
despus. Si intenta modificar una
variable final desps de haberla
declarado, el compilador producir el
mensaje de error:
Cant assign a value to a final variable

import java.awt.Graphics;
import java.applet.Applet;
public class Class1 extends Applet
{
final int arraySize = 10;
int s[ ];
public void init ( )
{
s = new int [arraySize];

for (int i=0; i < s.length; i++)


s[ i] = 2+2 * i;
}
public void paint (Graphics g)
{
int yPosition=25;
g.drawString("Elemento",25,yPosition);
g.drawString("Valor",100,yPosition);
for (int i=0; i < s.length; i++)
{

yPosition +=15;
g.drawString(String.valueOf(i),25,y
Position);
g.drawString(String.valueOf(s[i]),10
0,yPosition);
}
}
}

4) El programa siguiente obtiene la


sumatoria de los valores contenidos en
el arreglo de 10 elementos enteros a. El
enunciado del cuerpo del ciclo for se
encarga de obtener el total.
import java.awt.Graphics;
import java.applet.Applet;
public class Class1 extends Applet
{
int a[] = {1,2,3,4,5,6,7,8,9,10};
int total;

public void init ( )


{
total = 0;

}
}

for (int i=0; i < a.length; i++)


total += a[i];
public void paint (Graphics g)
{
g.drawString("Total de elementos
del arreglo: " + total,25,25);

5) El programa siguiente utiliza


arreglos para resumir los datos
obtenidos
de
una
encuesta.
Considere
el
enunciado
del
problema:
Se pidio a 40 estudiantes calificar la
calidad de la comida que se sirve en
la cafetera para estudiantes en una
escala del 1 al 10. Colquese las
respuestas en un arreglo de enteros y
resuma los resultados del sondeo:

import java.awt.Graphics;
import java.applet.Applet;
public class Class1 extends Applet
{
int responses[] = {1,2,3,4,5,6,7,8,9,10,
1,6,3,8,6,10,3,8,2,7,
6,5,7,6,8,6,7,5,6,6,
5,6,7,5,6,4,8,6,8,10};
int frecuency[];

public void init ( )


{
frecuency = new int [11];
for (int answer = 0;answer <
responses.length; answer++)
++frecuency[ responses [ answer ]];
}
public void paint (Graphics g)
{
int yPosition = 25;

g.drawString("Calificacin",25,
yPosition);
g.drawString("Frecuencia",100,
yPosition);
for ( int rating = 1; rating < frecuency
.length; rating++) {
yPosition +=15;
g.drawString(String.valueOf( rating), 25,
yPosition);
g.drawString(String.valueOf(frecuency
[rating]),100, yPosition);
}

6) El programa siguiente lee nmeros


de un arreglo y grafca la
informacin en forma de grficas de
barras o histograma: se imprime cada
nmero y junto
a l se imprime
una barra formada
por la misma
cantidad de
asteriscos. El ciclo for
anidado se
encarga de dibujar las
barras.
import java.awt.Graphics;
import java.applet.Applet;

public class Class1 extends Applet


{
int
n[]
{ 19,3,15,7,11,9,13,5,17,1};

public void paint (Graphics g)


{
int yPosition = 25;
int xPosition;
g.drawString("Elemento",25,
yPosition);

g.drawString("Valor",100,
yPosition);
g.drawString("Histograma",175,
yPosition);
for ( int i = 0; i< n.length; i++) {
yPosition +=15;
g.drawString(String.valueOf(i), 25,
yPosition);
g.drawString(String.valueOf(n[i]),1
00, yPosition);

xPosition = 175;
for (int j = 1;j <= n[i];j++){
g.drawString("*",xPosition , yPosition);
xPosition += 7;
}
}
}
}

Dos formas de pasar argumentos a los


mtodos (o funciones) en muchos
lenguajes de programacin son llamar
por valor o llamar por referencia.
Normalmente el programador especifica
la forma
en que se pasar cada
argumento. Cuando un argumneto se
pasa por valor, se crea una copia del
valor del argumento y se pasa al mtodo
invocado.

Con la llamada por referncia, el


invocador confiere al mtodo invocado
la capacidad de acceder directamente
los datos del invocador y modificar
dichos datos si el mtodo invocado lo
desea. La llamada por referncia puede
mejorar el rendimiento porque elimina
el gasto extra de copiar grandes
cantidades de datos, pero tambin
puede debilitar la seguridad porque el
mtodo invocado tiene acceso a los
datos del invocador.

Java no permite escoger cmo se van a


pasar los argumentos, las variables de
tipos de datos primitivos siempre se
pasan por valor y los objetos siempre se
pasan por referencia.

7) El programa siguiente demuestra la


diferencia entre pasar un arreglo
completo y pasar un elemento de
arreglo. Lo que hace el programa es
imprimir los cinco elementos del
arreglo de enteros a. Luego se pasa
a al mtodo modifyArray donde
cada uno de los elementos de a se
multiplica por dos. Despus a se
vuelve a imprimir en main.
ModifyArray
modifica
los
elementos de a.

Ahora el programa imprime el valor de


a [3] y lo pasa al mtodo
modifyElement, el cual multiplica su
argumento por 2. Se observa que
cuando a[ 3] se vuelve a imprimir en
main, no ha sufrido modificacin
alguna porque los elementos de arreglo
individuales de tipos de datos
primitivos se pasan por valor.

import java.awt.Graphics;
import java.applet.Applet;
public class Class1 extends Applet
{ int a[] = { 0,1,2,3,4 };
public void paint (Graphics g)
{
int yPosition = 25,xPosition= 25;
g.drawString("Efectos de pasar todo
el arreglo por
referencia:",xPosition,yPosition);

yPosition += 15;
g.drawString("Los valores del arreglo
original son:",xPosition, yPosition);
yPosition += 15;
xPosition += 15;
for ( int i = 0; i< a.length; i++) {
g.drawString(String.valueOf(a[i]),
xPosition, yPosition);
xPosition +=15;
}

xPosition = 25;
yPosition += 30;
modifyArray (a);
g.drawString("Los valores del
arreglo modificado
son:",xPosition,
yPosition);
xPosition += 15;
yPosition += 15;
for ( int i = 0; i< a.length; i++) {
g.drawString(String.valueOf(a[i]),
xPosition, yPosition);
xPosition +=15;
}

xPosition = 25;
yPosition += 30;
g.drawString("Efectos de pasar un
elemento de un arreglo por
valor:",xPosition, yPosition);
yPosition += 15;
g.drawString( "a[3] antes de
modifyElement: " + a[3],xPosition,
yPosition);
yPosition += 15;
modifyElement(a[3]);

g.drawString( "a[3] despues de


modifyElement:
"
+
a[3],xPosition, yPosition);
}
public void modifyArray ( int b[])
{
for (int j = 0;j <= b.length;j++)
b[j]*=2;
}
public void modifyElement (int e)
{
e*=2;
}
}

5.1.5 ARREGLOS
DIMENSIONALES

Es frecuente utilizar arreglos con dos


subndices para representar tablas de
valores, que consisten en informacin
dispuestas en filasa y columnas. Para
identificar el elemento en particular de la
tabla debemos especificar los dos
subndices. Las tablas o arreglos que
requieren dos subndices para identificar
un elemento en particular se denominan
arreglos con doble subndice . Cabe sealar
que los arreglos con mltiples subndices
pueden tener ms de dos subndices.

Java no soporta los arreglos


multidimensionales o de multiples
subndices, sin embargo puede declarar
y crear un arreglo de arreglos ( y esos
arreglos pueden contener arreglos, y as
en lo sucesivo, en tantas dimensiones
como lo necesite), y tener acceso a l
como lo hara en un arreglo
multidimensional:
int coords[] [] = new int[12][12];
coords[0][0] = 1;
coords[0][1] = 2;

1)

El siguiente programa declara dos


arreglos
y
muestra
la
inicializacin
de arreglos con
doble subndice en
declaraciones:
import java.awt.Graphics;
import java.applet.Applet;
public class Class1 extends Applet
{ int array1[][]= {{ 1,2,3}, { 4,5,6}};
int array2[][]= {{ 1,2}, {4}};

public void paint (Graphics g)


{
g.drawString("Los valores de array1
por fila son:",25,25);
printArray( array1,g,40);
g.drawString("Los valores de
array2 por fila son:",25,70);
printArray( array2,g,85);
}
public void printArray ( int a[][],
Graphics g, int y)
{

int x=25;
for (int i = 0; i<= a.length;i++){
for (int j = 0; j< a[i].length;j++){
g.drawString(String.valueOf(a[i][j]),x,y);
x += 15;}
x= 25;
y+=15;
}
}
}

2) El siguiente programa muestra las


manipulaciones que se pueden hacer
los arreglos:
import java.awt.Graphics;
import java.applet.Applet;
public class Class1 extends Applet
{ int grades[][]= {{77,68,86,73},
{96,87,89,81},
{70,90,86,81}};

int students, exams;


int xPosition, yPosition;
public void init()
{
students =grades.lenght;
exams = grades [0].length;
}
public void paint (Graphics g)
{
xPosition=25;
yPosition=25;

g.drawString("El arreglo es:",xPosition,


yPosition);
yPosition +=15;
printArray(g);
xPosition =25;
yPosition +=30;
g.drawString("Calificacin ms baja:",
xPosition, yPosition);
int min = minimum();
g.drawString(String.valueOf(min),
xPosition + 85, yPosition);

yPosition+=15;
g.drawString("Calificacin ms alta:",
xPosition, yPosition);
int max = maximum();
g.drawString(String.valueOf(max),
xPosition + 85, yPosition);
yPosition+=15;
for (int i = 0; i<=students;i++){
g.drawString("El promedio del
estudiante" +i+ "es",
25,yPosition);
double ave=average(grades[i]);

g.drawString(String.valueOf(ave),165,yPo
sition);
yPosition+=15;
}
}
public int minimum ()
{
int lowGrade= 100;
for (int i=0; i< students; i++)

if (grades[i][j]
<lowGrade)lowGrade=grades [i][j];
return lowGrade;
}

public int maximum ()


{
int highGrade= 0;
for (int i=0; i< students; i++)
for (int j=0; j< exams;j++)

if (grades[i][j] >
highGrade)highGrade=grades [i][j];
return highGrade;
}
public double average (int
setOfGrades[])
{
int total=0;
for (int i = 0; i<
setOfGrades.lenght;i++)

total+= setOfGrades[i];
return (double) total/setOfGrades[i];
}
public void printArray ( Graphics g)
{
xPosition = 80;
for (int i = 0;
i<exams;i++){

g.drawString("[" + i
+"]",xPosition,yPosition);
xPosition += 30;}
for (int i = 0; i<students;i++){
xPosition = 25;
yPosition += 15;
g.drawString("Grades["+i+"]",xPosition,
yPosition);
xPosition = 80;
for (int j = 0; j<exams;j++){

g.drawString(String.valueOf(grades[i][j]),
xPosition,yPosition);
xPosition += 30;}
}
}
}
}

CAPTULO VI
GRFICOS Y FUENTES
DE COLOR

6.1 CLASE GRAPHICS

Con las capacidades de los grficos de


Java puede dibujar lneas, figuras,
caracteres e imgenes en la pantalla
dentro de su applet. La mayora de estas
operaciones en Java consiste en mtodos
definidos en la clase Graphics. No tiene
que crear una instancia de sta para
dibujar algo en su applet. Al dibujar en
un objeto dibujar en su applet y sus
resultados aparecern en pantalla.

La clase Graphics es parte del paquete


Java.awt, as que si su applet hace un
dibujo, asegrese de incluir esa clase al
principio de su archivo Java:
import java.awt.Graphics;
public class MyClass
java.applet. Applet {

extends

6.1.1 EL SISTEMA DE
COORDENADAS
GRFICAS

Para dibujar un objeto en la pantalla,


llame a uno de los mtodos de dibujo
disponibles en la clase Graphics. Todos
los mtodos de dibujo tienen
argumentos que representan puntos
finales, esquinas o lugares de inicio del
objeto con valores en el sistema de
coordenadas del applet; por ejemplo,
una lnea inicia en el punto 10,10 y
termina en el punto 20,20.

El sistema de coordenadas de Java tiene


el origen (0,0) en la esquina superior
izquierda. Los valores positivos de x
estn a la derecha y los valores positivos
y estn hacia abajo. Todos los valores de
pixeles son enteros; no existen pixeles
parciales o fraccionarios. La siguiente
figura muestra cmo podra dibujar un
cuadrado comn al utilizar este sistema
de coordenadas.

0,0

+x

El sistema de coordenadas
grficas de Java

+y

El sistema de coordenadas Java es


diferente a muchos programas de dibujo
y arreglos que tienen su propia x y y en la
esquina inferior izquierda.

6.1.2 CMO DIBUJAR


RELLENAR

La claseGgraphics ofrece una serie de


primitivas
de
grfico
sencillos
integrados para dibujar, incluidos lneas,
rectngulos, polgonos, valos y arcos.

6.1.2.1 LNEAS

Para dibujar lneas rectas, use el


mtodo drawLine( ). Este mtodo toma
cuatro argumentos : las coordenadas x
y y del punto de inicio y del punto
final.
Dibujo de lneas

public void paint(Graphics g) {


g.drawLine(25,25,75,75);
}

La siguiente figura muestra el resultado


de este fragmento de cdigo:

Dibujo de lneas

6.1.2.2 RECTNGULOS

Las primitivas de grficos de Java


ofrecen no una, sino tres clases de
rectngulos:
Rectngulos comunes.
Rectngulos redondeados; son
rectngulos con esquinas redondas.
Rectngulos tridimensionales
dibujados con un borde sombreado.

Para cada uno de estos rectngulos


tiene dos mtodos a elegir: uno que lo
dibuja en forma de contorno y otro que
lo dibuja en color.
Para dibujar un rectngulo comn, use
los mtodos drawRect( ) o fillRect( ).
Ambos toman cuatro argumentos: las
coordenadas x y y de la esquina
superior izquierda del rectngulo, y el
ancho y altura del rectngulo que se va
a dibujar.

Por ejemplo, el siguiente mtodo paint( )


dibuja dos cuadrados el izquierdo es uno
de contorno y el derecho es uno de color.
public void paint(Graphics g) {
g.drawRect(20,20,60,60);
g.fillRect(120,20,60,60);
}

As quedan dibujados:

Los
rectngulos
redondeados
son
rectngulos con bordes redondos. Los
mtodos
drawRoundRect(
)
y
FillRoundRect( ) para dibujar rectngulos
redondeados, son similares a los rectngulos
ordinarios, pero con la diferencia de que
tienen dos argumentos extra para la anchura
y altura del ngulo de las esquinas. Estos dos
argumentos determinan que tan lejos de los
lmites del rectngulo empezar el arco para
la esquina; el primero para el ngulo en el
plano horizontal, el segundo para el plano
vertical.

Mientras ms grandes sean los valores


de la altura y anchura del ngulo, el
rectngulo en general ser ms redondo.

Aqu est un mtodo paint( ) que dibuja


dos rectngulos redondeados: uno como
contorno con una esquina redondeada de
10 pixeles cuadrados; el otro, relleno,
con la esquina redondeada de 20 pixeles
cuadrados.
public void paint(Graphics g) {
g.drawRoundRect(20,20,60,60,10,10);
g.fillRoundRect(120,20,60,60,20,20);
}

Rectngulos
redondeados

Por ltimo existen rectngulos


tridimensionales. Estos no son en
realidad 3D , en su lugar tienen un
efecto de sombra que los hace parecer
elevados o hundidos de la superficie
del
applet.
Los
rectngulos
tridimensionales
tienen
cuatro
argumentos que corresponden a la x y
y de la posicin de inicio as como a la
altura y la anchura del rectngulo.

El quinto argumento es un booleano


que indica si el efecto 3D es para
elevar el rectngulo (true) o hundirlo
(false).
Como
con
los
otros
rectngulos, tambin existen distintos
mtodos para dibujar y rellenar:
draw3DRect( ) y fill3DRect( ).Aqu
est el cdigo para producir dos de
ellos, el izquierdo hundido y el derecho
elevado.

import java.awt.Graphics;
import java.applet.Applet;
public class Class1 extends Applet{
public void paint(Graphics g) {
g.draw3DRect(20,20,60,60,true);
g.fill3DRect(120,20,60,60, false);
}
Rectngulos
tridimensionales

6.1.2.3 POLGONOS

Los polgonos son figuras con un


nmero ilimitado de lados. Para dibujar
uno necesita una serie de coordenadas x
y y; el mtodo de dibujo empieza en una
coordenada, dibuja una lnea a la
segunda, una a la tercera, y as de forma
sucesiva.
Como con los rectngulos, puede dibujar
un polgono de contorno o relleno (Con
los mtodos drawPolygon ( ) y
fillPolygon( ), respectivamente).

Tambin tiene la opcin para escoger cmo


quiere indicar la lista de coordenadas.
Como arreglos de coordenadas x y y o
como una instancia de la clase Polygon.
Con la primera opcin, estos mtodos
toman tres argumentos:
1. Un arreglo de enteros que representan
las coordenadas en x.
2. Un arreglo de enteros que representan
las coordenadas en y.
3. Un entero para el nmero total de puntos.

Los arreglos x y y deben por supuesto,


tener el mismo nmero de elementos.
A continuacin se muestra un ejemplo
para dibujar el contorno de un polgono
utilizando este mtodo:
public void paint(Graphics g) {
int
exes[
]
{39,94,97,142,53,58,26};
int
whys[
]
{33,74,36,70,108,80,106};

=
=

int pts = exes.length;


g.drawPolygon(exes,whys,pts);
}

Observe que Java cierra el polgono en


forma automtica. Si desea dejar el
contorno del polgono incompleto, tendr
que utilizar el mtodo drawPolyline( ).
Nota: el hecho de que Java cierre
automticamente el polgono representa
un cambio respecto a las versiones
anteriores. En la versin 1.02 deba
repetir el punto de inicio para indicarle al
mtodo drawpolygon( ) que cerrara el
polgono.

El mtodo fiilPolygon( ) si lo cerraba de


manera
automtica.
El
mtodo
drawPolyline( ) se introdujo en la versin
1.1.
La segunda forma de llamar
a
drawPolygon( ) y fillPolygon( ) es
utilizando un objeto Polygon para
almacenar los puntos individuales que los
forman.. La clase Polygon es til si intenta
agregar puntos al polgono o si va a
construir sobre la marcha. Al utilizar esta
clase puede tratar al polgono como un
objeto en lugar de trabajar con arreglos

Para crear un objeto Polygon, tiene


dos opciones, la primera es crear un
polgono vaco:
Polygon poly = new Polygon ( );
La segunda es crear un polgono a
partir de un conjunto de arreglos de
enteros, como por ejemplo el anterior:

public void paint(Graphics g) {


int exes[ ] =
{39,94,97,142,53,58,26};
int whys[ ] =
{33,74,36,70,108,80,106};
int pts = exes,length;
g.drawPolygon(exes,whys,pts);
}

Una vez que tenga un objeto Polygon,


puede agregarle puntos al polgono
conforme
lo
requiera:
poly.addPoint(20,35);
Posteriormente para dibujar el polgono,
solo utilice el mtodo polgono como
argumento de los mtodos drawPolygon o
fillPolygon( ). Aqu est el ejemplo
anterior reescrito esta vez con un objeto
Polygon. Tambin lo rellenar en lugar de
dibujar solo su contorno.

import java.awt.Graphics;
import java.awt.Polygon;
public class MyPoly2 extends java.applet.
Applet{
public void paint(Graphics g) {
int exes[ ] = {39,94,97,142,53,58,26};
int whys[ ] = {33,74,36,70,108,80,106};
int pts = exes,length;
Polygon poly = new Polygon (exes,
whys,pts);
g.fillPolygon(poly);
}
}

El mtodo drawPolyline( ), es cual es utilizado


para dibujar polgonos abiertos, trabaja
exactamente igual que el primer ejemplo de
dibujo de polgono. Usted especifica dos
arreglos de enteros que contienen las
coordenadas x y y para cada punto y otro
entero especifica el nmero de puntos.El
siguiente ejemplo dibuja un polgono abierto:

import java.awt.Graphics;
public
class
MyPoly3
extends
java.applet. Applet{
public void paint(Graphics g) {
int exes[ ] = {39,94,97,142,53,58,26};
int whys[ ] = {33,74,36,70,108,80,106};
int pts = exes,length;
g.drawPolyline(exes,whys,pts);
}
}

6.1.2.4 VALOS

Utilice valos para dibujar crculos o


elipses. Los valos son como los
rectngulos pero con las esquinas
demasiado redondeadas. Se dibujan
utilizando cuatro argumentos: la w y y
de la esquina superior, el largo y ancho
del valo. Observe que debido a que
est dibujando un valo, el punto inicial
est a cierta distancia del contorno real a
la izquierda y hacia arriba del valo. Si
se lo imagina como un rectngulo puede
ser ms fcil.

Como con las dems operaciones de


dibujo, el mtodo drawOval( ) dibuja
el contorno de un valo y el mtodo
fillOval( )dibuja un valo relleno.
El siguiente ejemplo dibuja dos
valos: un crculo y un elipse:
public void paint(Graphics g) {
g.drawOval(20,20,60,60);
g.fillOval(120,20,100,60);
}

6.1.2.5 ARCOS

De las operaciones de dibujo, los arcos


son los ms complejos de construir. Un
arco es una parte de un valo; la forma
ms fcil de pensar en un arco es como
una seccin de un valo completo. La
siguiente figura muestra algunos arcos:

El mtodo drawArc( ) toma seis


argumentos: la esquina inicial, el largo y
ancho, el ngulo con el que se inicia el
arco y los grados para dibujarlos antes
de terminar. Tiene el mtodo drawArc( )
para dibujar el contorno del arco y
fillArc( ) para rellenarlo. Los arcos
rellenos se dibujan como si fueran una
seccin del pastel; en lugar de unir los
dos extremos directamente , se unen en
el centro del crculo como si fueran una
rebanada de pastel.

Un punto importante para comprender la


estructura de los arcos es que en realidad
se dibuja un valo y luego slo se traza
una seccin de l. La esquina inicial, el
largo y el ancho no son los elementos
actuales del arco que se dibujan en la
pantalla, son los elementos de una elipse
completa de la cual solo se dibuja una
seccin.
Estos
primeros
puntos
determinan el tamao y la forma del arco;
los ltimos argumentos (para los grados)
determinan los puntos de inicio y fin.

Empecemos con un arco sencillo, una


figura en forma de C en un crculo,
como se muestra a continuacin:

Arcos sobre crculos

Para construir el mtodo para dibujar


este arco, primero debe pensar en l
como un crculo completo. Despus
encontrar las coordenadas de x y y
adems del largo y ancho del crculo.
Estos cuatro valores son los primeros
cuatro argumentos de los mtodos
drawArc( ) o fillArc( ). La siguiente
figura muestra cmo obtener esos
valores del arco:

100

100
Construccin de un arco
circular

Para obtener los dos ltimos


argumentos, piense en grados alrededor
del crculo, en sentido opuesto a las
manecillas del reloj. El grado 0 est a
las 3:00 en punto, 90o a las 12:00 hrs,
etc. El inicio del arco es el valor del
grado del punto de inicio. En este
ejemplo, el punto inicial es la parte
superior de la C a 90o , as que 90o es el
quinto argumento.

El sexto y ltimo argumento es otro


valor en grados que indica qu tanto
recorrer alrededor del crculo y la
direccin a seguir . En este caso como
va a la mitad del crculo recorrer 180o.
Para darse cuenta de cmo funcionan
las coordenadas en Java vea la
siguiente ilustracin:

90o
90o
180o

90o
180

270o

Arco sobre
crculo

Aqu est el cdigo para este ejemplo;


dibujar el contorno de una C y una C
rellena a su derecha, como se muestra en
la figura:
public void paint(Graphics g) {
g.drawArc(20,20,60,60,90,180);
g.fillArcl(120,20,100,60,90,180);
}

Dos arcos
circulares

Los crculos son una manera fcil de


visualizar este tipo de arcos; en tanto los
arcos sobre las elipses son ms difciles,
dibujemos una elipse como la que se
muestra a continuacin:

Como el arco en el circulo, es un


segmento de un valo completo, en este
caso, un valo elptico. Al completar el
valo del que el arco forma parte,
obtendr los argumentos de los puntos
iniciales, y el largo y el ancho para los
mtodos drawArc( ) y fillArc( ), vea la
figura:

140

30
Arcos sobre
elipses

Ahora lo que tiene que hacer, es


determinar el ngulo inicial y el ngulo
para el recorrido. Este arco no comienza
en un lmite sencillo como 90 u 180
grados, as que deber intentar y probar
algunos valores. Este arco comienza en
algn lugar alrededor de los 25 grados y
se desplaza en el sentido de las
manecillas de reloj como unos 130
grados.

90o
25o
90o

0o
-130o
Arcos sobre
elipses
270o

Con todas lasa partes del arco en su


lugar, ahora puede escribir el cdigo
correspondiente, como se muestra en
seguida tanto para el arco sencillo
como para el arco relleno.

import java.awt.Graphics;
public class MyOval extends
java.applet.Applet{
public void paint(Graphics g) {
g.drawArc(10,20,150,50,25,130);
g.fillArcl(10,80,150,50,25,130);
}
}

La siguiente figura muestra los arcos


elpticos:

6.2 TEXTO Y FUENTES

Al utilizar la clase graphics tambin


puede mostrar texto en la pantalla, en
conjunto con la clase Font. La clase
Font representa un tipo de letra
determinado (su nombre, estilo,
tamao de puntos) y FontMetrics
proporciona informacin acerca de la
fuente (alto y ancho de algn carcter)
de manera que puede disear con
precisin el texto de su applet.

Cmo crear objetos font


Para dibujar texto en la pantalla,
primero debe crear una instancia de la
clase Font. Estos objetos representan
un tipo de letra en particular y tambin
en puntos. Los nombres de las fuentes
son cadenas que representan a la
familia del tipo de letra. Los estilos de
fuentes son constantes definidas por la
clase Font; puede accederlas por
medio de variables de clase.

El tamao de puntos es el tamao de la


fuente, como lo haya definido la propia
fuente; el tamao de los puntos puede o
no ser la altura de los caracteres.
Para crear un objeto fuente individual
utilice estos tres argumentos en el nuevo
constructor de la clase Font

Font f = new Font(TimesRoman,


Font.BOLD, 24);

Este ejemplo crea un objeto font para


el tipo de letra Times Roman, en
negrita, de 24 puntos. Observe que
como en la mayora de las clases Java,
debe importar la clase java.awt.Font
antes de utilizarla.
El tipo de fuentes disponibles para su
applet depende de las fuentes que se
encuentren instaladas en el sistema
donde se ejecuta.

Si selecciona una fuente y no est instalada


en el sistema actual, Java utilizar la fuente
sustituta predeterminada. Puede averiguar
los nombres de las fuentes instaladas en el
sistema al utilizar esta instruccin:
String
[]
fontslist
this.getToolkit( ).getFontList( );

Con esta lista podr elegir de manera


inteligente las fuentes que utilizar en su
applet.

6.3 CMO DIBUJAR


CARACTERES
Y CADENAS

Contando ya con el objeto fuente,


puede dibujar textos en la pantalla por
medio de los mtodos drawChars( ) y
drawString( ). Sin embargo primero
necesitar asignar a la fuente actual en
su objeto font utilizando el mtodo
setFont( ).

La fuente actual es parte de los grficos


monitoreados por medio del objeto
graphics en donde usted est dibujando.
Cada vez que dibuja un carcter o una
cadena en la pantalla, Java dibuja texto
con la fuente actual. Para cambiar el tipo
de letra del texto primero cambie la
fuente actual. El siguiente mtodo paint(
)crea una nueva fuente , la establece
como la fuente actual y dibuja la cadena
Esta es una fuente Grande en el punto
10,100:

public void paint(Graphics g) {


Font
f
=
new
Font(TimesRoman,
Font.PLAIN,
72);
g.setFont(f);
g.drawstring(Este es una fuente
Grande.,10,100);
}

Los ltimos dos argumentos de


drawString determinan el punto donde
empieza la cadena. El valor x es el
inicio de la orilla ms a la izquierda y
la y es la base para toda la cadena.
El mtodo drawChars( )es similar a
drawString( ) que en lugar de tomar
una cadena como un argumento, toma
un arreglo como un conjunto de
caracteres.

El mtodo drawCahrs( ) tiene cinco


argumentos : el arreglo de caracteres, un
entero que representa el primer carcter
del arreglo a dibujar , otro entero para el
ltimo carcter del arreglo
y las
coordenadas x y y para el punto inicial.
La mayora de las veces drawString( )es
ms til que drawChars( ).
El siguiente listado muestra un applet
que dibuja varias lneas de texto en
diferentes tipos de letras; en la figura
vemos el resultado.

import java.awt.Graphics;
import java.awt.Graphics;
public class ManyFonts extends
java.applet.Applet{
public void paint(Graphics g) {
Font
f
=
new
Font(TimesRoman, Font.PLAIN,
18);
Font fb = new Font(TimesRoman,
Font.BOLD, 18);
Font f i= new Font(TimesRoman,
Font.ITALIC, 18);

Font fbi = new Font(TimesRoman,


Font.BOLD + Font.ITALIC, 18);
g.setFont(f);
g.drawstring(Esta es una fuente
plain.,10,25);
g.setFont(f);
g.drawstring(Esta es una fuente
bold.,10,50);
g.setFont(f);

g.drawstring(Esta es una fuente


italic.,10,75);
g.setFont(f);
g.drawstring(Esta es una fuente bold
italic.,10,100);
}
}

Esta es una fuente plain


Esta es una fuente bold
Esta es una fuente italic
Esta es una fuente bold italic.

6.4 COLOR

Se puede trabajar con colores haciendo


uso de la clase Color. El modelo de
color abstracto de Java utiliza colores de
24 bits, donde se representa como una
combinacin de valores de rojo, verde y
azul (RGB). Cada uno de stos colores
puede tener un valor entre el 0 y el 255.
0,0,0 representa al negro y 255,255,255
al blanco. Java puede presentar millones
de colores entre estos intervalos.

El modelo de color abstracto de Java se


mapea en el modelo de color de la
plataforma Java en que se ejecuta el applet,
la cual tiene por lo general 256 colores o
menos. Si el color solicitado en un objeto
no est disponible o no puede desplegarse,
el color resultante puede ser mapeado a
otro dependiendo de cmo vea el
navegador el color implementado, y de la
plataforma en la que se est ejecutando. En
otras palabras, a pesar de que Java puede
desplegar millones de colores, slo muy
pocos estarn disponibles en la vida real

Cmo utilizar los objetos Color


Para dibujar un objeto en un color en
particular, debe crear una instancia de
la clase Color para representarlo. Esta
clase define un conjunto de objetos de
color estndar, almacenados en
variables de clase, para tener acceso a
los colores ms populares. La siguiente
tabla, muestra los colores estndar
definidos por las variables la clase
Color.

Nombre del color

Valor RGB

Color.white

255,255,255

Color.black

0,0,0

Color.lightGray

192,192,192

Color.gray

128,128,128

Color.darkGray

64,64,64

Color.red

255,0,0

Color.green

0,255,0

Color.blue

0,0,255

Color.yellow

255,255,0

Color.magenta

255,0,255

Color.cyan

0,255,255

Color.pink

255,175,175

Color.orange

255,200,0

Si el color que busca no est en los


estndar, puede crear un objeto color
con su propia combinacin de rojo,
verde y azul, mientras tenga los
valores del color que desea. Para crear
un nuevo objeto color teclee:
Color c = new Color (140,140,140);

Esta lnea crea un objeto Color que


representa un gris oscuro. Puede
utilizar cualquier combinacin de rojo,
verde y azul para construir un objeto
Color. Como alternativa puede crear un
objeto Color utilizando tres nmeros
flotantes entre el 0.0 y el 1.0:

Color c = new Color (0.55,0.55,0.55);

Cmo definir y probar los


colores actuales
Para dibujar un objeto o texto
utilizando un objeto a color, tiene que
definir el color actual para ese objeto,
de la misma manera en que lo hizo
para definir la fuente actual con la que
quiere dibujar. Utilice el mtodo
setColor( ) (pertenece a los objetos
Graphics) para hacer esto:
g.setColor (Color.green);

Despus de definir el color actual,


todas las operaciones de dibujo se
realizarn con este color.
Adems de definir el color actual para
el contexto grfico, tambin puede
determinar los colores de fondo y de
primer plano para el applet mismo al
utilizar los mtodos setBackground( ) y
setForeground( ). Ambos estn
definidos
en
la
clase
java.awt.Component y por consiguiente
sus clases lo heredan automticamente.

Para definir el color de fondo de su


applet:
SetBackground (Color.white);
El mtodo setForeground( ) tambin toma
un solo color como argumento, afecta a
todo lo que ha dibujado en la applet, sin
importar el color en el cual fue dibujado.
Puede utilizar el mtodo setForeground( )
para cambiar el color de todo el applet de
un solo paso en lugar de tener que
redibujar todo:
SetForeground(color.black);

Adems de los mtodos setColor( ),


setForeground( ) y setBackground( ),
existen sus correspondientes mtodos get
que le permiten recuperar el color del
grfico actual, de fondo o de primer plano.
Estos mtodos son getColor( ) (definido
en los objetos graphics), getForeground( )
(definido en applet) y getBackground( ).
Puede utilizar estos mtodos para
seleccionar colores tomando como
referencia colores que ya existen el applet.
SetForeground (g.getColor( ));

6.5 EJEMPLOS DE GRAFICOS

1)
import java.awt.Graphics;
import java.applet.Applet;
import java.awt.Color;
public class Class1 extends Applet{
private Color c;
public void init()
{
c=Color.blue;
}

public void paint (Graphics g)


{
g.setColor(c);
g.drawString
("ABCDEFGHIJKLMNOPQRSTUVWX
YZ", 50,33);
showStatus("RGB vigente: " + " " +
String.valueOf(c.getGreen())+
String.valueOf(c.getBlue()));
}

""+

2)
import java.awt.Graphics;
import java.awt.Color;
import java.applet.Applet;
public class Class1 extends Applet
{
public void paint (Graphics g)
{
g.setColor(Color.pink);
g.fillOval(20,10,100,50);
g.setColor(Color.yellow);
g.fillOval(100,10,100,50);

g.setColor(Color.orange);
g.fillRect(190,10,80,50);
g.setXORMode(Color.yellow);
g.fillOval(180,25,60,20);
g.setColor(Color.blue);
g.fillArc(150,20,20,20,0,360);
g.setColor( Color.red);
g.fillRect(120,25,20,20);
}
}

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

public class Class1 extends Applet


{
public void paint (Graphics g)
{
g.drawArc(15,15,80,80,0,180);
g.drawArc(10,100,80,80,0,110);
g.fillArc(100,15,70,80,0,270);
g.fillArc(15,70,70,80,0,-110);
g.fillArc(190,15,80,140,0,-360);
}
}

CAPTULO VII
MULTIHILOS

7.1 INTRODUCCIN

Sera bonito que pudiramos hacer una


cosa a la vez y hacerlo bien, pero la
verdad es que el mundo no funciona as.
El cuerpo humano realiza una gran
variedad de operaciones en paralelo o de
forma concurrente o simultanea. Por
ejemplo, la respiracin, la circulacin de
la sangre y la digestin pueden ocurrir
simultneamente. Todos los sentidos
vista, tacto, olfato, gusto y odo- pueden
ejecutarse de forma concurrente.

Un automvil puede estar acelerando,


dando vuelta, acondicionando el aire y
tocando msica concurrentemente.
Tambin las computadoras realizan
operaciones concurrentes. Ya es comn
que computadoras personales de
escritorio
estn
compilando
un
programa, imprimiendo un archivo y
recibiendo
mensajes
de
correo
electrnico
por
una
red
concurrentemente.

El lenguaje de programacin Ada


desarrollado por el Departamento de la
Defensa de Estados Unidos puso las
primitivas de concurrencia a la
disposicin de los contratistas de la
Defensa que construyen sistemas de
mando y control. Sin embargo, Ada no
se ha usado mucho en las
universidades ni en la industria
comercial.

Java es nico entre los lenguajes de


programacin de propsito general
populares porque pone primitivas de
concurrencia a la disposicin del
programador de aplicaciones para
computadoras
personales.
El
programador especifica que las
aplicaciones contienen hilos de
ejecucin, cada uno de los cuales
designa una porcin del programa que
se puede ejecutar en paralelo con otros
hilos.

Esta capacidad, llamada multihilado,


confiere al programador en Java potentes
capacidades que no estn disponibles en
C ni en C++, los lenguajes en los que se
basa Java. Decimos que C y C++ son
lenguajes de un solo hilo.

Cuando los programas descargan


archivos grandes como clips de audio
o video de la World Wide Web,
preferiramos no esperar hasta que se
descargue todo el clip antes de iniciar
su reproduccin. As, podramos poner
dos hilos a trabajar, uno que descargue
el clip y otro que lo reproduzca, para
que estas actividades, o tareas, puedan
proceder de forma concurrente.

A fin de evitar una reproduccin


encontrada, coordinaremos los hilos
de modo que el hilo reproductor no
inicie antes de que haya en la memoria
una fraccin suficiente del clip para
mantener ocupado al hilo reproductor.

Otro ejemplo de multihilado es la


recoleccin automtica de basura de
Java. C y C++ dejan al programador la
responsabilidad de recuperar la
memoria
que
se
reparti
dinmicamente. Java provee un hilo
recolector
de
basura
que
automticamente recupera la memoria
dinmicamente repartida que ya no se
necesita.

El recolector de basura de Java se ejecuta


como un hilo de baja prioridad. Cuando
Java determina que ya no hay referencias
a un objeto, lo marca para que en algn
momento sea recolectado como basura.
El recolector de basura se ejecuta cuando
hay tiempo de procesador disponible y
cuando no hay hilos ejecutables de ms
alta prioridad. Por otro lado, el recolector
de basura se ejecutar de inmediato si el
sistema se queda sin memoria.

Aunque Java quiz es el lenguaje de


programacin ms porttil del mundo,
ciertas porciones del lenguaje no pueden
ms que ser dependientes de la
plataforma.
En
particular,
hay
diferencias entre las primeras tres
plataformas
de
Java
que
se
implementaron,
a
saber,
la
implementacin
Solaris
y
las
implementaciones basadas en Windows
para Windows 95 y Windows NT.

La plataforma Solaris Java inicial


ejecuta un hilo de cierta prioridad hasta
completarlo o hasta que est listo un
hilo de ms alta prioridad. En este punto
ocurre un desalojo; es decir, se concede
el procesador al hilo de mayor prioridad
y el hilo que antes se estaba ejecutando
debe esperar.

En las implementaciones de 32 bits de


Java para Windows 95 y Windows NT,
los hilos se manejan por tajadas de
tiempo. As, en Windows 95 y Windows
NT, un hilo en ejecucin puede ser
desalojado por un hilo de igual prioridad,
mientras que en la implementacin
Solaris inicial un hilo Java en ejecucin
slo puede ser desalojado por un hilo de
ms alta prioridad. Se espera que los
sistemas Solaris Java futuros manejen
tambin tajadas de tiempo.

7.2

MTODOS DE HILOS .

En seguida se da una explicacin de


algunos mtodos que se relacionan
con los hilos.
La clase Thread (hilo) tiene varios
constructores. El constructor
public Thread(String threadName)
construye un Thread cuyo nombre es
ThreadName (nombre de hilo). El
constructor:

public Thread()

construye un Thread cuyo nombre es


Thread concatenado con un dgito,
como Thread1, Thread2, etc.

Un programa inicia la ejecucin de un


hilo invocando el mtodo star (arrancar)
de ese hilo; a su vez, start invoca el
mtodo run. Una vez que start echa a
andar el hilo, regresa de inmediato a su
invocador. De ah en adelante, el
invocador se ejecutar en paralelo con el
hilo iniciado. El mtodo start lanza una
excepcin de estado de hilo ilegal
(Illegal ThreadStateException) si el hilo
que esta tratando de echar a andar ya se
est ejecutando.

El mtodo static sleep (dormir) se


invoca con un argumento que
especifica durante cuanto tiempo el
hilo que se est ejecutando debe
dormir (en segundos); mientras un hilo
duerme , no compite por el procesador,
y otros hilos pueden ejecutarse. Esto
da oportunidad a hilos de ms baja
prioridad a ejecutarse.

El mtodo interrupt (interrumpir) se


invoca para interrumpir un hilo. El
mtodo interrupted (interrumpido),
que es static, devuelve true si el hilo
ha sido interrumpido y false en caso
contrario. La llamada de mtodo
isInterrupted (est interrumpido), un
mtodo no static, se enva a algn otro
hilo para determinar si ha sido
interrumpido.

El mtodo suspend suspende la


ejecucin de un hilo. El mtodo resume
reanuda la ejecucin de un hilo
suspendido. Un intento por reanudar un
hilo que no est suspendido le permite
continuar ejecutndose.
El mtodo stop detiene un hilo lazando
un objeto ThreadDeath (muerte de
hilo). La mayora de los usuarios
utilizarn la versin de stop que no
recibe argumentos.

El mtodo isAlive (est vivo) devuelve


true si se ha invocado start para un
hilo dado pero todava no se ha
invocado stop para ese hilo.
El mtodo setName establece el
nombre del Thread. El mtodo
getName devuelve el nombre del
Thread. El mtodo toString devuelve
un String que consiste en el nombre del
hilo, su prioridad y su grupo de hilos.

El mtodo static currentThread (hilo


actual) devuelve una referencia al Thread
actual.
El mtodo join(unirsea, que recibe como
argumento
alguna
cantidad
de
milisegundos) hace que el Thread actual
espere hasta que el Thread al que se envi
el mensaje muera antes de continuar; si no
se proporciona argumento o el argumento
es de 0 milisegundos, se est especificando
que el Thread debe esperar indefinidamente
a que muera el Thread objetivo antes de
que el Thread actual contine.

Semejante espera puede ser peligrosa;


podra dar pie a dos problemas
especialmente
graves
llamados
bloqueo mortal y aplazamiento
indefinido.

7.3

ESTADOS DE HILOS.

En cualquier momento, se dice que un


hilo est en uno de varios estados de
hilos (que se ilustra en la figura 7.3.1).
Digamos que un hilo que se acaba de
crear est en el estado nacido. El hilo
permanece en ese estado hasta que se
invoca el mtodo start del hilo; esto
hace que el hilo pase al estado listo. El
hilo listo de ms alta prioridad pasa al
estado en ejecucin cuando el sistema
asigna un procesador al hilo (esto es,
el hilo inicia su ejecucin).

Un hilo pasa al estado muerto cuando


termina su mtodo run o cuando se
invoca el mtodo stop; en algn
momento el sistema dispondr del hilo
muerto.

nacido
start
listo
Expiracin
de cuanto

notify
wait

despachar
En ejecucin

sleep
En espera

dormido

Expira intervalo
de sueo
stop

Completar
E/S
Solicitud
de E/S

suspend
suspendido
bloqueado
completar

resume

muerto

Figura 7.3.1. Ciclo de vida de un hilo.

Un hilo en ejecucin pasa al estado


bloqueado cuando el hilo permite una
solicitud de entrada/ salida. Un hilo
bloqueado queda listo cuando la E/S
que estaba esperando termina. Un hilo
bloqueado no puede usar un
procesador
aunque
haya
uno
disponible.

Cuando se invoca el mtodo sleep de un


hilo en ejecucin, ese hilo pasa al
estado dormido. Un hilo dormido queda
listo cuando expira el tiempo de sueo
designado. Un hilo dormido no puede
usar un procesador aunque haya uno
disponible.

Cuando se invoca el mtodo


suspend de un hilo en ejecucin, el hilo
pasa al estado suspendido . Un hilo
suspendido queda listo cuando otro hilo
invoca su mtodo resume(reanudar). Un
hilo suspendido no puede usar un
procesador aunque haya uno disponible.

Cuando un hilo en ejecucin llama a


wait, el hilo pasa al estado en espera,
donde espera en una cola asociada al
objeto especfico para el cual invoc
wait. El primer hilo de la cola de espera
para un objeto en particular queda listo
cuando otro hilo asociado a este objeto
emite una llamada notify (notificar).
Todos los hilos de la cola de espera para
un objeto dado quedan listos cuando otro
hilo asociado a ese objeto emite una
llamada notifyAll (notificar a todos) .

Un hilo pasa al estado muerto cuando su


mtodo run termina o cuando se invoca
su mtodo stop. El mtodo stop (parar)
enva un objeto ThreadDeath al hilo
ThreadDeath es una subclase de la
clase Error.

7.4 PRIORIDADES DE HILOS


Y PLANIFICACION
DE HILOS

Toda applet o aplicacin Java es


multihilos. Todo hilo Java tiene una
prioridad
en
el
intervalo
de
Thread.MIN_PRIORITY
(una
constante
que
vale
1)
a
Thread.MAX_PRIORITY
(una
constante que vale 10). Por omisin, a
todos los hilos se les asigna la prioridad
normal Thread. NORM_PRIORITY
(una constante que vale 5). Todo hilo
nuevo hereda la prioridad del hilo que
lo cre.

Toda applet o aplicacin Java es


multihilos. Todo hilo Java tiene una
prioridad
en
el
intervalo
de
Thread.MIN_PRIORITY
(una
constante
que
vale
1)
a
Thread.MAX_PRIORITY
(una
constante que vale 10). Por omisin, a
todos los hilos se les asigna la prioridad
normal Thread.NORM_PRIORITY
(una constante que vale 5). Todo hilo
nuevo hereda la prioridad del hilo que
lo cre.

Algunas plataformas de Java manejan un


concepto llamado tajadas de tiempo; otras no
lo hacen. Sin tajadas de tiempo, cada hilo de
un conjunto de hilos con la misma prioridad
se ejecuta hasta terminar antes de que los
iguales de ese hilo tengan oportunidad de
ejecutarse. Con las tajadas de tiempo, cada
hilo recibe un lapso breve de tiempo de
procesador llamado cuanto, durante el cual
ese hilo puede ejecutarse. Al expirar cuanto,
sea que el hilo haya completado su ejecucin
o no, se le quitar el procesador a ese hilo y
se le dar al siguiente hilo con la misma
prioridad si hay uno listo.

La tarea del planificador de Java es


mantener un hilo de mxima prioridad
ejecutndose en todo momento y, si se
cuenta con tajadas de tiempo,
asegurarse de que varios hilos con la
misma prioridad se ejecuten, cada uno
durante un cuanto, siguiendo un turno
circular (es decir, por tajadas de
tiempo). En la figura 7.4.1 se ilustra la
cola de prioridad multinivel de Java
para los hilos.

En la figura, los hilos A y B se


ejecutan, cada uno durante un cuanto,
por turno circular hasta que ambos
terminan su ejecucin. A continuacin,
el hilo C se ejecuta hasta terminar.
Luego, los hilos D, E y F se ejecutan,
cada uno durante un cuanto, por turno
circular hasta que todos terminan su
ejecucin. Este proceso contina hasta
que todos los hilos terminan de
ejecutarse.

Cabe sealar que la aparicin de nuevos


hilos de alta prioridad podra posponer
tal vez indefinidamentela ejecucin
de los hilos de baja prioridad. Este
desplazamiento indefinido tambin se
conoce con el nombre ms sugestivo de
inanicin.

La prioridad de un hilo puede


ajustarse con el mtodo setPriority,
que recibe un argumento int. Si el
argumento no est en el intervalo de 1
a 10 inclusive, el mtodo setPriority
lanzar una excepcin de argumento
no
permitido
(IllegalArgumentException).
El
mtodo getPriority
devuelve la
prioridad del hilo.

Un hilo puede llamar al mtodo yield


(ceder el paso) para dar a otros hilos
oportunidad de ejecutarse. De hecho,
siempre que un hilo de ms alta
prioridad queda listo, el hilo actual es
desalojado, as que un hilo no puede
ceder el paso a un hilo de ms alta
prioridad porque ya habr sido
desalojado en el momento en que el
hilo de ms alta prioridad qued listo.

Por lo mismo, yield siempre permite


que se ejecute el hilo listo con ms alta
prioridad, y si los nicos hilos que
estn listos tienen ms baja prioridad
que el hilo actual, ste ser el hilo con
la ms alta prioridad y seguir
ejecutndose. Por tanto, un hilo usa
yield slo para dar oportunidad de
ejecutarse a hilos de la misma
prioridad.

En un sistema con tajadas de tiempo


esto es innecesario porque los hilos con
la misma prioridad se ejecutan por
turno circular durante un cuanto cada
uno (o hasta que pierden el procesador
por alguna razn). As yield resulta
apropiado para sistemas sin tajadas de
tiempo en los que un hilo normalmente
se ejecuta hasta terminar antes de que
otro hilo con la misma prioridad tenga
oportunidad de ejecutarse.

Hilos listos

Prioridad 10

Prioridad 9

Prioridad 8

C
D

Prioridad 7
G
Prioridad 6
H

Prioridad 5

Prioridad 4
Prioridad 3
Prioridad 2
Prioridad 1

Figura 7.4.1.

Planificacin por prioridad de hilos en Java.

Un hilo se ejecuta hasta que muere, se


bloquea para entrada/salida, llama a sleep
llama a yield o es desalojado por un hilo
de mayor prioridad, o hasta que un cuanto
expira. Un hilo con una prioridad ms alta
que la del hilo actual puede quedar listo (y
por tanto desalojar al hilo en ejecucin) si
se reanuda un hilo suspendido, si un hilo
dormido termina de dormir, si se completa
la E/S que un hilo estaba esperando, o si
se invoca notify o notifyAll para un hilo
que invoc wait.

La aplicacin de la figura 7.4.2 demuestra


algunas tcnicas bsicas de manejo de
hilos, incluida la creacin de una clase
derivada de Thread, construccin de un
Thread y el empleo del mtodo sleep de
la clase Thread. Cada hilo de ejecucin
que creamos en el programa exhibe su
nombre despus de dormir durante un
tiempo aleatorio entre 0 y 5 segundos. El
programa consiste en dos clases:
PrintThread (imprimir hilo) y PrintTest
(prueba de impresin).

La clase PrintThread que hereda de


Threadconsiste en la variable de
ejemplar sleepTime (tiempo de sueo),
un constructor y un mtodo run. La
variable de ejemplar
sleepTime
almacena un valor entero aleatorio que
se escoge cuando se contruye un objeto
Printthread. Cada objeto PrintThread
dormir durante el tiempo especificado
por sleepTime y luego exhibir su
nombre.

El constructor PrintThere recibe un


argumento String que representa el nombre
del hilo, e invoca el constructor Thread de
la superclase con ese String. El constructor
de la clase Thread usa el String para
establecer el nombre del hilo. A
continuacin, el constructor PrintThread
inicializa sleepTime asignndole un entero
aleatorio entre 0 y 5000 (0 a 5 segundos).
Luego se exhibe el nombre y el valor de
sleepTime para mostrar los valores
correspondientes al PrintThread especfico
que esta construyendo.

Cuando se invoca el mtodo star de un


PrintThread (heredado de Thread), el
objeto PrintThread pasa al estado
listo. Cuando el sistema asigna un
procesador al objeto PrintThread,
ste pasa al estado en ejecucin y su
mtodo run comienza a ejecutarse. El
mtodo run invoca al mtodo sleep
(lnea 42) que de inmediato hace que el
objeto pase al estado dormido.

Cuando el objeto despierta, pasa otra vez al


estado listo en el que permanece hasta que
se le asigna un procesador. Cuando el
objeto PrintThread pasa otra vez al estado
en ejecucin, exhibe su nombre. A
continuacin, el mtodo run termina y el
objeto PrintThread pasa al estado muerto.
Observe que el mtodo sleepn puede lanzar
una
excepcin
de
interrumpido
(InterruptedException), por lo que se
debe invocar dentro de un bloque try, o
bien la excepcin debe declararse en la
clusula throws del mtodo run.

El mtodo main de la clase PrintTest


ejemplariza cuatro objetos PrintThread
e invoca el mtodo start de la clase
Thread para cada uno a fin de
colocarlos en el estado listo.

7.5

EJEMPLOS

4:
5:
6:
7:
8:
9:
10:

public class Class1{


public static void
main (String args[])
{
PrintThread
thread1,thread2,
thread3, thread4;
thread1 = new
PrintThread("1");
thread2 = new
PrintThread("2");

11:
12:
13:
14:
15:
16:
17:
18:
19:
20:

thread3 = new
PrintThread("3");
thread4 = new
PrintThread("4");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}

21:
22:
23:
24:
25
26:
27:
28:
29:
30:

class PrintThread extends


Thread {
int sleepTime;

public
PrintThread
(String id)
{
super(id);

31:

sleepTime = (int)
(Math.random()*5000);

32:
33:System.out.println("Nombre:
"+ getName() + "; dormir: "
+ sleepTime);
34:
35:
}
36:
37:
38:
public void run()
39:
{
40:

41:
try {
42:
sleep(sleepTime);
43:
}
44: catch
(InterruptedException
exception) {
45: System.err.println("Excepcin:
" + exception.toString());
46:
47:
}
48:
49:
50:
System.out.println ("Hilo"
+getName());

51:
52: }

Figura 7.6.1. Mltiples hilos


queimprimen a intervalos aleatorios.

Cada hilo de ejecucin que se


crea en el programa exhibe su nombre
despus de dormir durante un tiempo
aleatorio entre 0 y 5 segundos. El
programa consiste en dos clases
PrintThread (imprimir hilo) y
PrintTest (prueba de impresin).

La clase PrintThread que hereda


de Thread consiste en la variable de
ejemplar sleepTime (tiempo de sueo),
un constructor y un mtodo run. La
variable de ejemplar sleepThread. Cada
onjeto PrintThread dormir durante el
tiempo especificado por sleepTime y
luego exhibir su nombre. El constructor
PrintThread recibe un argumento String
que representa el nombre del hilo, e
invoca el constructor Thread de la
superclase con ese String.

El constructor de la clase Thread


usa el String para establecer el nombre
del hilo. A continuacin, el constructor
PrintThread
inicializa
sleepTime
asignndole un entorno aleatorio entre
0 y 5000 (0 a 5 segundos). Luego se
exhibe el nombre y el valor de
sleepTime para mostrar los valores
correspondientes
al
PrintThread
especfico que est construyendo.

Cuando se invoca el mtodo start de


un PrintThread (heredado de Thread), el
objeto PrintThread pasa al estado listo.
Cuando el sistema asigna un procesador al
objeto PrintThread, ste pasa al estado en
ejecucin y su mtodo run comienza a
ejecutarse. El mtodo run invoca al mtodo
sleep (lnea 42) que de inmediato hace que
el objeto pase al estado dormido. Cuando
el objeto despierta, pasa otra vez al estado
listo, en el que permanece hasta que se le
asigna un procesador.

Cuando el objeto PrintThread pasa


otra vez al estado en ejecucin, exhibe
su nombre. A continuacin el mtodo
run termina y el objeto PrintThread
pasa al estado muerto. Observemos que
el mtodo sep puede lanzar una
excepcin
de
interrumpido
(InterrupteException), por lo que se
debe invocar dentro de un bloque try, o
bien la excepcin debe declararse en la
clusula throws del mtodo run.

El mtodo main de la clase


PrintTest ejemplariza cuatro objetos
PrintThread e invoca el mtodo start de
la clase Thread para cada uno a fin de
colocarlos en el estado listo.
El siguiente applet muestra un reloj
digital animado, que usa las tcnicas
bsicas de animacin para mostrar la
fecha y hora, actualizndola cada
segundo:

1:
2:
3:
4:
5:
6:

import java.awt.Graphics;
import java.awt.Font;
import java.util.Calendar;
import
java.util.GregorianCalendar;
public class Class1 extends
java.applet.Applet
implements Runnable{

7:
8:
9:Font theFont= new Font("TimesRoman",
Font.BOLD,24);

10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:

GregorianCalendar
theDate;
Thread runner;
public void start () {
if (runner == null){
runner=new Thread(this);
runner.start();
}
}
public void stop() {

21:
22:
23:
24:
25:
26:
27:
28:
29:
30:

if (runner !=null){
runner.stop();
runner=null;
}
}
public void run(){
while (true){
repaint();
try {Thread.sleep(1000); }

31:catch (InterruptedException e) {}
32:
}
33:
}
34:
35:public void paint(Graphics g ){
36:theDate= new
GregorianCalendar();
37: g.setFont(theFont);
38: g.drawString("" +
theDate.getTime(),10,50);
39:
}
40: }

La lnea 9 y 10 definen dos variables de


instancia bsica: theFont y theDate, las
cuales contienen los objetos que
presentan la fuente y la fecha actual,
respectivamente.
Los mtodos start() y stop() inician y
terminan un subproceso; la mayor parte
del trabajo del applet se encuentra en el
mtodo run().

Dentro del mtodo run() es donde se


lleva a cabo realmente la animacin.
Observemos el ciclo while() de la lnea
28; dado que la prueba siempre regresa
el valor true, el ciclo nunca termina.

Lo primero que sucede en el ciclo es que


la instruccin repaint() se llama en la
lnea 29 para volver a dibujar el applet.
Las lneas 30 y 31, que parecen muy
complicadas, lo nico que hacen es una
pausa de 1000 milisegundos (un
segundo) antes de que repita el ciclo. El
mtodo sleep(), parte de la clase Thread,
es el que hace la pausa.

Sin un mtodo sep() especfico, el


applet podra correr tan rpido como
fuera posible; este mtodo controla de
una manera exacta la velocidad de
ejecucin de la animacin. Las
funciones try y catch habilitan la
administracin de errores, si es que
sucede. Estas funciones manejan las
excepciones que se vern ms
adelante.

En el mtodo paint() que est en las


lneas 35 a 38, se crea una nueva
instancia
de
la
clase
GregorianCalendar para almacenar la
fecha y hora actuales. Este nuevo objeto
es asignado a la variable de instancia
theDate.

En la lnea 37, se define el tipo de


fuente utilizando el valor de la variable
theFont, y la fecha es desplegada en la
pantalla (observese que se tiene que
llamar al mtodo getTime() de la clase
GregorianCalendar para mostrar la
fecha y la hora como una cadena). Cada
vez que se llame apaint(), se crea un
nuevo objeto theDate para almacenar la
fecha y hora actual.

Revisemos las lneas de ste applet que


crean y administran los subprocesos.
Primero veamos las definiciones de las
lneas 6 y 7 (observemos que incluye la
interfaz Runnable). Todas las clases que
necesiten subprocesos deben incluir la
interfaz Runnable.
La lnea 11 define una tercer variable de
instancia para esta clase llamada runner
del tipo Thread, la cual almacenar el
subproceso para este applet.

Las lneas 13 a 25 definen los mtodos


start() y stop() que slo crean y
destruyen subprocesos. Estas funciones
de mtodo pueden ser exactamente las
mismas de una clase a otra porque todo
lo que hacen es proporcionar la
infraestructura de los subprocesos.
Por ltimo, la mayora del trabajo del
applet se realiza dentro del mtodo
run(), entre las lneas 27 a 33.

7.6

SINCRONIZACIN
DE HILOS

Java usa monitores para manejar la


sincronizacin. Todo objeto con mtodos
syncronized(sincronizado)
es
un
monitor. El monitor slo permite a un
hilo a la vez ejecutar un mtodo
synchronized con el objeto. Esto se logra
poniendo un candado al objeto cuando
se invoca el mtodo synchronized, slo
uno de ellos podr estar activo con un
objeto a la vez; todos los dems hilos
que
intenten
invocar
mtodos
synchronized debern esperar.

Cuando un mtodo synchronized


termina de ejecutarse, se libera el
candado del objeto y el monitor
permite que el hilo listo con ms alta
prioridad que est intentando invocar
un mtodo synchronized proceda.

Un hilo ejecutndose en un mtodo


synchrorized podra determinar que no
puede continuar, as que el hilo invoca wait
voluntariamente. Esto hace que el hilo deje
de competir con el procesador y por el
objeto monitor. Ahora el hilo esperar en
una cola mientras otros hilos dejen de entrar
en el objeto. Cuando un hilo que est
ejecutando un mtodo synchronized termina
el objeto puede notificar (con notify) a un
hilo en espera que vuelva a estar listo para
que pueda intentar obtener otra vez el
candado del objeto monitor y ejecutarse.

El notify acta como seal para el hilo


en espera, indicndole que la condicin
que estaba esperando ya se satisface y
que es aceptable que vuelva a entrar en
el monitor. Si un hilo invoca notifyAll,
todos los hilos estaban esperando el
objeto se hacen elegibles para volver a
entrar en el monitor (es decir, pasan al
estado listo). Recuerde que slo uno de
esos hilos puede obtener el candado del
objeto a la vez.

Los objetos monitor forman en cola


todos los hilos que esperan entrar en el
objeto
para
ejecutar
mtodos
synchronized. Un hilo se forma en cola y
espera el objeto si ese hilo llama a un
mtodo synchronized del objeto mientras
otro hilo ya se est ejecutando en un
mtodo synchronized de dicho objeto.
Un hilo tambin se forma en cola si
llama a wait mientras esta operando
dentro del objeto.

Sin embargo, es importante distinguir


entre los hilos en espera que se
bloquearon porque el monitor estaba en
ocupado y los hilos que explcitamente
invocaron wait dentro del monitor. Al
terminar un mtodo synchronized, los
hilos externos que se bloquearon por
que el monitor estaba ocupado pueden
proceder a entrar al objeto.

Los hilos que explcitamente invocaron


a wait slo podrn continuar cuando se
les notifique que pueden hacerlo (es
decir, cuando otro hilo invoca notify o
notifyAll). Cuando sea aceptable que
un hilo formado en cola continu, el
planificador seleccionar el hilo que
tenga la ms alta prioridad.

Relacin productor/consumidor sin


sincronizacin de hilos
En una relacin productor/consumidor,
un hilo productor que invoca un mtodo
de producir puede darse cuenta de que el
hilo consumidor no ley el ltimo
mensaje de una regin de memoria
compartida llamada buffer, as que el hilo
productor llamar a wait.

Cuando un hilo consumidor lee el


mensaje, llama notify para que el
productor en espera pueda continuar.
Cuando un hilo consumidor entra en el
monitor y encuentra el buffer vaco,
llama a wait. Un productor que
encuentre buffer vaco escribir en el y
luego llamar a notify para que el
consumidor en espera pueda proceder.

Los
datos
compartidos
pueden
corromperse si no sincronizamos el
acceso entre mltiples hilos. Considere
una
relacin
productor/consumidor
sencilla en la que un hilo productor
deposita una secuencia de nmeros
(usaremos 0,1,2,...) en una ranura de
memoria compartida. El hilo consumidor
lee estos datos de la ranura de memoria
compartida y los imprime. Imprimiremos
lo que el productor produce en el
momento en que lo consume.

La aplicacin demuestra un productor y


un consumidor que acceden a una celda
de
memoria
compartida
sin
sincronizacin. Porque estos hilos no
estn sincronizados, se pueden perder
datos si el productor coloca un dato
nuevo en la ranura antes de que el
consumidor consuma el dato anterior, y
se pueden duplicar datos si el
consumidor consume un dato antes de
que el productor produzca el siguiente
dato.

1: //Mostrar
mltiples
hilos
modificando un objeto compartido.
2:
3:
4: public class SharedCell {
5:
public static void main(
String args[] )
6:
{
7:
HoldInteger h = new
HoldInteger ();
8:
ProduceInteger p = new
ProduceInteger (h);
9:
ConsumeInteger c = new
ConsumeInteger (h);
10:

11:
p.start();
12:
c.start();
13:
}
14:}
15:
16: class ProduceInteger extends
Thread {
17: private HoldInteger pHold;
18:
19: public ProduceInteger (
HoldInteger h )
20: {

21:
pHold = h;
22: }
23:
24: public void run()
25: {
26:
for ( int count = 0; count <
10; count++ ) {
27:
pHold.setSharednt (
count );
28:
System.out.println( El
producto puso +
29: count en sharedInt );
30:

31: //dormir durante un intervalo


aleatorio
32: try {
33:
sleep( (int) (
Math.random() * 3000 ) );
34:
}
35:
catch
(
InterruptedException e ) {
36:
System.err.println(Exception
+
e.toString() );
37:
}
38:
}
39: }
40: }

41:
42: class ConsumeInteger extends
Thread {
43:
private HoldInteger cHold;
44:
45:
public ConsumeInteger (
HoldInteger h )
46:
{
47:
cHold = h;
48: }
49:
50: public void run()

51: {
52:
int val;
53:
54:
val = cHold.getSharedInt();
55: System.out.println(El
consumidor recuper + val );
56:
57: while (val !=9) {
58: // dormir durante un intervalo
aleatorio
59: try {
60: sleep ( (int) (Math.random() *
3000 ) );

61:}
62: catch (InterruptedException e ) {
63: System.err.println ( Exception
+ e.toString() );
64: }
65:
66: val = cHold.getSharedInt();
67: System.out.println (El
consumidor recupero + val );
68: }
69: }
70: }

71:
72: class HoldInteger {
73: private int sharedInt;
74:
75: public void setSharedInt ( int
val ) { sharedInt = val;}
76:
77: public void getSharedInt() {
return sharedInt;}
78: }

El programa consiste en 4 clases:


SharedCell
(celda
compartida),
ProduceInteger
(producir
entero),
ConsumeInteger (consumir entero) y
HoldInteger (retener entero). El mtodo
main de la clase SharedCell (lnea 5)
ejemplariza el objeto HoldInteger h y lo
usa
como
argumento
de
los
constructores
de
los
objetos
ProduceInteger p y ConsumeInteger c.

A continuacin, el mtodo invoca el


mtodo start de la clase Thread para
los objetos ProduceInteger p y
ConsumeInteger c a fin de colocarlos
en el estado listo. En esencia, esto
pone en marcha ambos hilos.

La clase ProduceInteger que hereda de


Thread- consiste en la variable de
ejemplar pHold (retener p), un
constructor y un mtodo run. La
variable de ejemplar pHold se inicializa
en el constructor (lnea 21) para hacer
que se refiera al objeto HoldInteger h
que pas como argumento. El mtodo
run de la clase PruduceInteger (lnea 24)
consiste en una estructura for que itera
10 veces.

Cada iteracin del ciclo invoca al


mtodo
setSharedInt
(establecer
sharedInt) de HoldInteger con el valor
de count(cuenta), a fin de asignar ese
valor a la variable de ejemplar sharedInt
(entero
compartido)
del
objeto
compartido. A continuacin se exhibe
el valor que se pas a setSharedInt.
Despus, se invoca el mtodo sleep para
poner el objeto PruduceInteger en el
estado dormido durante un tiempo
aleatorio de 0 a 3 seg.

La clase ConsumeInteger que hereda


de Thread- consiste en al variable de
ejemplar cHold (retener c), un
constructor y un mtodo run.
La
variable de ejemplar cHold se inicializa
en el constructor (lnea 47) de modo a
que se refiera al objeto HoldInteger h
que pas como argumento. El mtodo
run de la clase ConsumeInteger (lnea
50) consiste en una estructura while que
se ejecuta hasta que lee el valor 9 de la
celda de memoria compartida.

Cada iteracin del ciclo invoca al


mtodo sleep para poner al objeto
ConsumeInteger en el estado dormido
durante un tiempo aleatorio entre 0 y 3
seg. A continuacin se invoca al
mtodo
getSharedInt
(obtener
sharedInt) de la clase HoldInteger para
obtener el valor de la variable de
ejemplar
sharedInt
del
objeto
compartido. Finalmente, se exhibe el
valor devuelto por getSharedInt.

Los mtodos setSharedInt (lnea 75) y


getSharedInt (lnea 77) de la clase
HoldInteger no sincronizan el acceso a la
variable de ejemplar sharedInt.
Idealmente, nos gustara que cada valor
producido por el objeto ProduceInteger p
fuera consumido una y slo una vez por el
objeto ConsumeInteger c. Sin embargo,
cuando estudiamos la salida vemos que los
valores 2, 4, 7 y 8 se pierden (es decir, el
consumidor nunca los ve) y los valores 5 y
6 se duplican incorrectamente (es decir, el
consumidor los recupera dos veces).

Este ejemplo demuestra claramente el


acceso a datos compartidos por parte
de hilos concurrentes debe controlarse
cuidadosamente sopena de obtener
resultados incorrectos.

A fin de resolver los problemas de


prdida de datos y duplicacin de datos
del ejemplo anterior de sincronizaremos
el acceso de los hilos productor y
consumidor concurrentes a los datos
compartidos.
Todos los mtodos
empleados por un productor o un
consumidor para acceder a los datos
compartidos
se declararan en una
palabra clave synchronized.

Cuando un mtodo declarado como


synchronized se est ejecutando en un
objeto, el objeto queda cerrado con
candado para que ningn otro mtodo
synchronized pueda ejecutarse en este
objeto al mismo tiempo.

Relacin productor/consumidor
con sincronizacin de hilos
La aplicacin muestra un consumidor
y un productor accediendo con
sincronizacin a una celda de memoria
compartida, de modo que el
consumidor slo consuma despues de
que el productor haya producido un
valor. La clase HoldInteger (lnea 74)
se redefini para este ejemplo.

Ahora esta clase contiene dos


variables de ejemplar sharedInt y
writeable (escribible)- y hemos hecho
que los mtodos setSharedInt y
getSharedInt sean synchronized. Dado
que HoldInteger ahora contiene
mtodos synchronized, los objetos de
la clase HoldInteger se consideran
monitores.

La variable de ejemplar writeable a la


que llamamos variable de condicin
del monitor- es utilizada por el
mtodo setSharedInt para determinar si
se puede escribir en la posicin de
memoria compartida, y tambin es
utilizada por el mtodo getsharedInt
para determinar si se puede leer de la
posicin de memoria compartida.

1: // Mostrar mltiples hilos


modificando un objeto compartido.
2:
//Usar sincronizacin para
asegurar que varios hilos
3: //accedan a la celda compartida
correctamente
4:
5:
6: public class Class1 {
7: public static void main (String
args[ ])
8: {

9:
10:
11:

HoldInteger h = new
HoldInteger();
ProduceInteger p = new
ProduceInteger ( h );
ConsumeInteger c = new
ConsumeInteger ( h );

12:
13:
p.start();
14:
c.start();
15: }
16: }
17:
18: class ProduceInteger extends
Thread {
19:
private HoldInteger
pHold;

20:
21: public
ProduceInteger(HoldInteger h)
22: {
23:
pHold = h;
24: }
25:
26: public void run()
27: {
28: for ( int count = 0; count<10;
count++) {
29: pHold.setSharedInt( count );
30: System.out.println ("El
productor puso" + count +

31: "en sharedInt");


32:
33: //dormir durante un intervalo
aleatorio
34: try{
35:
sleep( (int) ( Math.random()
* 3000 ) );
36:
}
37:
catch ( InterruptedException e
){
38: System.err.println("Exception" +
e.toString() );
39:
}
40:
}

41: }
42: }
43:
44: class ConsumeInteger extends
Thread {
45:
private HoldInteger cHold;
46:
47:
public ConsumeInteger (
HoldInteger h )
48:
{
49:
cHold = h;
50: }

51:
52: public void run()
53: {
54: int val;
55:
56:
val = cHold.getSharedInt();
57: System.out.println("El
consumidor recuper" + val );
58:
59: while (val !=9) {
60: // dormir durante un intervalo
aleatorio

61: try {
62. sleep ( (int) (Math.random() * 3000 )
);
63: }
64: catch (InterruptedException e ) {
65: System.err.println ( "Exception" +
e.toString() );
66: }
67:
68: val = cHold.getSharedInt();
69: System.out.println
("El
consumidor recupero" + val );
70: }

71: }
72: }
73:
74: class HoldInteger {
75: private int sharedInt;
76: private boolean writeable = true;
77:
78: public synchronized void
setSharedInt (int val)
79: {
80: while ( !writeable ) {

81:
try {
82:
wait();
83: }
84: catch (InterruptedException e )
{
85: System.err.println
("Excepcin:" + e.toString() );
86: }
87: }
88:
89: sharedInt = val;
90: writeable = false;

91: notify();
92: }
93:
94: public synchronized int
getSharedInt ()
95:{
96: while (writeable) {
97:
try{
98:
wait();
99: }
100: catch (InterruptedException e) {

101: System.err.println
("Excepcin:" + e.toString() );
102: }
103: }
104:
105: writeable = true;
106: notify();
107: return sharedInt;
108: }
109: }

La variable de ejemplar writeable es un


boolean empleado por ambos mtodos de la
clase HoldInteger. Si writeable es true,
setSharedInt puede colocar un valor en la
variable sharedInt porque sta actualmente
no contiene informacin. Por otro lado, esto
significa que getSharedInt no puede leer de
momento el valor de sharedInt. Si writeable
es false, getSharedInt puede leer un valor
de la variable sharedInt porque est contiene
actualmente informacin. Por otro lado,
esto significa que setSharedInt no puede de
momento colocar un valor en sharedInt.

Cuando el objeto ProduceInteger invoca el


mtodo setSharedint, adquiere un candado
para el objeto HoldInteger. La estructura
while de la lnea 80 prueba la variable
writeable con la condicin !writeable. si
esta condicin es true, se invoca el mtodo
wait. Esto coloca al objeto, ProduceInteger
que llam al mtodo setSharedInt en la
cola de espera para el objeto HoldInteger y
libera el candado que tena con el para que
puedan
invocarse
otros
mtodos
synchronized con el objeto.

El objeto ProduceInteger permanecer en


la cola de espera hasta que sele notifique
que puede continuar, momento en el cual
pasar al estado listo y esperar a que se
le asigne un procesador. Cuando el objeto
ProduceInteger vuelve a estar en el estado
en ejecucin, adquiere de nuevo
implcitamente el candado para el objeto
HoldInteger y el mtodo setSharedInt
contina ejecutndose en la estructura
while con el siguiente enunciado despus
del wait. No hay mas enunciados, as que
se prueba otra vez la condicin while.

Si la condicin es false, se asignar val a


sharedInt (el argumento que se pasa a
setSharedInt), se asignar false a writeable
para indicar que la memoria compartida
est llena y se invoca al mtodo notify. Si
hay un hilo de espera, el primer hilo de la
cola de espera se coloca en el estado listo
para indicar que dicho hilo ya puede
intentar otra vez su tarea (tan pronto como
se le asigne un procesador). El mtodo
notify regresa de inmediato y el mtodo
setSharedInt regresa a quien lo invoc.

Los
mtodos
getSharedInt
y
setSharedInt se implementan de forma
similar.
Cuando
el
objeto
ConsumeInteger invoca el mtodo
getSharedInt, adquiere un candado para
el objeto HoldInteger. La estructura
while de la lnea 96 prueba la variable
writeable. Si esta variable es true (es
decir, si no hay nada que consumir), se
invoca el mtodo wait.

Esto coloca al objeto ConsumeInteger


que llam al mtodo getSharedInt en la
cola de espera para el objeto
HoldInteger y libera el candado que
tena con l para que puedan invocarse
otros mtodos synchronized con el
objeto. El objeto ConsumeInteger
permanecer en la cola de espera hasta
que se le notifique que puede continuar,
momento en el cual pasar a estar listo
y esperar a que se le asigne un
procesador.

Cuando el objeto ConsumeInteger


vuelve a estar en el estado de ejecucin,
vulve a adquirir el candado para el
objeto HoldInteger y el mtodo
gatSharedInt contina ejecutndose en
la estructura while con el siguiente
enunciado despus del wait. No hay
ms enunciados, as que se prueba otra
vez la ejecucin while. Si la condicin
es false, se asigna true a writeable para
indicar que la memoria compartida ya
esta vaca y se invoca el mtodo notify.

Si hay algn hilo de espera, el primer hilo


de espera se coloca en el estado listo para
indicar que dicho hilo ya puede intentar
otra vez su tarea (tan pronto como se le
asigne un procesador). El mtodo notify
regresa de inmediato y el valor de
sharedInt se devuelve a quien invoc
getSharedInt.
Si estudiamos la salida, veremos que todos
los enteros producidos consumen una sola
vez; no se pierde ni duplica ningn valor.

Relacin productor/consumidor:
El buffer circular
El programa accede correctamente a los
datos compartidos, pero tal vez no tenga
un rendimiento ptimo. Dado que los
hilos
se
estn
ejecutando
asincrnicamente, no podemos predecir
sus relativas velocidades.
Si el
productor desea producir ms deprisa de
lo que el consumidor puede consumir,
no podr hacerlo.

Si queremos que el productor contine


produciendo podemos usar un buffer
circular que tiene suficientes celdas extras
para manejar la produccin extra. El
programa muestra un productor y un
consumidor accediendo a un buffer
circular (en este caso un arreglo
compartido
de
5
celdas)
con
sincronizacin para que el consumidor
slo consuma un valor cuando haya uno o
ms valores en el arreglo, y el productor
slo produzca un valor cuando haya una o
ms celdas disponibles en el arreglo.

Este programa se implementa como una


applet que enva sus salidas a un rea de
texto. El mtodo start de la clase
SharedCell crea los objetos HoldInteger,
ProduceInteger y ConsumeInteger. El
objeto HoldInteger h se pasa a un objeto
TextArea en la que se exhibir la salida
del programa.

Una vez ms, los principales cambios en


este ejemplo ataen a la definicin de la
clase HoldInteger. La clase ahora
contiene 6 variables de ejemplar:
sharedInt es un arreglo de enteros de 5
elementos que se usa como buffer
circular, writeable indica si un productor
puede o no escribir en el buffer circular,
readable (leble) indica si un consumidor
puede o no leer del buffer circular,
readLoc (posicin de lectura) indica la
posicin actual de la que un consumidor

puede leer el siguiente valor, writeLoc


(posicin de escritura) indica la
siguiente posicin en la que el productor
puede colocar un valor y output (salida)
es el TextArea empleado para exhibir
las salidas.

El mtodo setSharedint realiza las


mismas tareas con unas cuantas
modificaciones. Cuando la ejecucin
continua en la lnea 105 despus del
ciclo while, el valor producido se coloca
en el buffer circular en la posicin
writeLoc. A continuacin se asigna true
a readable por que hay por lo menos un
valor en el buffer que se debe leer. El
valor producido y la celda donde se
coloco el valor se anexan al rea de
texto con el mtodo appendText.

Luego se actualiza writeLoc para la


siguiente llamada a setSharedInt. La
salida en el rea de texto se contina con
los valores actuales de writeLoc y
readLoc y los valores que estn en el
buffer circular. Si writeLoc es igual a
readLoc, quiere decir que el buffer
circular de momento est lleno, por lo
que se asigna false a writeable y se
exhibe la cadena BUFFER LLENO. Por
ltimo, se invoca el mtodo notify para
colocar el siguiente hilo en espera en el
estado listo.

El mtodo getSharedInt tambin realiza


las mismas tareas en este ejemplo, con
unas cuantas modificaciones menores.
Cuando la ejecucin continua en la lnea
139 despus del ciclo while, se asigna
true a writeable por que hay por lo
menos una posicin desocupada en el
buffer, en la cual puede colocarse un
valor. A continuacin se asigna a val el
valor que est en la posicin readLoc
del buffer circular.

El valor consumido y la celda de la cual


se ley el valor se anexan al rea de
texto con el mtodo appendText. A
continuacin, se actualiza readLoc para
la siguiente llamada al mtodo
getSharedInt. La lnea de salida en el
rea de texto se contina con los
valores actuales de writeLoc y readLoc,
as como los valores que estn en el
buffer circular.

Si readLoc es igual a writeLoc, quiere


decir que el buffer circular de
momento est vaco, por que se asigna
false a readable y se exhibe la cadena
BUFFER VACO, por ltimo se invoca
el mtodo notify para colocar el
siguiente hilo en espera en el estado
listo.

En el programa ampliamos las salidas


para incluir los valores actuales de
writeLoc y readLoc. Adems se exhibe
el contenido actual del buffer sharedInt.
Los elementos del arreglo sharedInt se
inicializaron en 9 para que sea ms fcil
ver como se inserta cada valor en el
buffer. Observe que, despus de colocar
el 5 valor en el 5 elemento del buffer, el
6 se valor se inserta al principio del
arreglo, logrndose as el efecto de buffer
circular.
Sacamos de las clases
ProduceInteger y ConsumeInteger todos
los enunciados de salida.

Hilos daemon
Un hilo daemon es un hilo que se ejecuta
en beneficio de otros hilos. Los hilos
daemon se ejecutan en segundo plano (es
decir, cuando hay tiempo de procesador
disponible que de otra manera se
desperdiciara). El recolector de basura
es un hilo daemon. Los hilos no daemon
son hilos de usuario convencionales.
Designamos a un hilo daemon con la
llamada de mtodo
setDaemon (true);

Si el argumento es false, quiere decir que


no es un hilo daemon. Un programa
puede incluir una mezcla de hilos daemon
y no daemon. Cuando slo quedan hilos
daemon en un programa, el programa
termina. Si un hilo va a ser daemon, se
debe asignar como tal antes de que se
invoque su mtodo start, de lo contrario se
lanzar una excepcin de estado de hilo
no
permitido
(IlegalthreadStateException). El mtodo
isDaemon devuelve true si un hilo es
daemon, y false si no lo es.

Interfaz Runnable
C++ apoya la herencia mltiple, en la que
una subclase puede heredar de ms de una
superclase. La herencia mltiple es una
capacidad muy potente pero es empleo y
adolece de problemas de ambigedad y
rendimiento. Java no reconoce la herencia
mltiple. Esta decisin es congruente con la
omisin, por parte de Java, de varios otros
aspectos complejos de C++. Lo que s
reconoce Java es el concepto de interfaces,
un esquema ms sencillo que ofrece
algunas de las ventajas clave de la herencia
mltiple.

Hasta aqu hemos extendiendo la clase


Thread para crear nueva clases que
apoyan el multihilado. Supeditamos el
mtodo run para especificar las tareas
que se deben ejecutar de forma
concurrente.
Un problema con este esquema es que
crea algunas relaciones ms bien
extraas, pues con extend en realidad
estamos heredando, lo que implica que
un objeto de subclase es un objeto de
su superclase.

Si queremos manejar multihilado en una


clase derivada de alguna clase distinta de
Thread
implementamos
(con
implements) la interfaz Runnable
(ejecutable) en esa clase. La clase
Thread misma implementa la interfaz
Runnable tal como se expresa en la
cabecera de la clase:
public class Thread extetends Object
implements Runnable

La implementacin de la interfaz
Runnable nos permite tratar nuestra
nueva clase como un objeto Runnable
(as como heredar de una clase nos
permite tratar nuestra subclase como un
objeto de su superclase). Al igual que
cuando derivamos de la clase Thread, el
cdigo que controla el hilo se coloca en
el mtodo run.

Creamos un hilo con la nueva clase


pasando al siguiente constructor de la
clase Thread:
public
Thread
(Runnable
objetoEjecutable)
una referencia a un objeto de la clase
que implementan la interfaz Runnable.
El constructor Thread registra el mtodo
run del objetoEjecutable como el
mtodo que se invocar cuando el hilo
inicie su ejecucin.

El constructor:
public
Thread
(Runnable
objetoEjecutable, String nombreHilo)
construye un Thread con el nombre
nombreHilo y registra el mtodo run de
su primer argumento (llamado aqu
objetoEjecutable) como el mtodo que
se invocar cuando el hilo comience a
ejecurtarse.

El programa demuestra una applet que


implementa la interfaz Runnable. La
clase de applet RandomCharacters
(caracteres aleatorios) exhibe 3 campos
de texto y 3 botones. Se asocia un hilo
de ejecucin individual a cada par de
campo de texto y botn. La applet
tambin define el String alphabet
(alfabeto) que contiene las letras de la A
a la Z. Esta cadena esta compartida por
los 3 hilos.

El mtodo start de la applet (lnea 38)


ejemplariza 3 objetos Thread e
inicializa cada uno con this- es decir,
el objeto applet- y luego invoca el
mtodo start de la clase Thread para
cada Thread, con lo que los 3 hilos
pasan al estado listo.

El mtodo run (lnea 95), contiene un


ciclo infinito. En cada iteracin del
ciclo, el hilo duerme durante un tiempo
aleatorio entre 0 y 5 segundos. A
continuacin se escoge un carcter al
azar de la cadena alphabet.
El
enunciado:
executingthread
Thread.currentThread().getName();

usa el mtodo currentThread (hilo


actual) de Thread para determinar cul
objeto Thread se est ejecutando
actualmente, y luego usa el mtodo
getName para obtener su nombre. La
cadena de vuelta por getName se usa en
la estructura if/else anidada para
escoger el campo de texto en el que se
exhibira el carcter.

Si el usuario hace clic en el botn


Susp./Reanudar que est junto a un
campo de texto en particular, se invoca el
mtodo action (lnea 59). El mtodo
action determina cualquier botn gener el
evento y luego determina si el hilo
correspondiente est suspendido probando
una de las variables boolean suspend1,
suspend2 o suspend3 (una para cada hilo).
Si la variable boolean apropiada es true, se
invoca el mtodo resume del hilo y se
asigna false a la variale booleana.

En caso contrario, se invoca el mtodo


suspend del hilo, se exhibe la cadena
suspendido en el campo de texto de ese
hilo y se asigna true a la variable booleana.
Se incluye el mtodo stop en la applet para
detener la ejecucin de los 3 hilos si el
usuario sale de la pgina de Web en la que
esta applet reside. Si el usuario regresa a la
pgina Web, los 3 hilos se ejemplarizarn
otra vez que porque cuando se vuelve a
visitar la pgina de Web se invoca el
mtodo start de la applet.

CAPTULO VIII
ANIMACIN, IMGENES,
SUBPROCESOS Y
SONIDOS

8.1

INTRODUCCIN

En dcadas atrs todos los que ingresamos al


campo de las computadoras estbamos
interesados primordialmente en usar las
computadoras
para
realizar
clculos
aritmticos a alta velocidad. Sin embargo,
conforme el campo de la computacin
evoluciona nos estamos comenzando a dar
cuenta de que las capacidades de
manipulacin de datos de las computadoras
ya tienen una importancia equiparable. Lo
que ms llama la atencin de Java son los
multimedia: el empleo de sonido, imgenes,
grficos y video para hacer que la
aplicaciones cobren vida.

La mayor parte de los lenguajes de


programacin no cuenta con capacidades
multimedia integradas, pero Java,
gracias a los paquetes de clases que
forma parte integral del mundo de la
programacin en Java, ofrece amplios
recursos multimedia que le permitirn
comenzar a crear potentes aplicaciones
multimedia de inmediato.

8.2 CARGADO, EXHIBICIN


Y ESCALADO DE IMGENES

La animacin en Java involucra dos


pasos bsicos: la construccin de un
cuadro de animacin y cmo pedirle a
Java que lo dibuje. Estos pasos se repiten
para crear la ilusin de movimiento.
El mtodo paint ( ) es llamado en el
momento en que un applet necesita
dibjarse; cuando se dibuja por primera
vez, cuando la ventana que lo contiene se
mueve o cuando otra ventana es colocada
sobre el applet.

Se le puede indicar a Java que vuelva a


dibujar un applet cuando lo requiera.
Para cambiar la apariencia de lo que
est en la pantalla, es necesario
construir la imagen o cuadro que desea
dibujar y despus se le pide a Java que
lo dibuje. Si se realiza esto de forma
repetida y a una velocidad suficiente,
se logra el efecto de la animacin
dentro del aplet. Esto es todo lo que
sucede en una animacin.

El mtodo paint( ) es responsable solo del


cuadro actual de la animacin. El cuadro se
construye al definir variables para que las
use paint( ) , crea los objetos Font o Color
que el mtodo paint los utilice, despus se
invoca al mtodo repaint( )el cual es un
disparador que hace que Java llame a
paint( ) y el cuadro se dibuje.
Ser necesario utilizar los mtodos start( )
y stop( ) para iniciar del aplet y detenerla
cuando se salga de la pgina que lo
contiene.

8.3 SUBPROCESOS

Cualquier cosa que realiza en el


programa Java que se ejecute
continuamente y ocupe mucho tiempo
de procesamiento debe ejecutarse en un
subproceso, la animacin, por ejemplo,
debe ejecutarse en un subproceso.

Para lograr la animacin es necesario


utilizar el mtodo start( ) para iniciar un
subproceso, despus se realiza todo el
proceso de animacin dentro de un
mtodo run( ) del subproceso. Esto
permite a la animacin ejecutarse por si
misma sin interferir con otras partes del
programa.

Mientras ms grandes sean los


programas y ms cosas realicen, es
necesario ejecutar subprocesos. En un
programa regular de un solo
subproceso, el programa comienza su
ejecucin, corre su cdigo de
inicializacin llama a los mtodos o
procedimientos y continua ejecutndose
o procesndose hasta que se completa o
el programa se sale del subproceso.
Este programa se ejecuta en un solo
subproceso.

Al utilizar subprocesos en Java se


pueden crear partes de un applet que se
ejecuten de manera satisfactoria sin
interferir entre ellos, en sus propios
subprocesos. Dependiendo de cuntos
subprocesos se tengan, eventualmente se
puede sobrecargar el sistema de forma
que su ejecucin sea mas lenta, pero de
todas formas continuarn corriendo de
forma independiente.

Crear applets que utilicen subprocesos


es muy fcil. De hecho, muchas de las
cosas bsicas necesarias para usar
subprocesos
son
simplemente
secciones de cdigo que se pueden
copiar y pegar de un applet a otro.

Hay
cinco
modificaciones
necesarias para crear un applet que
utilice subprocesos:
Cambiar la firma del applet para
incluir la palabra Runnable
Incluir una variable de instancia para
almacenar el subproceso de este
applet.
Crear un mtodo start ( ) que no
haga nada ms que crear un
subproceso e iniciar la ejecucin.

Crear un mtodo stop ( ) para


detener el subproceso.

Crear un mtodo run ( ) que


contenga el cdigo actual que
controle el applet.

El primer cambio es en la primera lnea


de definicin de clase. Se tiene:
public class MyAppletClass extends
java.applet.Applet {
...}
Es necesario cambiarla por la siguiente:
public class MyAppletClass extends
java.applet.Applet implements Runnable
{
...
}

Esto incluye el soporte para la interfaz


Runnable en el applet. Las interfaces son una
forma de coleccionar nombres de mtodos
comunes a diferentes clases, los cuales
pueden despus mezclarse e implementarse
dentro de las distintas clases que necesitan
implementar esos comportamientos. Aqu, la
interfaz Runnable define el comportamiento
que el applet necesita para poder ejecutar un
subproceso; en particular le da una definicin
predeterminada para el mtodo run( ).Al
implementar Runnable, se indica a otros que
pueden llamar a las instancias del mtodo
run ( ).

El segundo
paso es agregar una
variable de instancia para almacenar el
subproceso de ese applet. Puede tener
cualquier nombre, es una variable de
tipo Thread (la cual es una clase de
java.lang, por lo tanto no es necesario
importarla):
Thread runner;

El tercer paso es agregar un mtodo


start() o modificar el existente para que
no haga nada excepto crear un nuevo
subproceso e iniciar su ejecucin. Aqu
est un ejemplo del mtodo start( ):
public void star( ) {
if (runner == null) {
runner = new Thread(this);
runner.start();
}
}

Si se modifica start() para no hacer


nada excepto producir un subproceso,el
cdigo que manipula el applet va
dentro de un mtodo run(), el cual tiene
esta apariencia:
public void run(){
//lo que realmente hace el
applet
}

El mtodo run()en realidad se sobrepone


a la versin predeterminada de run(), la
cual se agrego al incluir la interfaz
Runnable. Run() es uno de esos
mtodos estndar, como start() u paint(),
que se sobrepone en las clases para
obtener el conocimiento necesario.

El mtodo run() puede contener


cualquier cosa que se desee ejecutar en
su subproceso separado: cdigo de
inicializacin, el ciclo real para el
applet, o cualquier otra aplicacin que
necesite ejecutarse en su propio
subproceso. Tambin se puede crear
nuevos objetos y llamar mtodos desde
run(), estos se ejecutaran dentro del
subproceso. As que run() es el
verdadero corazn del applet.

Por ltimo, ahora que


se tienen
subprocesos en ejecucin y un mtodo
strat() para iniciarlos, se debe aadir el
mtodo stop() para suspender la
ejecucin de ese subproceso (y, por
consiguiente, cualquier cosa que el
applet haga en ese momento) cuando el
lector deje esa pgina. Este mtodo, al
igual que start(), contiene por lo
general:

public void stop() {


if (runner != null) {
runner.stop();
runner = null;
}
}

El mtodo stop( ) aqu hace dos trabajos:


detiene la ejecucin del subproceso y define
las variables de ejecucin de runner en null.
Asignando la variable a null hace que el
objeto Thread est disponible para el colector
de basura y de esta manera el applet pueda
ser removido de la memoria despus de
cierto tiempo. Si el lector regresa a esta
pgina y a este applet, el mtodo start( ) crea
un nuevo subproceso e inicia el applet de
nuevo. Con estas cinco modificaciones
bsicas se tiene un applet con un buen
comportamiento para ejecutarse en su propio
subproceso.

Cmo ponerlo a trabajar


Explicar
cmo
hacer
una
animacin en Java es ms complicado
que
simplemente
mostrar
su
funcionamiento en cdigo. Un ejemplo
ayudar a hacer ms clara la relacin
que hay entre todos estos mtodos. El
siguiente applet muestra un reloj
digital animado, que usa las tcnicas
bsicas de animacin para mostrar la
fecha y hora, actualizndola cada
segundo:

import java.awt.Graphics;
import java.awt.Font;
import java.util.Calendar;
import
java.util.GregorianCalendar;
public class Class1 extends
java.applet.Applet
implements Runnable{
Font theFont= new
Font("TimesRoman",
Font.BOLD,24);

Thread runner;

public void start () {


if (runner == null){
runner=new
Thread(this);
runner.start();
}

public void stop() {


if (runner !=null){
runner.stop();
runner=null;
}
}

public void run(){


while (true){
repaint();
try
{Thread.sleep(1000); }
catch
(InterruptedException e) {}
}
}

public void paint(Graphics g ){


theDate=new
GregorianCalendar();
g.setFont(theFont);
g.drawString(""+
theDate.getTime(),10,50);
}
El applet anterior utiliza los mtodos
paint(), repaint(), start() y stop().
Tambin utiliza subprocesos.

La animacin es un buen ejemplo del


tipo de tareas que necesita su propio
subproceso. Se considera el ciclo infinito
while() del applet DigitalClock. Si no
utilizara subprocesos,
while() se
ejecutara
en
el
subproceso
predeterminado del sistema Java, el cual
tambin es responsable de manejar las
imgenes en la pantalla, interactuar con
las entradas del usuario, como clics del
ratn, y mantener internamente todo
actualizado.

Desafortunadamente si se ejecuta el
ciclo while() en el subproceso del
sistema principal, ste monopolizar
los recursos de Java y evitara que se
realice otras actividades. No se vera
nada en la pantalla porque Java estara
esperando que el ciclo while()
terminara para hacer otra cosa.

Se definen dos variables de instancia


bsicas: theFont y theDate, las cuales
contienen los objetos que representan la
fuente
y
la
fecha
actual,
respectivamente. Los mtodos start() y
stop() inician y terminan un subproceso;
la mayor parte del trabajo del applet se
encuentran en el mtodo run()

Dentro del mtodo run() es donde se


lleva a cabo realmente la animacin. En
el ciclo while() de este mtodo, dado
que la prueba siempre regresa el valor
true, el ciclo nunca termina. Un cuadro
de la animacin se construye dentro del
ciclo while.

Lo primero que sucede en el ciclo es


que la instruccin repaint() se llama
para volver a dibujar el applet. Las
lneas try {Thread.sleep(1000) , catch
(InterruptedException e) {} lo nico
que hacen es una pausa de 1000
milisegundos (un segundo) antes de
que repita el ciclo. El mtodo sleep(),
parte de la clase Thread(), es la que
hace la pausa.

Sin un mtodo sleep() especfico, el


applet podra correr tan rpido como
fuera posible; este mtodo controla de
una manera exacta la velocidad de
ejecucin de la animacin.
Las
funciones try y catch habilitan la
administracin de errores, si es que
suceden, estas funciones manejan las
excepciones.

En el mtodo paint() se crea una nueva


instancia de la clase GregorianCalendar
para almacenar la fecha y hora actuales.
Este nuevo objeto es asignado a la variable
de instancia theDate. Se define el tipo de
fuente utilizando el valor de la variable
theFont, y la fecha es desplegada en la
pantalla llamando al mtodo getTime() de
la clase GregorianCalendar para mostrar la
fecha y la hora como una cadena. Cada vez
que se llama a paint(), se crea un nuevo
objeto theDate para almacenar la fecha
actual.

Todas las clases que necesiten subprocesos


deben incluir la interfaz Runnable. Otra
variable de instancia definida para esta
clase es runner del tipo Thread, la cual
almacenar el subproceso para este applet.
Los mtodos start() y stop() slo crean y
destruyen subprocesos. Estas definiciones
de mtodo pueden ser exactamente las
mismas de una clase a otra porque todo lo
que hacen es proporcionar
la
infraestructura de los subprocesos. Por
ltimo la mayora del trabajo del applet se
realiza dentro del mtodo run().

8.4 REDUCCIN DEL


PARPADEO EN UNA
ANIMACIN

Cuando se ejecuta el programa del reloj


digital, de vez en cuando hay un molesto
parpadeo en la animacin. No hay error
en el programa; de hecho, el parpadeo es
un efecto secundario de la creacin de
animaciones en Java. Debido a que esto
es realmente molesto, implementaremos
formas de reducirlo para que las
animaciones se ejecuten limpiamente y
se vean mejor en la pantalla.

El parpadeo y cmo evitarlo


El parpadeo es causado por la forma en
que Java pinta y vuelve a pintar cada
cuadro de un applet. Se defini que
mtodo repaint() hace un llamado a
paint(), esto no es del todo cierto. Una
llamada a paint() ocurre como una
respuesta a repaint(), aunque lo que est
sucediendo exactamente es lo siguiente:

1.

La llamada a repaint() resulta en


una llamada al mtodo update().
2. El mtodo update() limpia la
pantalla de cualquier contenido
que
hubiera y luego llama a paint().
3. El mtodo paint() dibuja el
contenido del cuadro actual.

La llamada a update() es la que


ocasiona el parpadeo de la animacin.
Debido a que la pantalla es limpiada
entre cuadros, las partes de la pantalla
que no cambian alternan rpidamente
entre dibujar y limpiar, lo que
ocasiona el parpadeo. Hay dos formas
principales para evitar el parpadeo en
sus applets:

Sobreponer el mtodo update() ya


sea para no limpiar toda la
pantalla o para limpiar
nicamente
la parte que
cambi.

Sobreponer tanto a update() como


a
paint() para utilizar el doble
bfer.

La tcnica de doble bfer involucra


dibujar una superficie de grficos fuera
de la pantalla para despus copiar la
superficie completa a la pantalla.

Cmo sobreponer update()


La causa del parpadeo se encuentra en
el mtodo update(). Para reducirlo hay
que sobreponer este mtodo. Se muestra
lo que la versin predeterminada de
update() realiza (proviene de la clase
Component la cual es parte del AWT,
que es una de las superclases de la clase
applet.):

Public void update(Graphics g) {


g.setColor(getBackground());
g.fillRect(0,0, width, height);
g.setColor(getForeground());
paint(g);
}
Bsicamente, el mtodo update() borra
la pantalla (rellena el rectngulo que
limita al applet con el color del fondo),
fija las cosas de regreso a la normalidad
y llama al mtodo paint().

Solucin 1: no limpiar la pantalla


La primera solucin para reducir el
parpadeo es no limpiar la pantalla. Esto
funciona slo para algunos applets. Aqu
esta un ejemplo de este tipo, en el cual
se imprime una sola cadena en la
pantalla, pero esta cadena se presenta en
colores que se desvanecen entre si en
forma dinmica, este applet parpadea
terriblemente cuando se ejecuta:

import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
public
class
Class1
extends
java.applet.Applet
implements Runnable{
Font f= new Font("TimesRoman",
Font.BOLD,48);
Color colors[]= new Color[50];
Thread runner;

public void start () {


if (runner == null){
runner=new
Thread(this);
runner.start();
}
}

public void stop() {


if (runner !=null){
runner.stop();
runner=null;
}
}

public void run(){


float c = 0;
for (int i=0; i<colors.length; i+
+){
colors[i]=
Color.getHSBColor(c, (float)1.0,
(float)1.0);
c += .02;
}

int i =0;
while (true){
setForeground(colors[i]);
repaint();
i++;
try {Thread.sleep(200); }
catch
(InterruptedException e) {}
if (i==colors.length) i=0;
}

public void paint(Graphics g ){


g.setFont(f);
g.drawString("Observa los
colores",15,50);
}
}

Se define una variable de instancia


llamada colors, el cual es un arreglo de
50 elementos. Cuando el applet inicia,
la primera tarea que hace en el mtodo
run() es llenar ese arreglo con objetos
Color. Al crear todos los colores con
anticipacin puede dibujar el texto con
ese color, de uno en uno; es ms fcil
precalcular todos los colores a un
tiempo. Se escogi arbitrariamente el
nmero 50 como el nmero de colores
que se utilizarn; de igual modo se
pueden utilizar ciclos de 20 a 250
colores.

Para crear los diferentes objetos Color, se


utiliza un mtodo de esa clase llamado
getHSB- Color ( ), en lugar de utilizar
new con varios colores RGB. El mtodo
de clase getHSBColor ( ) crea un objeto
Color basado en valores para tinte
saturacin y brillo, en lugar del estndar
rojo, verde y azul. HSB (Hue,
Saturation,brigtness) es simplemente una
forma diferente de ver los colores. Al
incrementar el valor del tinte y mantener
la saturacin y el brillo constantes, se
puede crear un rango de colores sin tener
que conocer el valor RGB de cada uno.

Para crear la animacin, el applet realiza


un ciclo a travs del arreglo de colores,
al definir el color de primer plano para
cada objeto y llamar a repaint ( ).
Cuando llega al final del arreglo, inicia
una nueva, por lo que el subproceso se
repite una y otra vez indefinidamente.

El parpadeo se produce porque cada vez


que el applet se pinta hay un momento
en que se limpia la pantalla. En vez que
el texto realice su ciclo limpiamente de
rojo a rosa o morado, va de rojo a gris,
de rosa a gris, de morado a gris, y as
sucesivamente; lo cual no se ve nada
bien.

Ya que la limpieza de la pantalla es lo que


ocasiona el problema, la solucin es
sobreponer el mtodo update ( ) y eliminar
la parte en donde la pantalla se limpia,
aunque en realidad no necesita limpiarse
pues nada cambia excepto el color del
texto.
Con
la
eliminacin
del
comportamiento de limpieza de update ( ),
todo lo que este mtodo necesita es llamar
a paint ( ). Aqu est la apariencia del
mtodo update ( ) en este applet ( puede
agregar el mtodo paint ( ), con esto no hay
ms parpadeo.

public void update (Graphics g ) {


paint (g) ;
}

8.5

RECUPERAR Y
UTILIZAR
IMGENES

La manipulacin bsica de imgenes en


Java es fcil. La clase Image, en el
paquete java.awt, proporciona los
mtodos abstractos para representar el
comportamiento comn de la imagen, y
los mtodos especiales definidos en
Applet y Graphics proporcionan todo
lo necesario para cargar y desplegar las
imgenes en las applets tan fcilmente
como dibujar un rectngulo.

Cmo recuperar imgenes


Para desplegar una imagen, primero se
debe de cargar de Web a el applet. Las
imgenes se almacenan como archivos
separados del archivo de clase Java, as
que se debe indicar a Java dnde
encontrarlas.

La clase Applet proporciona un mtodo


llamado getImage ( ), el cual carga una
imagen y crea de manera automtica una
clase Image. Para utilizarla, hay que
importar la clase java.awt.Image con el
programa y darle getImage ( ) la URL de
la imagen que desea. Hay dos formas de
hacer esto:

El mtodo getImage ( ) con un solo


argumento (un objeto de tipo URL)
recupera la imagen de la URL
dada.
El mtodo getImage ( ) con dos
argumentos: la URL base (tambin
un objetoURL) y una cadena que
representa la ruta o nombre de
archivo de la imagen actual
(relativa a la base).

La segunda forma es la que se


utiliza
con ms
frecuencia. La clase
Applet
tambin proporciona dos
mtodos
que ayudarn con el
argumento
URL base para
getImage ( ) :

El mtodo getDocumentBase ( )
deuelve un objeto URL que
representa el directorio del archivo
HTML que contiene este
applet.
Por ejemplo, si el archivo
HTML
est en http://www.
Myserver.com/
htmlfiles/javahtml/, el mtodo
getDocumentBase( ) devolver
un
URL apuntando a esa
direccin.

El mtodo getCodeBase ( )
devuelve una cadena que
representa el directorio en el cual se
almacena el applet (el cual
puede
ser o no el mismo directorio en que
se encuentra el
archivo HTML
dependiendo de si est el atributo
CODEBASE definido en <APPLET>
o no.

El uso de getDocumentBase ( ) o
getCodeBase ( ) depende de si las
imgenes son relativas a los archivos
HTML o sin son relativas al archivo de
clase Java.Se utiliza el que convenga
ms
a
la
situacin;
utilizar
getDocumentBase ( ) o getCodebase ( )
permite cambiar los archivos HTML y
los applets, al mismo tiempo deja que
Java encuentre sus imgenes.

Aqu estn algunos ejemplos de


getImage ( ) : El primero llama al
mtodo getImage( ) el cual recupera el
archivo en una direccin URL
especfica
(
http://www.server.com/file
s/image.gif)
. Si cualquier parte de ese URL cambia,
se tendr que volver a compilar para
que el applet Java considere la nueva
ruta:

Image img = getImage(


new
URL(http:/www.server.com/files/image
.gif));
De esa otra forma, el archivo
image.gift est en el mismo directorio
del archivo HTML para referirse a este
applet:
Image
img
getImage(getDocumentBase(
Image.gif)

=
),

De manera similar el archivo image.gif


se encuentra en el mismo directorio del
applet:

Image img = getImage(getCodeBase( ),


Image.gif)

Si existen muchos archivos de imagen,


es comn ponerlos todos en su propio
subdirectorio. El siguiente ejemplo de
getImage( ) busca el archivo image.gif
en el directorio images, el cual se
encuentra en el mismo directorio del
applet Java.
Image
img
getImage(getCodeBase(
Images/image.gif)

=
),

Si getImage ( ) no puede encontrar el


archivo indicado devuelve un nulo y
el mtodo drawImage ( ) no dibujar
nada o marque un error.

Cmo dibujar imgenes


Si se desea desplegar la imagen como
si fuera un texto o un rectngulo, la clase
Graphics proporciona dos mtodos para
hacer
esto,
ambos
se
llaman
drawImage().
La primera versin de drawImage()
utiliza 4 argumentos: dibuja la imagen
en
sus
dimensiones
originales
comenzando en la esquina superior
izquierda indicadas por las coordenadas
x y y.

La segunda versin de este mtodo utiliza 6


argumentos: la imagen a dibujar, las
coordenadas x y y de esquina superior
izquierda, el ancho y largo de un cuadro
delimitador y this. Si el cuadro delimitador
es ms grande o ms chico que en tamao
de la imagen,
ste se ajustar
automticamente a las dimensiones del
cuadro. Se pueden reducir o ampliar las
imgenes para que ocupen el espacio que
se desea por medio de los argumentos
extras, puede haber cierta deformacin en
la imagen al modificar su tamao.

Para manejar imgenes a escala es


importante conocer su tamao real para
que de esta manera se pueda reducir o
aumentar a un porcentaje especfico
evitando de esta forma cualquier
distorsin que se pudiera dar. Los
mtodos getWihdth() y getHeight()
definidos en la clase Image
proporcionan informacin acerca de la
escalas.

Ambos tienen un solo argumento, una


instancia de ImageObserver, el cual es
usado para rastrear el cargado de la
imagen.La mayora de las veces,
simplemente puede utilizar this como
argumento de los mtodos getWidth() y
getHeight().

Por ejemplo, si almacena la imagen de


una catarina en una variable llamada
bugimg, la siguiente lnea devolver el
ancho de la imagen en pixeles:
theWidth= bugimg. getWidth(this);

El listado siguiente muestra el uso de la


imagen de una catarina, dibujndola a
diferentes escalas.
import java.awt.Graphics;
import java.awt.Image;
public
class
Class1
extends
java.applet.Applet{
Image bugimg;
public void init() {
bugimg=getImage
(getCodeBase(),"images/ladybug.gif");
}

public void paint(Graphics g) {


int
iwidth=bugimg.getWidth(this);
int
iheight=bugimg.getHeight(this);
int xpos = 10;
// 25%
g.drawImage(bugimg, xpos,
10,iwidth / 4, iheight / 4, this);

// 50%
xpos += (iwidth / 4) + 10;
g.drawImage(bugimg, xpos,
10,iwidth / 2, iheight / 2 ,this);
// 100%
xpos += (iwidth / 2) + 10;
g.drawImage(bugimg, xpos,
10, this);

// 150% x 25% y
g.drawImage(bugimg, 10,
iheight + 30,(int)(iwidth * 1.5),
iheight / 4, this);

}
}

Observadores de imagen
This aparece como argumento tanto en
getWidth() como en getHeight(). Su uso
es pasar un objeto que funcione como
un ImageObserver (esto es, un objeto
que implemente la interaccin con
ImageObserver).

Los observadores de Image son usados


para vigilar el proceso de una imagen
en el proceso de carga y para tomar
decisiones
dependiendo de si la
imagen esta
cargada completa o
parcialmente. Por ejemplo, el applet
podra detenerse hasta que se carguen
todas las imgenes y estn listas, o
desplegar un mensaje en la pantalla de
cargando..., o hacer algo mientras
espera.

La clase Applet, de la cual hereda el


applet, contiene un comportamiento
predeterminado para la observacin de
imgenes (la cual hereda de la superclase
Component) que debe funcionar en la
mayora de los casos (aqu el argumento
this en los mtodos drawImage(),
getWidth() y getHeight()).
El nico
motivo por el cual utilizar un argumento
distinto es si se desea ms control sobre lo
que har el applet cuando una imagen sea
parcialmente cargada, o si est rastreando
la
carga
de
muchas
imgenes
asncronamente.

8.6 COMO
CREAR
ANIMACIN USANDO
IMGENES

La creacin de animaciones con


imgenes es muy parecida a la creacin
de animaciones con las fuentes, colores
o formas, se utilizaran los mismos
mtodos y procedimiento para pintar,
volver a pintar y reducir el parpadeo.
La nica diferencia es que se tiene una
pila de imgenes a secuenciar en lugar
de mapas de bits a mano.

La mejor forma de aprender el uso de


imgenes para hacer animaciones es con
un ejemplo. Se muestra una animacin
extensiva sobre un pequeo gato
llamado Neko.
Un ejemplo: Neko

Neko es una pequea animacin/juego


de Macintosh escrito y dibujado por
Kenji Gotoh en 1989. Neko en japons
significa gato, y la animacin es de
un pequeo gato que persigue el
puntero del ratn en la pantalla, se
duerme, se rasca y generalmente hace
cosas graciosas. El programa Neko ha
sido portado a prcticamente todas las
plataformas posibles, adems de
reescribirse como un popular protector
de pantalla.

Para este ejemplo, se implementar una


pequea animacin fundamentada en
los grficos originales de Neko. A
diferencia del original, en el cual el gato
es autnomo (puede sentir las orillas de
las ventanas, voltearse y correr en
diferente direccin), este applet
simplemente hace que Neko entre
corriendo desde el lado izquierdo de la
pantalla, se detenga en la mitad,
bostece, se rasque una oreja y despus
salga por la derecha.

Paso 1: coleccione las imgenes


Antes de comenzar a escribir el cdigo
Java para crear la animacin se deben
tener todas las imgenes que la forman..
Para este ejemplo, se almacenan las
imgenes
en
un
directorio
apropiadamente llamado images.

Paso 2: Organice y cargue las imgenes


en el Applet
La idea bsica es que se tengan un
conjunto de imgenes y se desplieguen
rpidamente una por una para que den la
apariencia del movimiento. La manera ms
fcil de hacer esto en Java, es almacenar
las imgenes en un arreglo de la Image y
tener una variable especial para rastrear la
imagen actual. Conforme itere en las
posiciones del arreglo (utilizando un ciclo
for) puede cambiar el valor de la imagen
actual cada vez.

Para el applet Neko, se crearan


variables de instancia para implementar
ambas cosas: un arreglo que almacene
las imgenes, llamado nekopics; y la
variable de tipo Image llamada
currenttimg que almacena la imagen
desplegada.
Image nekopics[] = new image [9];
Image currenttimg;

El arreglo de imgenes tiene 9


posiciones, al igual que las imgenes de
Neko. Si se tuviera un conjunto de
imgenes ms pequeo o ms grande
se tendra que ajustar el nmero de
posiciones del arreglo.

Debido a que la animacin Neko dibuja


las imgenes de un gato en diferentes
posiciones en la pantalla, ser necesario
rastrear las posiciones actuales de x y y
para que los diferentes mtodos del
applet sepan donde comenzar a dibujar.
La coordenada y permanece constante
para este applet en particular (Neko
corre de izquierda a derecha en la
misma posicin y), pero x puede variar.
Es necesario agregar dos variables de
instancia para esas posiciones:

int xpos;
int ypos = 50;
Ahora, en el cuerpo del applet.
Durante su inicializacin, leer todas
las imgenes y las almacenar en el
arreglo nekopics. Este es el tipo de
operaciones que funcionan bien con un
mtodo init().

Dado que tiene 9 nombres de archivos


diferentes, podra hacer una llamada por
separado a getImage() para cada uno.
Sin embargo, se puede crear un arreglo
local
para
los
nombres
de
archivos(nekosrc, un arreglo de
cadenas) y despus utilizar un ciclo for
para iterar sobre cada una y cargarlas.
Aqu esta el mtodo init() del applet
Neko que carga todas las imgenes en
el arreglo nekopics:

public void init() {


String nekosrc[] = { "right1.gif", "right2.gif",
"stop.gif", "yawn.gif",
"scratch1.gif",
"scratch2.gif", "sleep1.gif",
"sleep2.gif",
"awake.gif" };
for (int i=0; i<nekopics.length; i++) {
nekopics[i] =
getImage(getCodeBase(),
"images/" + nekosrc[i]);
}

En la llamada a getImage() el directorio


en el cual estn almacenadas las
imgenes (el directorio images) esta
incluido como parte de la ruta.

Paso 3: Animacin de las


imgenes
Con las imgenes cargadas, el
siguiente paso escomenzar a animar las
partes del applet. Esto se hace dentro
del mtodo run() del subproceso del
applet. En este applet, Neko hace cinco
acciones principales:

Entra

corriendo desde el lado


izquierdo de la pantalla.
Se detiene en la mitad y bosteza.
Se rasca la oreja cuatro veces.
Se duerme.
Despierta y sale corriendo hacia
la derecha de la pantalla.

Aunque se podra hacer la animacin


simple dibujando la imagen adecuada
en la pantalla en el momento correcto,
tiene ms sentido escribir este applet de
manera que las diferentes actividades
de Neko estn contenidas en mtodos
individuales. De esta forma se puede
reutilizar algunas de las actividades (en
particular la de Neko corriendo) si se
desea que Neko haga las cosas en un
orden diferente.

Se crea el mtodo en el que Neko


corre. Debido a que se utilizar dos
veces, se puede hacer uno genric. El
mtodo
nekorun()
toma
dos
argumentos, la posicin inicial x y la
posicin final x. Neko corre entre estas
dos posiciones (la posicin
y
permanece constante).
void nekorun(int start, int end) {
...
}

Hay dos imgenes que representan a


Neko corriendo; para crear el efecto de
movimiento es necesario alternarlas
(almacenadas en las posiciones 0 y 1
del arreglo de imgenes) as como
moverlas en la pantalla. La parte del
movimiento es un simple ciclo for entre
los argumentos de inicio y fin,
asignando la posicin x al valor actual
del ciclo.

El intercambio de imgenes consiste en


la comprobacin de la imagen activa en
algn turno del ciclo y la asignacin de
la otra imagen a la imagen actual. En
cada nuevo cuadro, se llamar a
repaint() y a sleep() para una pequea
pausa en la animacin

Debido a que durante esta animacin


habr muchas pausas con varios
intervalos, tiene sentido crear un mtodo
utilitario para realizar esto(hacer una
pausa para una cantidad de tiempo dado).
El mtodo pause(), tiene un argumento,
que es un nmero dado en milisegundos.
Aqu est su definicin:
void pause (int time) {
try{Thead.sleep(time);}
catch (InterruptedException e) { }
}

El mtodo nekorun(), itera desde una


posicin inicial a una posicin final.
Por cada vuelta de ciclo, se fija la
posicin actual
de x, se asigna
currentimg al cuadro correcto de la
animacin, se llama a repaint() y se
hace una pausa. Aqu est la definicin
de nekorun():

void nekorun(int start, int end) {


for (int i=start; i<end; i+=10) {
xpos=i;
// intercambio de imgenes
if (currentimg==nekopics[0])
currentimg=nekopics[1]}
else currentimg=nekopics [0]
repaint();
pause (150);
}

En la segunda lnea se incrementa el


ciclo en 10 pxeles.Por qu 10 y no 5 u
8? La respuesta est determinada
principalmente por prueba y error para
ver cul luce mejor. Al parecer 10 es la
que trabaja mejor con esta animacin.
Cuando escriba sus animaciones, es
necesario jugar tanto con la distancia
como los tiempos de espera hasta que
consiga el efecto que desea.

El mtodo paint() dibuja cada cuadro,


este mtodo simple, es el responsable de
dibujar la imagen en las coordenadas x y
y actuales. Toda esta informacin se
almacena en variables de instancia Sin
embargo es necesario verificar que las
imgenes realmente existan antes de
dibujarlas en la pantalla (las imgenes
talvez estn en el proceso de carga).

Para verificarlo y asegurarse que no se


intenta dibujar una imagen que an no
se tiene (provocando toda clase de
errores), se probar si el estado de
currentimg no es nulo antes de llamar
a drawImage() para dibujar la imagen:
public void paint (Graphics g) {
if (currentimg != null)
g.drawImage(currentimg, xpos, ypos
this);
}

El mtodo run () es donde se realiza el


proceso de animacin. Ya se creo el
mtodo nekoreun() que ser llamado
desde el mtodo run() con los valores
apropiados para que Neko corra de la
orilla izquierda al centro de la pantalla
de la siguiente forma:
//Corre de un lado de la pantalla al
centro
nekorun(0, size (). width/2);

La segunda accin que Neko hace es


detenerse y bostezar. Tiene un cuadro
para cada accin en las posiciones 2 y
3 del arreglo), as que no necesita un
mtodo distinto para dibujarlos. Todo
lo que se tiene que hacer es asignar la
imagen apropiada, llamar a repaint() y
hacer una pausa el tiempo correcto.

El siguiente ejemplo hace una pausa de


un segundo tanto para detenerse como
para bostezar (determinado por prueba y
error). Vea el cdigo:

//alto y pausa
currentimg = nekopics[2]
repaint();
pause(1000);

La parte de la animacin: Neko


rascndose. No hay desplazamiento
horizontal para esta parte esta parte de
la animacin. Simplemente alterna
entre las dos imgenes donde se est
rascando(almacenadas en la posicin 4
y 5 del arreglo). Debido a que esta
accin es diferente es necesario crear
su propio mtodo.

El mtodo nekoscratch() toma un solo


argumento: el nmero de veces que se
rasca. Con ese argumento puede iterar y
despus, dentro del ciclo, alternar entre
las imgenes donde se rasca Neko y
volver a dibujar otra vez:

void nekoscratch(int numtimes) {


for (int i = numtimes; i > 0; i--) {
currentimg = nekopics[4];
repaint();
pause(150);
currentimg = nekopics[5];
repaint();
pause(150);
}
}

Dentro del mtodo run se puede


llamar a nekoscratch con un argumento
(4):
Nekoscratch (4);
Despus de rascarse Neko se duerme.
Se tienen dos imgenes para hacer la
animacin las cuales se van a alternar
cierto nmero de veces. Se presenta el
mtodo nekosleep(), el cual tiene solo
un argumento: el nmero de veces que
se repite la animacin:

void nekosleep(int numtimes) {


for (int i = numtimes; i > 0; i--) {
currentimg = nekopics[6];
repaint();
pause(250);
currentimg = nekopics[7];
repaint();
pause(250);
}
}

Para llamar el mtodo nekosleep( ) en


el mtodo run( )es necesario hacer:
nekosleep(5 );
Para terminar el applet, Neko
despierta y corre hacia la derecha de la
pantalla. La imagen para despertar es la
ultima del arreglo y se puede volver a
utilizar el m todo nekorun( ) para
terminar:

currentimg = nekopics[8];
repaint();
pause(500);
nekorun(xpos, size().width +
10);

Paso 4 terminado
Todas las imagines de la animacin
tiene fondo blanco. Dibujarlas sobre el
fondo predeterminado del applet
significa tener un desagradable fondo
blanco alrededor de cada imagen. Para
resolver este problema solo hay que
asignar el color de fondo del applet a
blanco, tambin al inicio del mtodo
run():
setBackground(Color.white);

No se hizo nada para reducir el


parpado en este applet, debido a que la
imagen es suficientemente pequea, y
el rea de dibujo tambin. A
continuacin se muestra el listado
completo de este applet:
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Color;

public class Neko extends


java.applet.Applet
implements Runnable {
Image nekopics[] = new Image[9];
Image currentimg;
Thread runner;
int xpos;
int ypos = 50;

public void init() {


String nekosrc[] = { "right1.gif",
"right2.gif",
"stop.gif", "yawn.gif",
"scratch1.gif",
"scratch2.gif","sleep1.gif",
"sleep2.gif",
"awake.gif" };
{

for (int i=0; i < nekopics.length; i++)


nekopics[i] =

getImage(getCodeBase(),
"images/" + nekosrc[i]);
}
}

public void start() {


if (runner == null) {
runner = new Thread(this);
runner.start();
}
}
public void stop() {
if (runner != null) {
runner.stop();
runner = null;
}
}

public void run() {


setBackground(Color.white);
// run from one side of the screen
to the middle
nekorun(0, size().width / 2);
// stop and pause
currentimg = nekopics[2];
repaint();
pause(1000);

// yawn
currentimg = nekopics[3];
repaint();
pause(1000);
// scratch four times
nekoscratch(4);
// sleep for 5 "turns"
nekosleep(5);
// wake up and run off
currentimg = nekopics[8];
repaint();
pause(500);

void nekorun(int start, int end) {


for (int i = start; i < end; i += 10) {
xpos = i;
// swap images
if (currentimg == nekopics[0])
currentimg = nekopics[1];
else currentimg = nekopics[0];
repaint();
pause(150);
}
}

void nekoscratch(int numtimes) {


for (int i = numtimes; i > 0; i--) {
currentimg = nekopics[4];
repaint();
pause(150);
currentimg = nekopics[5];
repaint();
pause(150);
}
}

void nekosleep(int numtimes) {


for (int i = numtimes; i > 0; i--) {
currentimg = nekopics[6];
repaint();
pause(250);
currentimg = nekopics[7];
repaint();
pause(250);
}
}

void pause(int time) {


try { Thread.sleep(time); }
catch (InterruptedException e) { }
}
public void paint(Graphics g) {
if (currentimg != null)
g.drawImage(currentimg, xpos,
ypos, this);
}
}

8.7 CMO RECUPERAR


Y
UTILIZAR
SONIDOS

Java incluye soporte para reproducir


sonidos, ya sea solo o en conjuncin
con animaciones. Este soporte est
integrado en las clases Applet y AWT,
de modo que cargar sonidos en los
applets de Java es tan sencillo como
cargar y usar imgenes.

Hasta ahora el nico sonido que


soporta Java es el formato AU de Sun,
algunas veces llamado formato m-law.
Los archivos AU tienden a ser ms
chicos que los de otros formatos, pero
su calidad no es muy buena.

La forma para recuperar y reproducir


un sonido es a travs del mtodo
play(), parte de la clase Applet. Este
mtodo es similar a getImage() y puede
tomar una de dos formas:

play() con un argumento, un


objeto URL, carga y ejecuta el clip de
audio en ese URL.

play() con dos argumentos, un


argumento para el URL base y el otro
para la ruta, carga y reproduce el
archivo de audio.

La siguiente lnea
reproduce un sonido:

recupera

play(getCodeBase(),
audio/mew.au);
El mtodo play recupera y reproduce
el sonido dado lo ms pronto que
puede. Si no puede encontrar el sonido,
no se generar un error, ni se obtendr
el audio cuando se esperaba.

El mtodo getAudioClip() se usa para


cargara el sonido y almacenarlo en una
instancia de la clase AudioClip, para
despus operar directamente con el
objeto audioClip.
Por ejemplo, se tiene un ciclo de
sonido que se desea reproducir en un
segundo palno. En el cdigo de
inicializacin, se puede utilizar la
siguiente lnea para obtener el audio:

AudioClip clip=
getAudioClip(getCodeBase(),
audio/loop.au);
Para reproducir el clip una vez se utiliza
el mtodo play():
clip.play();
Para detener un sonido en ejecucin se
usa el mtodo stop():
clip.stop();

Para reproducir de manera repetida un


clip, se usa el mtodo loop():
clip.loop();

Si se est usando un sonido en segundo


plano, ese clip no se detendr de manera
automtica cuando se suspenda el
subproceso del applet. Esto significa
que si el lector se cambia a otra pgina,
el sonido del primer applet continuar
ejecutndose. Se puede arreglar este
problema utilizando el mtodo stop()
par detener el sonido de segundo plano
del applet.

public void stop() {


if (runner != null) {
if (bgsound != null)
bgsound.stop();
bgsound.stop();
runner.stop();
runner = null;
}
}

El siguiente applet muestra


modelo que reproduce sonidos:

un

import java.awt.Graphics;
import java.applet.AudioClip;
public class AudioLoop
java.applet.Applet
implements Runnable {

extends

AudioClip bgsound;
AudioClip beep;
Thread runner;
public void start() {
if (runner == null) {
runner = new Thread(this);
runner.start();
}

public void stop() {


if (runner != null) {
if (bgsound != null)
bgsound.stop();
runner.stop();
runner = null;
}
}

public void init() {


bgsound =
getAudioClip(getCodeBase(),"audio/lo
op.au");
beep =
getAudioClip(getCodeBase(),
"audio/beep.au");
}

public void run() {


if (bgsound != null)
bgsound.loop();
while (runner != null) {
try { Thread.sleep(5000); }
catch (InterruptedException e) {

if (beep != null) beep.play();


}
}

public void paint(Graphics g) {


g.drawString("Playing
Sounds....", 10, 10);
}
}

Reduccin del parpadeo: uso del


doble bfer
Doble bfer es un proceso de preparar
toda la imagen fuera de la pantalla y
cuando est lista, mostrarla de un solo
golpe en el monitor. Se le llama de
doble bfer porque hay dos reas de
memoria para la pantalla y se
intercambia entre ellas.

Este mtodo no siempre es el mejor, si el


applet tiene parpadeo, primero intente
sobreponer el mtodo update() y dibujar
solo partes de la pantalla. El doble bfer
ocupa ms espacio en memoria, pero
reduce casi totalmente el parpadeo.

Crear applets con doble bfer


Para hacerlo es necesario dos cosas:
especio fuera de la pantalla para dibujar
y un contexto grfico para esta imagen .
Ambos imitan el rea de dibujo del
applet, el contexto grfico (una instancia
de Graphics) para proporcionar mtodos
de dibujo drawImage(), drawString, e
Image que almacena los puntos
dibujados. A continuacin se muestra un
ejemplo del uso del doble bfer:

En este applet llamado juego de damas,


un valo rojo (una ficha del juego) se
mueve de un cuadro negro a un blanco,
como si estuviera en un tablero. Al final
de este movimiento regresa a su
posicin original y se mueve de nuevo.
A continuacin se muestra el cdigo
para este applet:

mport java.awt.Graphics;
import java.awt.Color;
public
class
Checkers
extends
java.applet.Applet
implements
Runnable {
Thread runner;
int xpos;

public void start() {


if (runner == null); {
runner = new Thread(this);
runner.start();
}
}
public void stop() {
if (runner != null) {
runner.stop();
runner = null;
}
}

public void run() {


while (true) {
for (xpos = 5; xpos <= 105;
xpos+=4) {
repaint();
try { Thread.sleep(100); }
catch (InterruptedException e) { }
}
xpos=5;
}
}

public void update(Graphics g) {


paint(g);
}
public void paint(Graphics g) {
// Draw background
g.setColor(Color.black);
g.fillRect(0,0,100,100);
g.setColor(Color.white);
g.fillRect(100,0,100,100);

// Draw checker
g.setColor(Color.red);
g.fillOval(xpos,5,90,90);
}
}

Hasta aqu lo que el applet est


haciendo, una variable de instancia,
xpos, almacena la posicin inicial de la
ficha, debido a que se mueve solo
horizontalmente la coordenada que
cambia es x. El mtodo run( ) cambia el
valor de x, lo vuelve a dibujar y espera
100
milisegundos
entre
cada
movimiento. La ficha parece moverse
de izquierda a derecha y regresar a su
posicin original despus.

En el mtodo paint( ) actual se dibujan


los cuadros del fondo (uno blanco y el
otro negro, y despus se dibuja la ficha
en su posicin actual.
Este applet tiene un parpadeo porque
primero se dibuja el fondo y despus la
ficha.

La solucin para este caso es usar el


doble buffer, el cual eliminar el
parpadeo. Para hacerlo agregue las
variables de instancia para la imagen
fuera de la pantalla y su contexto
grfico:
Image offscreenImg;
Graphics offscrfeenG;

Despus agregue un mtodo init( ) {


public void init( ){
offscreenImg
=
createImage(size(
).width,
size( ).height);
offscrfeenG
=
offscreenImg.getGraphics( );
}

Posteriormente es necesario modificar el


mtodo paint( ) para dibujar en el bfer
fuera de la pantalla en lugar del monitor:
public void paint (Graphics g){
offscreenG.setColor(Color.black);
offscfeenG.fillRect(0,0,100,100);
offscfeenG.setColor(Color.white);
offscreenG..fillRect(10,0,100,100);
offscreenG.setColor(Color.red);
offscreenG.fillOval(xpos,5,90,90);
g.drawImage(offscreenImg,0,0,this);
}

En el mtodo destroy( ) del applet, se


elimina el contexto grfico almacenado
en offscreenG:
public void destroy( ){
offscreenG.dispose( );
}

El applet completo se muestra a


continuacin:
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Image;
public class Checkers2 extends
java.applet.Applet
implements
Runnable {

Thread runner;
int xpos;
Image offscreenImg;
Graphics offscreenG;
public void init() {
offscreenImg
createImage(this.size().width,
this.size().height);
offscreenG
offscreenImg.getGraphics();
}

=
=

public void start() {


if (runner == null); {
runner = new Thread(this);
runner.start();
}
}
public void stop() {
if (runner != null) {
runner.stop();
runner = null;
}
}

public void run() {


while (true) {
for (xpos = 5; xpos <= 105;
xpos+=4) {
repaint();
try { Thread.sleep(100); }
catch (InterruptedException e) { }
}
xpos = 5;
}
}

public void update(Graphics g) {


paint(g);
}
public void paint(Graphics g) {
// Draw background
offscreenG.setColor(Color.black);
offscreenG.fillRect(0,0,100,100);
offscreenG.setColor(Color.white);
offscreenG.fillRect(100,0,100,100);

// Draw checker
offscreenG.setColor(Color.red);
offscreenG.fillOval(xpos,5,90,90);
g.drawImage(offscreenImg,0,0,this);
}
public void destroy() {
offscreenG.dispose();
}
}

S-ar putea să vă placă și