0% encontró este documento útil (0 votos)
13 vistas157 páginas

Nive L 6 Completo

Cargado por

somas55470
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
13 vistas157 páginas

Nive L 6 Completo

Cargado por

somas55470
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

ALGORITMICA Y PROGRAMACION POR OBJETOS I

Nivel 6
Manejando Estructuras
Contenedoras de 2 Dimensiones
y
Persistencia

Olga Mariño adaptado de Marcela Hernández Hoyos


Qué vamos a aprender en este
nivel:
Cómo definir, crear y manipular matrices
(estructuras contenedoras de 2
dimensiones)

Patrones de recorrido de matrices

Esquema simple de persistencia (archivos)


Caso de estudio No. 1: Visor
de Imágenes
El Visor de Imágenes
• Funcionalidad
• Interfaz usuario
• Formato BMP
• Mundo
El Visor de Imágenes -
Funcionalidad
• Permite la visualización de imágenes en formato
BMP
• Ofrece servicios de transformación de la imagen:
– Transformar la imagen en su negativa
– Aplicar un filtro
– Rotar la imagen
– Binarizar la imagen
– …
Formato BMP

Pixel tiene
un color

Rojo 0..255

Verde 0..255

Azul 0..255
El Visor de Imágenes
El Visor de Imágenes – Mundo
IMAGEN: Único
elemento del mundo Rojo

Verde

Azul

Se representa por
medio de una MATRIZ
de 300x400
Contenedoras de 2
dimensiones: MATRICES
El Visor de Imágenes – Mundo
Único atributo de la clase Imagen
llamado bitmap (nombre de la
matriz)

Clase nativa de Java

bitmap
Imagen Color
[300] [400]
int R
int G
int B

Así se indica en UML que se trata


de una matriz (contenedora de 2
dimensiones)
Un objeto de la clase Imagen podría
verse de la siguiente manera
: Imagen
0 1 2 … 399 Cada elemento de la
matriz apunta a un
0
objeto de tipo Color
Color bitmap =
1

299 : Color

R = 255
G=0
B=0
Matriz = contenedora de 2
dimensiones de tamaño fijo
bitmap [0][1]
bitmap [0][399]
bitmap [0][0]
columnas

0 1 2 … 399
filas bitmap [1][0]
0


bitmap =
299

bitmap [299][0] bitmap [299][399]


Matriz = contenedora de 2
dimensiones de tamaño fijo
columnas
filas 0 1 2 … 399
• Cada posición de la matriz
0
(casilla) se utiliza como una
1 variable


bitmap = bitmap[2][3] = new Color(0,0,0);

299 if ( bitmap[ i ][ j ] == bitmap[ 0 ][ 0 ] )



Declaración de una matriz
Se declaran
public class Imagen constantes para fijar
{ el tamaño de la
matriz
//Constantes
final public static int ANCHO_MAXIMO = 400;
final public static int ALTO_MAXIMO = 300;

//Atributos
private Color [ ][ ] bitmap;
}
Declaración de una matriz
public class Imagen
{
//Constantes
final public static int ANCHO_MAXIMO = 400;
final public static int ALTO_MAXIMO = 300;

//Atributos
private Color [ ][ ] bitmap;
} bitmap es una matriz
de dos dimensiones
de tamaño fijo y
cuyos elementos son
TODOS de tipo Color
Declaración de una matriz
public class Imagen
{
//Constantes
final public static int ANCHO_MAXIMO = 400;
final public static int ALTO_MAXIMO = 300;

//Atributos
private Color [ ][ ] bitmap;
}
Color es una clase de
JAVA (paquete
java.awt)
Declaración de una matriz
public class Imagen
{
//Constantes
final public static int ANCHO_MAXIMO = 400;
final public static int ALTO_MAXIMO = 300;

//Atributos
private Color [ ][ ] bitmap;
}

También se puede escribir


private Color bitmap [ ][ ]
Inicialización de una matriz
public Imagen
{
bitmap = new Color [ALTO_MAXIMO] [ANCHO_MAXIMO];
}
• El espacio en memoria (una cajita por posición de la matriz) queda
reservado.
• El valor de los elementos del arreglo es indefinido al comienzo.
• Para consultar el número de filas de la matriz: length
bitmap.length
• Para consultar el número de columnas de la matriz:
bitmap[0].length
• Si se trata de acceder a una casilla con un par de índices no válidos
java.lang.ArrayIndexOutOfBoundsException
Un objeto de la clase Imagen podría
verse de la siguiente manera
Cada elemento de la
: Imagen matriz es UNA
REFERENCIA
0 1 2 … 399 (apunta) a un objeto
0 de tipo Color
Color bitmap =
1

299 : Color

R = 255
Bitmap [ i ][ j ] G=0
B=0
Acceso a los elementos de una
matriz (ejemplo de recorrido total)
Se necesitan 2
• Método todoazul: inicializar todas las casillas con índices para acceder
azul a una posición de la
matriz:
• Recorrido: • i: fila
– Todas las filas
– Para cada fila todas las columnas • j: columna
– inicializando las casillas con objetos de tipo Color cuyo valor
representa el azul (0,0,255)

• for ( int i = 0; i < ALTO_MAXIMO; i++ )


{
• for ( int j = 0; j < ANCHO_MAXIMO; j++ )
{
Acceso a los elementos de una
matriz (ejemplo de recorrido total)
public void ImagenAzul ( )
{
// Recorre la matriz inicializando las casillas con
// objetos de tipo Color cuyo valor representa el azul

for ( int i = 0; i < ALTO_MAXIMO; i++ )


{
for ( int j = 0; j < ANCHO_MAXIMO; j++ )
{
bitmap[ i ][ j ] = new Color( 0, 0, 255);
}
} Se necesitan 2
} índices para acceder
a una posición de la
matriz:
• i: fila
• j: columna
Entonces…
Se necesitan 2 ciclos
para recorrer la
matriz:
public void ImagenAzul ( ) • recorrido de
{ TODAS las filas
// Recorre la matriz inicializando las casillas con • para cada fila,
// objetos de tipo Color cuyo valor representa el azul recorrido de
TODAS las
for ( int i = 0; i < ALTO_MAXIMO; i++ ) columnas
{
for ( int j = 0; j < ANCHO_MAXIMO; j++ )
{
bitmap[ i ][ j ] = new Color( 0, 0, 255);
}
}
}
Entonces…

public void ImagenAzul ( ) Los índices van


{ desde 0 hasta el
// Recorre la matriz inicializando las casillas con número de elementos
// objetos de tipo Color cuyo valor representa el azul menos 1

for ( int i = 0; i < ALTO_MAXIMO; i++ ) columnas


{
for ( int j = 0; j < ANCHO_MAXIMO; j++ )
{
bitmap[ i ][ j ] = new Color( 0, 0, 255);
}
} filas
}
Entonces…

public void ImagenAzul ( ) Los índices van


{ desde 0 hasta el
// Recorre la matriz inicializando las casillas con número de elementos
// objetos de tipo Color cuyo valor representa el azul menos 1

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


{
for ( int j = 0; j < bitmap[0].length; j++ )
{
bitmap[ i ][ j ] = new Color( 0, 0, 255);
}
} filas
}
Ahora con while…
public void ImagenAzul ( )
{
// Recorre la matriz inicializando las casillas con
// objetos de tipo Color cuyo valor representa el azul

int i = 0;
while (i < ALTO_MAXIMO)
{ columnas
int j = 0;
while ( j < ANCHO_MAXIMO )
{
bitmap[ i ][ j ] = new Color( 0, 0, 255);
j++;
}
filas
i++;
} fila columna
}
Cómo comparar los elementos de
una matriz (o arreglo) ?
• Si los elementos de una matriz son de tipo
simple (enteros, reales, etc.)
– Se comparan con el operador ==.
• Si los elementos NO son de tipo simple,
sino que son objetos, en la matriz se
guarda una referencia (apuntador) al
objeto y NO el objeto mismo. En este
caso, hay que compararlos con equals.
Un objeto de la clase Imagen podría
verse de la siguiente manera
Cada elemento de la
: Imagen matriz es UNA
REFERENCIA
0 1 2 … 399 (apunta) a un objeto
0 de tipo Color
Color bitmap =
1

299 : Color

R = 255
G=0
B=0
Ejemplo de comparación
: Color : Color : Color
R = 255 R = 255 R = 255
G=0 G=0 G=0
B=0 B=0 B=0
• Imagen de 2 x 3
: Imagen • Primera fila de
coloreada de rojo
0 1 2
(255,0,0)
0
Color bitmap =
• Segunda fila
1 coloreada de azul
(0,0,255)
• Cada casilla tiene
: Color : Color : Color un objeto
R=0 R=0 R=0 DIFERENTE que
G=0 G=0 G=0 representa el color
B = 255 B = 255 B = 255
del pixel
Ejemplo de comparación
: Color : Color : Color
R = 255 R = 255 R = 255
G=0 G=0 G=0
B=0 B=0 B=0

: Imagen
V F
0 1 2
bitmap[0][0] == bitmap[0][1]
0 bitmap[0][0] .equals(bitmap[0][1])
Color bitmap =
1 bitmap[0][0] .equals(bitmap[1][0])

: Color : Color : Color


R=0 R=0 R=0
G=0 G=0 G=0
B = 255 B = 255 B = 255
Ejemplo de comparación
: Color : Color : Color
R = 255 R = 255 R = 255
G=0 G=0 G=0
B=0 B=0 B=0

: Imagen
V F
0 1 2
bitmap[0][0] == bitmap[0][1] X
0 bitmap[0][0] .equals(bitmap[0][1]) X
Color bitmap =
1 bitmap[0][0] .equals(bitmap[1][0]) X

: Color : Color : Color


R=0 R=0 R=0
G=0 G=0 G=0
B = 255 B = 255 B = 255
Ejemplo de asignación
: Color : Color : Color
R = 255 R = 255 R = 255
G=0 G=0 G=0
B=0 B=0 B=0

: Imagen
0 1 2 Color temp = bitmap[0][0];

Color bitmap =
0
• Qué es temp?
1 • Qué valor tiene?
• Cómo se puede
visualizar?
: Color : Color : Color • Es un objeto o una
R=0 R=0 R=0 referencia?
G=0 G=0 G=0
B = 255 B = 255 B = 255
Ejemplo de asignación
: Color
R = 255
G=0
B=0

: Imagen Color temp = bitmap[0][0];


0 1 2

0
Color bitmap =
1
temp

• Qué es temp? R// Una variable


• Qué valor tiene? R// el valor de bitmap[0][0]
• Es un objeto o una referencia? R// Es una referencia al
mismo objeto que es referenciado por bitmap[0][0]
Ejemplo de asignación
: Color
R = 255
G=0
B=0

: Imagen Color temp = bitmap[0][0];


0 1 2

0
Color bitmap =
1
temp

CONCLUSION:
• TODAS las variables que tienen como valor un objeto,
son en realidad UNA REFERENCIA (apuntador) al
objeto
Ejemplo de asignación
: Color
R = 255
G=0
B=0

: Imagen Color temp = bitmap[0][0];


0 1 2

0
Color bitmap =
1
temp

En este caso:
temp y bitmap[0][0] referencian el mismo objeto
Ejemplo de asignación
: Color
R = 255
G=0
B=0

: Imagen Color temp = bitmap[0][0];


0 1 2

0
Color bitmap =
1
temp

Por lo tanto, las expresiones:


temp == bitmap[0][0] es verdadera
temp.equals(bitmap[0][0]) es verdadera también
Algunos métodos de la clase
Color
brighter()
Returns a brighter version of this color.

darker()
Returns a darker version of this color.

equals(Object)
Compares this object against the specified object.

getBlue()
Gets the blue component.

getGreen()
Gets the green component.

getRed()
Gets the red component.
Patrón de recorrido total
• Se usan DOS ciclos:
– Un primer ciclo recorre las filas
– Por cada fila, un segundo ciclo recorre sus
columnas
Patrón de recorrido total
Indice del primer ciclo
empieza en CERO

for ( int i = 0; i < NUM_FILAS; i++)


{
for ( int j = 0; j < NUM_COLUMNAS; j++)
{
<cuerpo del ciclo>
}
}

Primer ciclo:
recorrido de
filas
Patrón de recorrido total
Condición para continuar: índice
menor que el número de filas

for ( int i = 0; i < NUM_FILAS; i++)


{
for ( int j = 0; j < NUM_COLUMNAS; j++)
{
<cuerpo del ciclo>
}
}

Primer ciclo:
recorrido de
filas
Patrón de recorrido total
Avance: incremento
en 1 del índice

for ( int i = 0; i < NUM_FILAS; i++)


{
for ( int j = 0; j < NUM_COLUMNAS; j++)
{
<cuerpo del ciclo>
}
}

Primer ciclo:
recorrido de
filas
Patrón de recorrido total
Indice del primer ciclo empieza
en CERO

for ( int i = 0; i < NUM_FILAS; i++)


{
for ( int j = 0; j < NUM_COLUMNAS; j++)
{
<cuerpo del ciclo>
}
}

Segundo ciclo:
recorrido de
columnas
Patrón de recorrido total
Condición para continuar: índice
menor que el número de
columnas

for ( int i = 0; i < NUM_FILAS; i++)


{
for ( int j = 0; j < NUM_COLUMNAS; j++)
{
<cuerpo del ciclo>
}
}

Segundo ciclo:
recorrido de
columnas
Patrón de recorrido total
Avance: incremento
en 1 del índice

for ( int i = 0; i < NUM_FILAS; i++)


{
for ( int j = 0; j < NUM_COLUMNAS; j++)
{
<cuerpo del ciclo>
}
}

Segundo ciclo:
recorrido de
columnas
Patrón de recorrido total
• Se usa cuando se necesita recorrer TODA la matriz
• Ejemplos:
– Cambiar el color de todos los puntos en la imagen haciéndolos
mas oscuros (método darker() de la clase Color)
– Método que recibe un parámetro Color y cuenta el número de
píxeles (puntos) de la imagen que tienen el mismo color del
dado como parámetro (usando equals de la clase Color !!!)
– Método que mira si la imagen tiene más pixeles puro rojos, o
más puro verdes o más puro azules. Puede usar las constantes
de la clase Color: Color.RED, Color.BLUE, Color.GREEN
– Contar cuántos puntos en la imagen no tienen rojo (getRed( )
==0)
– Calcular la tendencia (rojo, verde o azul). La tendencia se
calcula viendo cuantos pixels tienen más verde que los otros
dos colores, cuántos más azul y cuántos más rojo y mirando el
mayor
Ejemplo: Modificación de la matriz

for ( int i = 0; i < ALTO_MAXIMO; i++)


{
for ( int j = 0; j < ANCHO_MAXIMO; j++)
{
bitmap[ i ][ j ] = bitmap[ i ][ j ].darker( );
}
}

Oscurece TODA la imagen con el método


darker de la clase Color
Ejemplo: Cálculo sobre la matriz
(uso de acumulado)
public int pixelsrojos( ) Cuenta cuántos
{ puntos tienen
int cuantosRojo = 0; solo rojo
for ( int i = 0; i < ALTO_MAXIMO; i++)
{
for ( int j = 0; j < ANCHO_MAXIMO; j++)
{
Color c = bitmap[ i ][ j ];
if ( c.getGreen( ) == 0 && c.getBlue( ) == 0 && c.getRed() != 0 )
{
cuantosRojo++;
}
}
}
return cuantosRojo;
}
Ejemplo: Cálculo sobre la matriz
(uso de acumulado)
public int rojosCero( )
{
int cuantosRojoCero = 0;
for ( int i = 0; i < ALTO_MAXIMO; i++)
{
for ( int j = 0; j < ANCHO_MAXIMO; j++)
Cuenta cuántos
{
Color c = bitmap[ i ][ j ]; puntos no
if ( c.getRed() == 0 ) tienen rojo
{
cuantosRojoCero++;
}
}
}
return cuantosRojoCero;
}
Patrón de recorrido parcial
• Se usa cuando NO se necesita recorrer TODA
la matriz
• Existe una condición que debemos verificar en
cada iteración para saber si debemos detener
los ciclos o volver a repetirlos
• Ejemplos:
– Saber si hay al menos un punto negro (0,0,0) en la
imagen
–…
–…
–…
Patrón de recorrido parcial (1)
Uso de un mismo centinela en los dos
ciclos
boolean termino = false;
int i = 0;
while (i < NUM_FILAS && !termino)
{
// revise los elementos de la fila i completos o hasta que se
cumpla la condición de terminación
i++;
} La variable termino puede ser
remplazada por cualquier
condición que indique el punto
en el que el problema ya ha
sido resuelto y se debe
interrumpir el recorrido de las
filas
Patrón de recorrido parcial (1)
Uso de un mismo centinela en los dos
ciclos
boolean termino = false;
int i = 0;
while (i < NUM_FILAS && !termino)
{
int j = 0
while (j < NUM_COLUMNAS && !termino)
{
// revise el elemento i,j y la condición de terminación
j++; La variable termino puede ser
} remplazada por cualquier
i++; condición que indique el punto
} en el que el problema ya ha
sido resuelto y se deben
interrumpir los dos ciclos
Patrón de recorrido parcial (1)
Uso de un mismo centinela en los dos
ciclos
boolean termino = false;
int i = 0;
while (i < NUM_FILAS && !termino)
{
int j = 0
while (j < NUM_COLUMNAS && !termino)
{
// revise el elemento i,j
if problema terminado
{
termino = true; La variable termino puede ser
} remplazada por cualquier
j++; condición que indique el punto
} en el que el problema ya ha
i++; sido resuelto y se deben
} interrumpir los dos ciclos
Patrón de recorrido parcial con
for
Uso de un mismo centinela en los dos
ciclos
boolean termino = false;
for ( int i = 0; i < NUM_FILAS && !termino ; i++)
{
for ( int j = 0; j < NUM_COLUMNAS && !termino; j++)
{
<cuerpo del ciclo>
La variable termino puede ser
if ( <problema terminado> )
remplazada por cualquier
termino = true;
condición que indique el punto
} en el que el problema ya ha
} sido resuelto y se deben
interrumpir los dos ciclos
Ejemplo (1)
public boolean hayPuntoNegro( )
{
boolean termino = false;
for ( int i = 0; i < ALTO_MAXIMO && !termino ; i++)
{
for ( int j = 0; j < ANCHO_MAXIMO && !termino; j++)
{

Retorna
Dice (verdadero
true si
} o falso)
hay al menos
si hay un
al
} menosnegro
punto un punto
en la
negro enfalse
imagen, la
imagen.
sino
}
Ejemplo (1)
public boolean hayPuntoNegro( )
{
boolean termino = false;
for ( int i = 0; i < ALTO_MAXIMO && !termino ; i++)
{
for ( int j = 0; j < ANCHO_MAXIMO && !termino; j++)
{
if ( bitmap[ i ][ j ].equals(Color.BLACK) )
{
termino = true;
Retorna true si
} hay al menos un
} punto negro en la
} imagen, false
return termino; sino
}
Ejemplo con recorrido total y
rompiendo el ciclo con return
public boolean hayPuntoNegro( )
{
boolean termino = false;
for ( int i = 0; i < ALTO_MAXIMO && !termino ; i++)
{
for ( int j = 0; j < ANCHO_MAXIMO && !termino; j++)
{
if ( bitmap[ i ][ j ].equals(Color.BLACK) )
{
termino = true; return true;
Dice (verdadero
} o falso) si hay al
} menos un punto
} negro en la
return termino; return false imagen.
}
Patrón de recorrido parcial (2)
Uso de un centinela diferente para cada
ciclo
boolean termino1 = false;
for ( int i = 0; i < NUM_FILAS && !termino1 ; i++)
{
boolean termino2 = false;
for ( int j = 0; j < NUM_COLUMNAS && !termino2; j++)
{
<cuerpo del ciclo> • Con termino1 se maneja el
if ( <problema interno terminado> ) recorrido parcial del ciclo
termino2 = true; externo
} • Con termino2 se maneja el ciclo
if ( <problema externo terminado> ) interno
termino1 = true; • termino1 y termino2 pueden ser
remplazadas por condiciones
}
Ejemplo (2)
public boolean hayMuchasFilasConPixelNegro( )
{
boolean termino1 = false;
int numFilas = 0;
for ( int i = 0; i < ALTO_MAXIMO && !termino1 ; i++)
{
boolean termino2 = false;
for ( int j = 0; j < ANCHO_MAXIMO && !termino2; j++)
{
if ( bitmap[ i ][ j ].equals(Color.BLACK) )
{
numFilas++;
termino2 = true; Devuelve true si
} hay mas de 50
} filas en la imagen
if ( numFilas > 50 )
termino1 = true;
con al menos un
} punto negro,
return termino1; false sino
}
Otros algoritmos de recorrido
• Son adaptaciones de los patrones de
recorrido total y parcial.
• Ejemplos:
– Recorrer sólo una fila
– Recorrer sólo una columna
– Recorrer sólo la diagonal
Ejemplo: Recorrer sólo una fila
public int contarVerdes( int numFila)
{

Cuenta el
numero de
píxeles de la fila
“numFila” cuyo
componente
} verde es el
máximo posible
(255).
Ejemplo: Recorrer sólo una fila
public int contarVerdes( int numFila)
{
int numVerdes = 0;
for ( int j = 0; j < ANCHO_MAXIMO; j++)
{
if ( bitmap[ numFila ][ j ].getGreen( ) == 255 ) Cuenta el
numVerdes++; numero de
} píxeles de la fila
return numVerdes;
} “numFila” cuyo
componente
verde es el
máximo posible
(255).
Ejemplo: Recorrer sólo una columna
public boolean hayAzul( int numColumna)
{

}
Mira si hay un
pixel azul en la
columna dada
Ejemplo: Recorrer sólo una columna
public boolean hayAzul( int numColumna)
{
boolean hay = false;
for ( int i = 0; i < ALTO_MAXIMO && !hay; i++)
{
if (bitmap[ i ][ numColumna ].getBlue( ) != 0 &&
bitmap[ i ][ numColumna ].getRed( ) == 0 &&
bitmap[ i ][ numColumna ].getGreen( ) == 0 )
hay = true;
}
return hay; Mira si hay un
} pixel azul en la
columna dada
Ejemplo: Recorrer sólo la diagonal
public boolean negroEnDiagonal( )
{
Indica (true / false) si
boolean termino = false;
hay un pixel negro
int dimension = ALTO_MAXIMO; sobre la diagonal de la
imagen.
if (ANCHO_MAXIMO < dimension)
dimension = ANCHO_MAXIMO;

for ( int i = 0; i < dimension && termino; i++)


{
if ( bitmap[ i ][ i ].equals( Color.BLACK ) )
termino = true;
}
return termino;
}
Tarea No. 3
• Filtrar una imagen con un filtro promedio. En el proceso de adquisición de
una imagen, ésta puede quedar con una serie de errores los cuales hacen
que se vea de mala calidad. Para corregir estos errores existe un algoritmo
de filtrado, el cual está basado en el cálculo de un nuevo valor para cada
píxel de la imagen. Este valor es calculado como el promedio de los 8
vecinos del píxel en la imagen original, sobre cada uno de los componentes
RGB. En este proceso no se incluyen los bordes de la imagen, puesto que
no tienen los 8 vecinos necesarios. Este método de la clase Imagen debe
retornar una matriz con una copia de la imagen filtrada.
Tarea No. 3
• Este método de la clase Imagen debe retornar una matriz con una copia de
la imagen filtrada.
public Color [ ] [ ] imagenFiltrada( )
{

}
Caso de estudio: Campeonato
de Fútbol
El Campeonato de Fútbol
• Funcionalidad – Requerimientos
funcionales
• Interfaz usuario
• Mundo del problema
• Persistencia
El Campeonato de Fútbol -
Funcionalidad
• Manejo de los resultados de los partidos de un
campeonato de fútbol.
• En el campeonato:
– Hay varios equipos.
– Cada equipo puede jugar contra cada uno de los otros
equipos una sola vez.
• Información de los equipos está en un archivo.
• La aplicación debe permitir:
– Cargar la lista de equipos
– Registrar el resultado de un partido
– Mostrar la tabla de goles
– Mostrar la tabla de posiciones
El Campeonato de Fútbol –
Requerimientos Funcionales
R1 Cargar equipos
R2 Registrar el
resultado de un
partido
R3 Mostrar la tabla de
goles
R4 Mostrar la tabla de R3
posiciones

R4

R2
R1
R1: Cargar equipos
El Campeonato de Fútbol –
Requerimientos Funcionales
• RF1: Cargar equipos

• Entradas:
– Nombre del
archivo
R2: Registrar un resultado
R2: Registrar un resultado

• Entradas:
– Equipo 1
– Equipo 2
– Goles del equipo 1
– Goles del equipo 2
R3: Mostrar tabla de goles
R3: Mostrar la tabla de goles
R4: Mostrar la tabla de posiciones
R4: Mostrar la tabla de posiciones

Puntos:
Por partido ganado: 3
Por partido empatado: 1
R4: Mostrar la tabla de posiciones
El Campeonato de Fútbol –
Mundo
Campeonato 0 .. maxEquipos Equipo
int maxEquipos equipos String nombre

tablaGoles [maxEquipos] [maxEquipos]

Gol
El Campeonato de Fútbol –
Mundo
Campeonato 0 .. maxEquipos Equipo
int maxEquipos equipos String nombre

tablaGoles [maxEquipos] [maxEquipos]

Gol
Campeonato
En implementación int tablaGoles =
real, NO hay clase
Gol. tablaGoles es
una matriz de
enteros
La clase Campeonato
public class Campeonato
{
//Constantes
final public static int SIN_JUGAR = -1;
final public static int INVALIDO = -2;

//Atributos
private int maxEquipos;
private int [ ] [ ] tablaGoles;
private Equipo[ ] equipos;

}
La clase Campeonato
public class Campeonato
{
//Constantes
final public static int SIN_JUGAR = -1;
final public static int INVALIDO = -2;

//Atributos
private int maxEquipos; Los equipos
private int [ ] [ ] tablaGoles; son modelados
private Equipo[ ] equipos; como un arreglo
de tamaño fijo
}
La clase Campeonato
public class Campeonato
{
//Constantes
final public static int SIN_JUGAR = -1;
final public static int INVALIDO = -2;

//Atributos
private int maxEquipos;
private int [ ] [ ] tablaGoles; La información de
private Equipo[ ] equipos; los equipos se lee
de un archivo: NO
} ES CONSTANTE,
se modela con un
atributo
La clase Campeonato
public class Campeonato
{
//Constantes
final public static int SIN_JUGAR = -1;
final public static int INVALIDO = -2;

//Atributos
private int maxEquipos;
private int [ ] [ ] tablaGoles; La tabla de goles es
private Equipo[ ] equipos; una matriz
CUADRADA (número
} de filas = número de
columnas = número de
equipos)
La tabla de goles
int tablaGoles =

equipo1

equipo2

tablaGoles [ equipo1 ] [ equipo2 ] = número de goles que el equipo1


hizo al equipo2

1 2
La tabla de goles
int tablaGoles =

equipo2

equipo1

tablaGoles [ equipo2 ] [ equipo1 ] = número de goles que el equipo2


hizo al equipo1

2 1
La tabla de goles
int tablaGoles =

equipo1

equipo1

tablaGoles [ equipo1 ] [ equipo1 ] = INVALIDO (constante = -2)

Un equipo NO puede
1 1 jugar contra el mismo
La clase Campeonato
public class Campeonato
{
//Constantes
final public static int SIN_JUGAR = -1;
final public static int INVALIDO = -2;

//Atributos
Indica que el partido
private int maxEquipos;
es INVALIDO porque
private int [ ] [ ] tablaGoles;
un equipo NO puede
private Equipo[ ] equipos;
jugar contra si mismo
}
La tabla de goles
int tablaGoles =

INVALIDO

INVALIDO

INVALIDO

INVALIDO

La diagonal de la matriz tiene


SIEMPRE el valor INVALIDO (= -2)
La tabla de goles
int tablaGoles =

?
equipo1

equipo2

tablaGoles [ equipo1 ] [ equipo2 ] = SIN_JUGAR ( constante = -1 )

Si un partido NO se ha
jugado, NO se conoce el
resultado, este es
SIN_JUGAR
La clase Campeonato
public class Campeonato
{
//Constantes
final public static int SIN_JUGAR = -1;
final public static int INVALIDO = -2;

//Atributos
Indica que el partido
private int maxEquipos;
NO se ha jugado
private int [ ] [ ] tablaGoles;
private Equipo[ ] equipos;

}
Responsabilidades de la clase
Campeonato
• La clase Campeonato es la DUEÑA de los equipos
y los goles, por lo tanto es la responsable de:
– Dar la información sobre los equipos
– Dar la información sobre la tabla de goles
– Dar la información sobre la tabla de posiciones
• Además es responsable de:
– Registrar el resultado de un partido
– Cargar la información del campeonato (de un archivo) y
llenar con ella el arreglo de equipos
Registrar el resultado de un
partido
Registrar el Resultado de un Partido
/**
* Registra el resultado de un partido <br>
* <b>pre: </b> Los equipos que participan en el campeonato ya
* fueron inicializados.
* <b>post: </b>Se actualizó la tabla de goles con el resultado indicado
*
* @param eq1 - Es el número del equipo 1 (Indice dentro de la matriz)
* @param eq2 - Es el número del equipo 2 (Indice dentro de la matriz)
* @param gol1 - Es el número de goles marcados por el equipo 1
* @param gol2 - Es el número de goles marcados por el equipo 2
* @throws Exception Se lanza excepción si:
* los equipos no son válidos,
* el número de goles es inválido
* el partido ya se ha jugado antes
*/
Registrar el Resultado de un Partido
public void registrarResultado(int eq1, int eq2, int gol1, int gol2) throws Exception
{
if ( eq1 < 0 || eq1 >= maxEquipos || eq2 < 0 || eq2 >= maxEquipos )
{
throw new Exception("Equipos incorrectos");
}
if ( eq1 == eq2 )
{
throw new Exception(“Son el mismo equipo");
}
if ( gol1 < 0 || gol2 < 0 )
{  Verificación de
throw new Exception(“Número de goles inválido"); los datos de
} entrada
if ( tablaGoles[ eq1 ][ eq2 ] != SIN_JUGAR ||
tablaGoles[ eq2 ][ eq1 ] != SIN_JUGAR )
{
throw new Exception(“Partido ya jugado antes");

}…
Registrar el Resultado de un Partido
public void registrarResultado(int eq1, int eq2, int gol1, int gol2) throws Exception
{


tablaGoles[ eq1 ][ eq2 ] = gol1;
 Asignación de los
tablaGoles[ eq2 ][ eq1 ] = gol2;
}
goles en las posiciones
correctas de la matriz

eq1 gol1

gol2

eq2
Responsabilidades de la clase
Campeonato
• La clase Campeonato es la DUEÑA de los equipos
y los goles, por lo tanto es la responsable de:
– Dar la información sobre los equipos
– Dar la información sobre la tabla de goles
– Dar la información sobre la tabla de posiciones
• Además es responsable de:
– Registrar el resultado de un partido
– Cargar la información del campeonato (de un archivo) y
llenar con ella el arreglo de equipos
Dar la información sobre la
tabla de posiciones
Construir la tabla de posiciones

1 3
tablaGoles[ 0 ] [ 2 ] > tablaGoles[ 2 ] [ 0 ]
1 1
2 Milán jugó contra Juventus y ganó 3 a 2
5 SIN_JUGAR
INVALIDO
1 3
tablaGoles[ 0 ] [ 2 ] > tablaGoles[ 2 ] [ 0 ]
1 1
2 Milán jugó contra Juventus y ganó 3 a 2
5 SIN_JUGAR
INVALIDO
Construir la tabla de posiciones
• Para cada equipo, se debe calcular:
1. Partidos jugados
2. Partidos ganados
3. Partidos empatados
4. Partidos perdidos
5. Goles a favor
6. Goles en contra
7. Puntos
Tarea No. 4
• Escriba un método de la clase Campeonato que calcule el número
total de partidos ganados por el equipo que se recibe como
parámetro.
public int partidosGanados( int equipo )
{

}
Tarea No. 4
• Escriba un método de la clase Campeonato que calcule el número
total de partidos empatados por el equipo que se recibe como
parámetro.
public int partidosEmpatados( int equipo )
{

}
Tarea No. 4
• Escriba un método de la clase Campeonato que calcule el número
total de partidos jugados por el equipo que se recibe como
parámetro.
public int partidosJugados( int equipo )
{

}
Tarea No. 4
• Escriba un método de la clase Campeonato que calcule el número
total de goles marcados por el equipo que se recibe como
parámetro.
public int golesAFavor( int equipo )
{

}
Tarea No. 4
• Escriba un método de la clase Campeonato que calcule el número total de
puntos del equipo que se recibe como parámetro. Tenga en cuenta que un
equipo recibe 3 puntos por cada partido ganado y un punto por cada partido
empatado
public int calcularTotalPuntos( int equipo )
{

}
Tarea No. 5
• Escriba un método de la clase Campeonato que retorne el índice del equipo
que va ganando el campeonato. Si hay dos equipos con el mismo número
de puntos, gana aquel cuya diferencia de goles (goles anotados menos
goles recibidos) sea mayor.
public int calcularGanador( )
{

}
Tarea No. 5
• Escriba un método de la clase Campeonato que calcule el número
de partidos que faltan por jugar en el campeonato.
public int calcularPorJugar( )
{

}
Tarea No. 5
• Escriba un método de la clase Campeonato que calcule el mayor
número de goles marcados en un partido del campeonato (sumando
los goles de los dos equipos).
public int calcularTotalGoles( )
{

}
Tarea No. 5
• Escriba un método de la clase Campeonato que calcule el número
de partidos del campeonato cuyo marcador fue cero a cero.
public int calcularTotalCeroACero( )
{

}
Persistencia y manejo del
estado inicial
Responsabilidades de la clase
Campeonato
• La clase Campeonato es la DUEÑA de los equipos
y los goles, por lo tanto es la responsable de:
– Dar la información sobre los equipos
– Dar la información sobre la tabla de goles
– Dar la información sobre la tabla de posiciones
• Además es responsable de:
– Registrar el resultado de un partido
– Cargar la información del campeonato (de un archivo) y
llenar con ella el arreglo de equipos

PERSISTENCIA … a 1/2
Persistencia es …
• Guardar los datos resultado de un programa en un
archivo para hacerlos persistentes cuando la
aplicación termine.
• Es tema de APO2 !!!
• En APO1 … introducción a persistencia:
– Leer y cargar los datos de un archivo para configurar el
estado inicial de los elementos del mundo
– Ejemplos:
• Cargar la información de la posición inicial de las fichas del
rompecabezas.
• Abrir una imagen.
• Ahora … leer la información de los equipos del campeonato
para configurar el estado inicial del mundo.
El Concepto de Archivo
Qué es un archivo ?
• Una entidad que contiene información y que es
almacenada en la memoria secundaria del
computador (disco duro, CD, unidad USB,
diskette …)
• Tiene un nombre y una extensión
• El nombre tiene una ruta (camino o path en
inglés) y el nombre corto propiamente dicho.

c:/apoo/uniandes/cupi2/empleado/mundo/Empleado.java
Qué es un archivo ?

c:/apoo/uniandes/cupi2/empleado/mundo/Empleado.java

• Ruta = estructura de directorios dentro de los cuales


se encuentra el archivo, empezando por la raíz del
disco
• “/”: separador de nombres de archivos
• Extensión: indica el tipo del archivo (doc para word,
xls para excel, txt para texto, java para java, …)
Ejemplo de archivos –
Información de los valores iniciales
del rompecabezas de nivel difícil
rompecabezas.filas=5
rompecabezas.columnas=5

rompecabezas.pieza0PosX=0
rompecabezas.pieza0PosY=1
rompecabezas.pieza0RutaImagen=./data/imagenes/imagen5x5/p0-1.png

rompecabezas.pieza1PosX=0
rompecabezas.pieza1PosY=2
rompecabezas.pieza1RutaImagen=./data/imagenes/imagen5x5/p0-2.png

rompecabezas.pieza2PosX=0
rompecabezas.pieza2PosY=3
rompecabezas.pieza2RutaImagen=./data/imagenes/imagen5x5/p0-3.png


Ejemplo de archivos –
Imagen BMP (bitmap)

?
Es un archivo especial (no es texto plano). Solo se puede
leer con una aplicación especializada (paint, photo shop,
paint shop pro, visor de imágenes de APO1 !!!, …)
Ejemplo de archivos –
Equipos del campeonato
El archivo equipos.properties

• Es un archivo de texto que contiene una lista de


propiedades
• Cada propiedad es una línea del archivo y está
definida como:
– nombre = valor
– campeonato.equipos = 5
Ejemplo de archivos –
Equipos del campeonato
rompecabezas.filas=5
rompecabezas.columnas=5

rompecabezas.pieza0PosX=0
rompecabezas.pieza0PosY=1
rompecabezas.pieza0RutaImagen=./data/imagenes/imagen5x5/p0-1.png

rompecabezas.pieza1PosX=0
rompecabezas.pieza1PosY=2
rompecabezas.pieza1RutaImagen=./data/imagenes/imagen5x5/p0-2.png

rompecabezas.pieza2PosX=0
rompecabezas.pieza2PosY=3
rompecabezas.pieza2RutaImagen=./data/imagenes/imagen5x5/p0-3.png


Qué contiene un objeto de la clase
“Properties” ?
• Clase Properties de JAVA
– Representa un conjunto de propiedades “persistentes”, es
decir que pueden ser almacenadas en un archivo.

datos
campeonato.equipos 5
campeonato.nombre0 A.C.Milan
campeonato.equipos = 5
campeonato.nombre0 = A.C.Milan campeonato.nombre1 Inter
campeonato.nombre1 = Inter campeonato.nombre2 Juventus
campeonato.nombre2 = Juventus
campeonato.nombre3 = Roma campeonato.nombre3 Roma
campeonato.nombre4 = Lazio campeonato.nombre4 Lazio

Archivo llamado Objeto llamado “datos” de tipo


“equipos.properties” Properties (en memoria principal)
(en el disco duro)
Etapas
1. Localizar el archivo en el disco
2. Hacer la asociación entre un archivo
físico y un objeto en el programa que lo
represente
3. Leer o cargar el contenido del archivo
Localizar el archivo en el disco
y guardar su información
• Si se conoce el nombre del archivo

File archivoDatos = new File ( “C:\n6_campeonatos\data\equipos.properties”);

• Si se desea obtener el nombre por pantalla


– Método en la clase interfazCampeonato : cargarEquipo
– Crear un objeto de la clase FileChoooser que va a permitir seleccionar
de un directorio
JFileChooser fc = new JFileChooser ( “.data);
– Presentar la ventana del directorio y permitir que el usuario
seleccione
Lectura de Archivos: desde
la selección del archivo hasta
la inicialización del estado
del mundo de la aplicación
Selección del archivo

El usuario genera un evento oprimiendo el botón. Se


dispara el método cargarEquipos de la ventana
principal (clase InterfazCampeonato)
En el método cargarEquipos …
public class InterfazCampeonato extends JFrame
{…
public void cargarEquipos( )
{

JFileChooser fc = new JFileChooser( "./data" ); Caja de diálogo para


fc.setDialogTitle( "Abrir archivo de campeonato" ); escoger el archivo
int resultado = fc.showOpenDialog( this ); con la clase
JFileChooser (JAVA)

}
}

Se muestra al usuario la


caja de diálogo para
seleccionar el archivo
En el método cargarEquipos …
public class InterfazCampeonato extends JFrame
{…
public void cargarEquipos( )
{
File archivoCampeonato = null;

JFileChooser fc = new JFileChooser( "./data" );


fc.setDialogTitle( "Abrir archivo de campeonato" );
int resultado = fc.showOpenDialog( this );
Se obtiene el archivo
if( resultado == JFileChooser.APPROVE_OPTION ) seleccionado, que es
{ un objeto de la clase
archivoCampeonato = fc.getSelectedFile( ); File (de JAVA)
}
else
{
return;
Se
} muestra al usuario la
} caja de diálogo para
} seleccionar el archivo
En el método cargarEquipos …
public class InterfazCampeonato extends JFrame
{…
public void cargarEquipos( )
{
File archivoCampeonato = null;

JFileChooser fc = new JFileChooser( "./data" );


fc.setDialogTitle( "Abrir archivo de campeonato" );
int resultado = fc.showOpenDialog( this );

if( resultado == JFileChooser.APPROVE_OPTION )


{
archivoCampeonato = fc.getSelectedFile( );
campeonato = new Campeonato( archivoCampeonato );
}
} Se llama al método
} constructor de la
clase Campeonato,
Se crea el objeto que recibe como
campeonato parámetro, el archivo
En el método constructor de la clase
Campeonato …
public class Campeonato
{…
public Campeonato( File arch )
{
Properties datos = cargarInfoCampeonato( arch );
inicializarEquipos( datos );
inicializarTablaGoles( );
}
}

Se llama al método
cargarInfoCampeonato de la clase
Campeonato, que recibe como
parámetro, el archivo

Se carga la información del


campeonato, a partir del archivo
En el método cargarInfoCampeonato de
la clase Campeonato …
public class Campeonato
{…
private Properties cargarInfoCampeonato( File arch )
{
Properties datos = new Properties( );
FileInputStream in = new FileInputStream( arch );
datos.load( in );
in.close( );
return datos;
}
}
Carga la información del archivo en un
objeto de tipo Properties (JAVA) y
retorna este objeto
En el método cargarInfoCampeonato de
la clase Campeonato …
public class Campeonato
{…
private Properties cargarInfoCampeonato( File arch )
{
Properties datos = new Properties( );
FileInputStream in = new FileInputStream( arch );
datos.load( in );
in.close( );
return datos;
}
}
Crea el objeto de tipo Properties
En el método cargarInfoCampeonato de
la clase Campeonato …
public class Campeonato
{…
private Properties cargarInfoCampeonato( File arch )
{
Properties datos = new Properties( );
FileInputStream in = new FileInputStream( arch );
datos.load( in );
in.close( );
return datos;
}
}
Crea un objeto de tipo FileInputStream
(clase de JAVA que permite cargar
archivos)  Canal por donde se
transmiten los datos desde el disco duro
hasta el programa
En el método cargarInfoCampeonato de
la clase Campeonato …
public class Campeonato
{…
private Properties cargarInfoCampeonato( File arch )
{
Properties datos = new Properties( );
FileInputStream in = new FileInputStream( arch );
datos.load( in );
in.close( );
return datos;
}
}
Carga el archivo mediante el método
load
En el método cargarInfoCampeonato de
la clase Campeonato …
public class Campeonato
{…
private Properties cargarInfoCampeonato( File arch )
{
Properties datos = new Properties( );
FileInputStream in = new FileInputStream( arch );
datos.load( in );
in.close( );
return datos;
}
}
Cierra el “canal”
En el método cargarInfoCampeonato de
la clase Campeonato …
public class Campeonato
{…
private Properties cargarInfoCampeonato( File arch )
{
Properties datos = new Properties( );
FileInputStream in = new FileInputStream( arch );
datos.load( in );
in.close( );
return datos;
}
}
Retorna los “datos” que es un objeto de
la clase Properties
Qué contiene un objeto de la clase
“Properties” ?
• Clase Properties de JAVA
– Representa un conjunto de propiedades “persistentes”, es
decir que pueden ser almacenadas en un archivo.

datos
campeonato.equipos 5
campeonato.nombre0 A.C.Milan
campeonato.equipos = 5
campeonato.nombre0 = A.C.Milan campeonato.nombre1 Inter
campeonato.nombre1 = Inter campeonato.nombre2 Juventus
campeonato.nombre2 = Juventus
campeonato.nombre3 = Roma campeonato.nombre3 Roma
campeonato.nombre4 = Lazio campeonato.nombre4 Lazio

Archivo llamado Objeto llamado “datos” de tipo


“equipos.properties” Properties (en memoria principal)
(en el disco duro)
El objeto llamado “datos” de la
clase Properties
datos
campeonato.equipos 5
campeonato.nombre0 A.C.Milan
nombre = valor campeonato.nombre1 Inter
campeonato.nombre2 Juventus
campeonato.nombre3 Roma
campeonato.nombre4 Lazio

• Tiene métodos para obtener el valor de sus


elementos
• Ejemplo:
– String valor = datos.getProperty(“campeonato.nombre0”)
El objeto llamado “datos” de la
clase Properties
Retorna el “valor” del
datos “nombre”
campeonato.nombre0,
campeonato.equipos 5 que es “A.C. Milan”
campeonato.nombre0 A.C.Milan
nombre = valor campeonato.nombre1 Inter
campeonato.nombre2 Juventus
campeonato.nombre3 Roma
campeonato.nombre4 Lazio

• Tiene métodos para obtener el valor de sus


elementos
• Ejemplo:
– String valor = datos.getProperty(“campeonato.nombre0”)
Volvamos al método
cargarInfoCampeonato de la clase
Campeonato …
public class Campeonato
{…
private Properties cargarInfoCampeonato( File archivoInfoCampeonato )
{
Properties datos = new Properties( );
FileInputStream in = new FileInputStream( archivoInfoCampeonato );
datos.load( in );
in.close( );
datos
return datos;
} campeonato.equipos 5
} campeonato.nombre0 A.C.Milan
campeonato.nombre1 Inter
Retorna los “datos” que campeonato.nombre2 Juventus
es un objeto de la clase
Properties campeonato.nombre3 Roma
campeonato.nombre4 Lazio
Volvamos al método constructor de la
clase Campeonato (paso 4) …
public class Campeonato
{…
public Campeonato( File archivoInfoCampeonato )
{
Properties datos = cargarInfoCampeonato( archivoInfoCampeonato );
inicializarEquipos( datos );
inicializarTablaGoles( maxEquipos );
}
}

datos Retorna los “datos” que es un objeto


campeonato.equipos 5 de la clase Properties
campeonato.nombre0 A.C.Milan
campeonato.nombre1 Inter
campeonato.nombre2 Juventus
campeonato.nombre3 Roma Se carga la información del
campeonato.nombre4 Lazio campeonato, a partir del archivo
Continuemos con el método constructor
de la clase Campeonato (paso 5) …
public class Campeonato
{…
public Campeonato( File archivoInfoCampeonato )
{
Properties datos = cargarInfoCampeonato( archivoInfoCampeonato );
inicializarEquipos( datos );
inicializarTablaGoles( maxEquipos );
}
}

datos Inicializa (llena) el arreglo


de equipos a partir de la
campeonato.equipos 5
información contenida en el
campeonato.nombre0 A.C.Milan
objeto “datos”
campeonato.nombre1 Inter
campeonato.nombre2 Juventus
campeonato.nombre3 Roma
campeonato.nombre4 Lazio
En el método inicializarEquipos de la
clase Campeonato …
public class Campeonato
{…
private void inicializarEquipos( Properties datos )
{
String strNumeroEquipos = datos.getProperty("campeonato.equipos");
int numeroEquipos = Integer.parseInt(strNumeroEquipos); Obtiene el valor del nombre
equipos = new Equipo[ numeroEquipos ]; “campeonato.equipos” que
maxEquipos = numeroEquipos; contiene una cadena de
caracteres con el número de
for (int i = 0; i < numeroEquipos; i++) equipos
{
String nombreEquipo = datos.getProperty("campeonato.nombre"+ i);
Equipo nuevo = new Equipo( nombreEquipo ); datos
equipos[ i ] = nuevo;
campeonato.equipos 5
}
} campeonato.nombre0 A.C.Milan

campeonato.nombre1 Inter

campeonato.nombre2 Juventus

campeonato.nombre3 Roma

campeonato.nombre4 Lazio
En el método inicializarEquipos de la
clase Campeonato …
public class Campeonato
{…
private void inicializarEquipos( Properties datos )
{
String strNumeroEquipos = datos.getProperty("campeonato.equipos");
int numeroEquipos = Integer.parseInt(strNumeroEquipos);
equipos = new Equipo[ numeroEquipos ]; Obtiene el valor numérico de la
maxEquipos = numeroEquipos; cantidad de equipos

for (int i = 0; i < numeroEquipos; i++)


{
String nombreEquipo = datos.getProperty("campeonato.nombre"+ i);
Equipo nuevo = new Equipo( nombreEquipo ); datos
equipos[ i ] = nuevo;
campeonato.equipos 5
}
} campeonato.nombre0 A.C.Milan

campeonato.nombre1 Inter

campeonato.nombre2 Juventus

campeonato.nombre3 Roma

campeonato.nombre4 Lazio
En el método inicializarEquipos de la
clase Campeonato …
public class Campeonato
{…
private void inicializarEquipos( Properties datos )
{
String strNumeroEquipos = datos.getProperty("campeonato.equipos");
int numeroEquipos = Integer.parseInt(strNumeroEquipos);
equipos = new Equipo[ numeroEquipos ]; Crea el arreglo de equipos con
maxEquipos = numeroEquipos; un tamaño igual a la cantidad
de equipos
for (int i = 0; i < numeroEquipos; i++)
{
String nombreEquipo = datos.getProperty("campeonato.nombre"+ i);
Equipo nuevo = new Equipo( nombreEquipo ); datos
equipos[ i ] = nuevo;
campeonato.equipos 5
}
} campeonato.nombre0 A.C.Milan

campeonato.nombre1 Inter

campeonato.nombre2 Juventus

campeonato.nombre3 Roma

campeonato.nombre4 Lazio
En el método inicializarEquipos de la
clase Campeonato …
public class Campeonato
{…
private void inicializarEquipos( Properties datos )
{
String strNumeroEquipos = datos.getProperty("campeonato.equipos");
int numeroEquipos = Integer.parseInt(strNumeroEquipos);
equipos = new Equipo[ numeroEquipos ]; Inicializa el atributo
maxEquipos = numeroEquipos;

for (int i = 0; i < numeroEquipos; i++)


{
String nombreEquipo = datos.getProperty("campeonato.nombre"+ i);
Equipo nuevo = new Equipo( nombreEquipo ); datos
equipos[ i ] = nuevo;
campeonato.equipos 5
}
} campeonato.nombre0 A.C.Milan

campeonato.nombre1 Inter

campeonato.nombre2 Juventus

campeonato.nombre3 Roma

campeonato.nombre4 Lazio
En el método inicializarEquipos de la
clase Campeonato …
public class Campeonato
{…
private void inicializarEquipos( Properties datos )
{
String strNumeroEquipos = datos.getProperty("campeonato.equipos");
int numeroEquipos = Integer.parseInt(strNumeroEquipos);
equipos = new Equipo[ numeroEquipos ]; Carga uno a uno los nombres
maxEquipos = numeroEquipos; de los equipos

for (int i = 0; i < numeroEquipos; i++)


{
String nombreEquipo = datos.getProperty("campeonato.nombre"+ i);
Equipo nuevo = new Equipo( nombreEquipo ); datos
equipos[ i ] = nuevo;
campeonato.equipos 5
}
} campeonato.nombre0 A.C.Milan

campeonato.nombre1 Inter

campeonato.nombre2 Juventus

campeonato.nombre3 Roma

campeonato.nombre4 Lazio
En el método inicializarEquipos de la
clase Campeonato …
public class Campeonato
{…
private void inicializarEquipos( Properties datos )
{
String strNumeroEquipos = datos.getProperty("campeonato.equipos");
int numeroEquipos = Integer.parseInt(strNumeroEquipos);
equipos = new Equipo[ numeroEquipos ]; Crea el objeto de la clase
maxEquipos = numeroEquipos; Equipo

for (int i = 0; i < numeroEquipos; i++)


{
String nombreEquipo = datos.getProperty("campeonato.nombre"+ i);
Equipo nuevo = new Equipo( nombreEquipo ); datos
equipos[ i ] = nuevo;
campeonato.equipos 5
}
} campeonato.nombre0 A.C.Milan

campeonato.nombre1 Inter

campeonato.nombre2 Juventus

campeonato.nombre3 Roma

campeonato.nombre4 Lazio
En el método inicializarEquipos de la
clase Campeonato …
public class Campeonato
{…
private void inicializarEquipos( Properties datos )
{
String strNumeroEquipos = datos.getProperty("campeonato.equipos");
int numeroEquipos = Integer.parseInt(strNumeroEquipos);
equipos = new Equipo[ numeroEquipos ];
maxEquipos = numeroEquipos;

for (int i = 0; i < numeroEquipos; i++)


{
String nombreEquipo = datos.getProperty("campeonato.nombre"+ i);
Equipo nuevo = new Equipo( nombreEquipo ); datos
equipos[ i ] = nuevo;
campeonato.equipos 5
}
} campeonato.nombre0 A.C.Milan

Adiciona el nuevo equipo al campeonato.nombre1 Inter


arreglo campeonato.nombre2 Juventus

campeonato.nombre3 Roma

campeonato.nombre4 Lazio
Continuemos con el método constructor
de la clase Campeonato (paso 6) …
public class Campeonato
{…
public Campeonato( File archivoInfoCampeonato )
{
Properties datos = cargarInfoCampeonato( archivoInfoCampeonato );
inicializarEquipos( datos );
inicializarTablaGoles( maxEquipos );
}
}
0 1 2 3 4 Inicializa la tabla
A.C. Milan 0 de goles (con los
Inter 1 valores
Juventus 2 SIN_JUGAR e
INVALIDO)
Roma 3
Lazio 4

SIN_JUGAR INVALIDO
Volvamos al método cargarEquipos …
public class InterfazCampeonato extends JFrame
{…
public void cargarEquipos( )
{
File archivoCampeonato = null;

JFileChooser fc = new JFileChooser( "./data" );


fc.setDialogTitle( "Abrir archivo de campeonato" );
int resultado = fc.showOpenDialog( this );

if( resultado == JFileChooser.APPROVE_OPTION )


{
archivoCampeonato = fc.getSelectedFile( );
campeonato = new Campeonato( archivoCampeonato );
}
} Se llama al método
} constructor de la
clase Campeonato,
que recibe como
parámetro, el archivo
Volvamos a la selección del
archivo

El usuario genera un evento oprimiendo el botón. Se


dispara el método cargarEquipos de la ventana
principal (clase InterfazCampeonato)
En el método cargarInfoCampeonato de
la clase Campeonato se pueden generar
excepciones … (pag. 319)
public class Campeonato
{…
private Properties cargarInfoCampeonato( File archivoInfoCampeonato )
{
Properties datos = new Properties( );
FileInputStream in = new FileInputStream( archivoInfoCampeonato );
datos.load( in );
in.close( );
return datos; Genera excepción si
} no encuentra el
} archivo
En el método cargarInfoCampeonato de
la clase Campeonato se pueden generar
excepciones … (pag. 231)
public class Campeonato
{…
private Properties cargarInfoCampeonato( File archivoInfoCampeonato )
{
Properties datos = new Properties( );
FileInputStream in = new FileInputStream( archivoInfoCampeonato );
datos.load( in );
in.close( );
return datos; Genera excepción si
} la manera como está
} escrito el archivo no
es “nombre=valor”
public class Campeonato
Entonces …
{…
private Properties cargarInfoCampeonato(File archivoInfoCampeonato) throws Exception
{
Properties datos = new Properties( );
FileInputStream in = null;
try
{
Disparar la excepción si
in = new FileInputStream(archivoInfoCampeonato);
no encuentra el archivo
}
catch (Exception e)
{
throw new Exception("El archivo no existe!");
}
try
{
datos.load(in); Disparar la excepción si
in.close(); el archivo no es válido
}
catch (Exception e)
{
throw new Exception("El formato del archivo no es válido!");
}
return datos;
}

También podría gustarte