notasGUI
notasGUI
Héctor Tejeda V
Febrero, 2010
2
Índice general
1. Introducción 5
1.1. Componentes, gestores de disposición y captura de eventos . . 6
1.2. AWT y Swing . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2. Caso de estudio 9
2.1. Mostrando texto en un cuadro de diálogo . . . . . . . . . . . . 9
2.2. Ingresando texto en un cuadro de diálogo . . . . . . . . . . . . 10
2.2.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3. Creando dibujos simples . . . . . . . . . . . . . . . . . . . . . 12
2.3.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.4. Dibujando rectángulos y elipses . . . . . . . . . . . . . . . . . 16
2.4.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.5. Figuras Rellenas y Colores . . . . . . . . . . . . . . . . . . . . 19
2.5.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.6. Dibujo de Arcos . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.6.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.7. Usando objetos con gráficas . . . . . . . . . . . . . . . . . . . 25
2.7.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.8. Texto e imágenes con etiquetas . . . . . . . . . . . . . . . . . 30
2.8.1. Ejercicio . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.9. Dibujado con polimorfismo . . . . . . . . . . . . . . . . . . . . 32
2.9.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . 32
3
4 ÍNDICE GENERAL
Capı́tulo 1
Introducción
5
6 CAPÍTULO 1. INTRODUCCIÓN
Una vez que se sabe cómo crear una GUI en Java, se pueden desarrollar
programas que tengan una mejor presentación visual.
más modernos, esta forma es muy simple, ya que se debe tener en cuenta las
distintas resoluciones de pantalla, las diferentes fuentes, las ventanas que los
usuarios pueden redimensionar, y otros aspectos que hacen difı́cil la distribu-
ción de los componentes. La solución es un esquema donde el programador
pueda indicar la disposición de los componentes en términos más generales.
Por ejemplo, se puede indicar que “este componente deberá estar debajo de
este otro” o que “este componente se estrechará cuando la ventana cambie
de tamaño pero este otro tendrá un tamaño constante”. Lo anterior se logra
usando los gestores de disposición.
El manejo de eventos se refiere a la técnica que se usa para responder
a las entradas del usuario. Una vez que los componentes han sido creado y
que han sido posicionados en la pantalla, es necesario asegurar de que ocurra
algo cuando el usuario presione un botón, por ejemplo. El modelo que usa la
biblioteca de Java para lograr lo anterior está basada en eventos: si un usuario
activa un componente, por ejemplo, por pulsar un botón o seleccionar un
elemento de un menú, el sistema generará un evento. Entonces, la aplicación
puede recibir una notificación del evento, mediante la invocación de uno de
sus métodos, y se puede llevar a cabo la acción adecuada.
Caso de estudio
Este caso de estudio está diseñado para iniciar el aprendizaje de las poten-
tes capacidades de Java para crear GUIs. Se muestran diez secciones breves,
en donde cada sección introduce unos cuantos conceptos básicos y propor-
ciona ejemplos visuales gráficos. En las secciones subsecuentes, se emplean
conceptos de la programación orientada a objetos para crear aplicaciones que
dibujan una variedad de figuras.
1 // Dialogo1.java
2 // Imprimiendo múltiples lı́neas en un cuadro de diálogo
3 import javax.swing.JOptionPane; // importar la clase JOptionPane
4
9
10 CAPÍTULO 2. CASO DE ESTUDIO
6
7 public static void main( String args[] ) {
8 // solicitar al usuario que ingrese un nombre
9 String nombre =
10 JOptionPane.showInputDialog( "¿Cuál es tu nombre?" );
11 // crear el mensaje
12 String mensaje = String.format(
13 "¡Bienvenido, %s, a la Programación con Java!", nombre );
14 // mostrar el mensaje de bienvenida al usuario
15 JOptionPane.showMessageDialog( null, mensaje );
16 } // fin de main
17 } // fin de la clase NombreDialogo
2.2.1. Ejercicios
1. Escribir un programa que use entradas y salidas con cuadros de diálogo
con los métodos de la clase JOptionPane para multiplicar dos números.
Como el método showInputDialog regrese un String, se deberá con-
vertir el String ingresado por el usuario a un tipo int para hacer el
cálculo. El método
Integer.parseInt( String s )
1 // Clase DibujaPanel.java
2 // Usando drawLine para conectar las esquinas de un panel.
3
4 import java.awt.Graphics;
5 import javax.swing.JPanel;
6
7 public class DibujaPanel extends JPanel {
8
9 // dibujar una X desde las esquinas del panel
10 public void paintComponent( Graphics g ) {
11
2.3. CREANDO DIBUJOS SIMPLES 13
1 // DibujaPanelPrueba.java
2 // Aplicación para montar un DibujaPanel.
3
4 import javax.swing.JFrame;
5
6 public class DibujaPanelPrueba {
7
8 public static void main( String args[] ) {
9
10 // crear un panel que contenga el dibujo
11 DibujaPanel panel = new DibujaPanel();
12
13 // crear un nuevo frame para contener al panel
2.3. CREANDO DIBUJOS SIMPLES 15
2.3.1. Ejercicios
1. Usando ciclos y sentencias de control dibujar lı́neas para obtener diseños
interesantes.
1 // ProbarFiguras.java
2 // Aplicación de prueba que muestra la clase Figuras
3
4 import javax.swing.JFrame;
5 import javax.swing.JOptionPane;
6
7 public class ProbarFiguras {
8
9 public static void main( String args[] ) {
10 // obtener la opción del usuario
11 String entrada = JOptionPane.showInputDialog(
18 CAPÍTULO 2. CASO DE ESTUDIO
2.4.1. Ejercicios
1. Dibujar 12 cı́rculos concéntricos en el centro de un JPanel. El cı́rculo
más interno deberá tener un radio de 10 pixeles, y cada cı́rculo sucesivo
deberá tener un radio de 10 pixeles más grande que el previo anterior.
Iniciar encontrando el centro del JPanel. Para obtener la esquina su-
perior izquierda de un cı́rculo moverse un radio hacia arriba y un radio
hacia la izquierda desde el centro. El ancho y el alto del rectángulo
acotador es el diámetro del cı́rculo (dos veces el radio).
para que se puedan crear colores hechos a la medida especificando los com-
ponentes individuales rojo, verde y azul de un color.
Los rectángulos y las elipses rellenas son dibujados con los métodos fillRect
y fillOval de la clase Graphics, respectivamente. Estos dos métodos tie-
nen los mismos parámetros como sus contrapartes sin rillenar drawRect y
drawOval; los primeros dos parámetros son las coordenadas para la esquina
superior izquierda de la figura, mientras los siguientes dos parámetros deter-
minan su ancho y alto. El código de enseguida crea una cara sonriente, ver
figura 2.1, empleando colores y figuras rellenas.
1 // CaraSonriente.java
2 // Muestra figuras rellenas
3
4 import java.awt.Color;
5 import java.awt.Graphics;
6 import javax.swing.JPanel;
7
8 class CaraSonriente extends JPanel {
20 CAPÍTULO 2. CASO DE ESTUDIO
9
10 public void paintComponent( Graphics g ) {
11 super.paintComponent( g );
12 // dibujar la cara
13 g.setColor( Color.YELLOW );
14 g.fillOval( 10, 10, 200, 200 );
15 // draw los ojos
16 g.setColor( Color.BLACK );
17 g.fillOval( 55, 65, 30, 30 );
18 g.fillOval( 135, 65, 30, 30 );
19 // dibujar la boca
20 g.fillOval( 50, 110, 120, 60 );
21 // "retocar" la boca en una sonrisa
22 g.setColor( Color.YELLOW );
23 g.fillRect( 50, 110, 120, 30 );
24 g.fillOval( 50, 120, 120, 40 );
25 } // fin del método paintComponent
26 } // fin de CaraSonriente
Las sentencias import en las lı́neas 4–6 del código anterior importan las
clases Color, Graphics y JPanel. La clase CaraSonriente, lı́neas 10–25, usa
la clase Color para especificar los colores de dibujo, y usa la clase Graphics
para dibujar. La clase JPanel proporciona el área en la cual se dibujará. En
la lı́nea 13 se emplea setColor de la clase Graphics para indicar el color
con el que se dibujará usando el color amarillo. El método setColor requiere
un argumento, el color que será puesto como el color para dibujar. La lı́nea
14 dibuja un cı́rculo con diámetro 200 para representar la cara. En la lı́nea
16 se pone el color negro, y las lı́neas 17 y 18 ponen los ojos. La boca se
dibuja con una elipse en la lı́nea 20, pero no tiene el diseño requerido. Para
2.5. FIGURAS RELLENAS Y COLORES 21
1 // PruebaCaraSonriente
2 // Probar aplicación que muestra cara sonriente
3
4 import javax.swing.JFrame;
5
6 public class PruebaCaraSonriente {
7
8 public static void main( String args[] ) {
9 CaraSonriente panel = new CaraSonriente();
10 JFrame aplicacion = new JFrame();
11 aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
12 aplicacion.add( panel );
13 aplicacion.setSize( 230, 250 );
14 aplicacion.setVisible( true );
15 } // fin de main
16 } // fin de la clase PruebaCaraSonriente
2.5.1. Ejercicios
1. Usando el método fillOval, dibujar una diana que alterne entre dos
colores aleatorios. Usar el constructor Color( int r, int g, int b)
con argumentos aleatorios para generar colores aleatorios.
1 // DibujaArcorIris.java
2 // Se muestra el uso de colores en un arreglo.
3 import java.awt.Color;
4 import java.awt.Graphics;
5 import javax.swing.JPanel;
6
7 class DibujaArcoIris extends JPanel {
8
9 // Definir el color ı́ndigo y violeta
10 final Color VIOLETA = new Color( 128, 0, 128 );
11 final Color INDIGO = new Color( 75, 0, 130 );
12
13 // Colores para el arco iris, iniciando con el mas interno.
14 // Las dos entradas en blanco dan un arco vacı́o en el centro
15 private Color colores[] = {
16 Color.WHITE, Color.WHITE, VIOLETA, INDIGO, Color.BLUE,
17 Color.GREEN, Color.YELLOW, Color.ORANGE, Color.RED
18 };
19
20 // constructor
21 public DibujaArcoIris() {
2.6. DIBUJO DE ARCOS 23
El código anterior inicia con las sentencias import usuales para crear los
dı́bujos, lı́neas 3–5. Las lı́neas 10–11 declaran y crean dos nuevos colores
–VIOLETA e INDIGO. Para los colores del arco iris en la clase Color se en-
cuentran definidos los primeros 5 de los 7 colores del arco iris. En las lı́neas
15–17 se inicializa un arreglo con los colores del arco iris, iniciando primero
con los arcos más internos. El arreglo inicia con dos elementos Color.WHITE,
los cuales son para dibujar los arcos vacı́os en el centro del arco iris. El cons-
tructor de las lı́neas 21–23 contiene una sola sentencia que llama al método
setBackground, el cual se hereda desde la clase JPanel, con el parámetro
Color.White. El método setBackground toma un solo argumento tipo Color
y fija el fondo del componente a ese color.
En la lı́nea 29 se declara la variable local radio, la cual determina el
radio de cada arco. Las variables locales centroX y centroY, lı́neas 32–33,
determinan la localidad del punto medio en la base de la ventana. El ciclo en
las lı́neas 36–43 usa la variable de control i para contar hacia atrás a partir
del final del arreglo, dibujando los arcos más grandes primero y colocando
arcos más pequeños sucesivante al frente del previo. En la lı́nea 38 se fija el
24 CAPÍTULO 2. CASO DE ESTUDIO
1 // PruebaDibujaArcoIris.java
2 // Aplicación de prueba para mostrar un arco iris.
3
4 import javax.swing.JFrame;
5
6 public class PruebaDibujaArcoIris {
7
8 public static void main( String args[] ) {
9 DibujaArcoIris panel = new DibujaArcoIris();
10 JFrame aplicacion = new JFrame();
11 aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
12 aplicacion.add( panel );
13 aplicacion.setSize( 400, 250 );
14 aplicacion.setVisible( true );
15 } // fin del main
16 } // fin de la clase PruebaDibujaArcoIris
2.6.1. Ejercicios
1. En el ejercicio, se dibujarán espirales, ver figura 2.3, con los métodos
drawLine y drawArc. Las espirales deberán cubrir todo el panel, no
debe haber zonas sin llenar al redimensionar la ventana.
2.7. USANDO OBJETOS CON GRÁFICAS 25
para guardar las lı́neas a dibujar. Dentro del constructor, lı́neas 14–35, en la
lı́nea 15 se fija el color del fondo a Color.WHITE. La lı́nea 17 crea el arreglo
con una longitud aleatoria entre 5 y 9. El ciclo, en las lı́neas 20–34 crea un
nuevo MiLinea para cada elemento en el arreglo. Las lı́neas 22–25 generan
coordenadas aleatorias para cada los extremos de cada lı́nea, en las lı́neas
28–30 se genera un color aleatorio para la lı́nea. En la lı́nea 33 se crea un
nuevo objeto MiLinea con los valores generados aleatoriamente y se guarda
este en el arreglo.
El método paintComponent itera con los objetos MiLinea en el arre-
glo lineas usando una versión mejorada del ciclo for, lı́neas 41–42. Cada
iteración llama el método dibujar del objeto actual MiLinea y le pasa el ob-
jeto Graphics para dibujarlo en el panel. La clase PruebaDibujo, siguiente
código, configura una nueva ventana para mostrar el dibujo. Como se están
fijando las coordenadas para las lı́neas solamente una vez en el constructor,
el dibujo no cambia si paintComponent es llamado para refrescar el dibujado
en la pantalla.
1 // DibujaPanel.java
2 // Programa que usa la clase MiLinea
3 // para dibujar lı́neas aleatorias
4 import java.awt.Color;
5 import java.awt.Graphics;
6 import java.util.Random;
7 import javax.swing.JPanel;
8
9 public class DibujaPanel extends JPanel {
10 private Random numerosAleatorios = new Random();
11 private MiLinea lineas[]; // arreglo de lı́neas
12
13 // constructor, crea un panel con figuras aleatorias
14 public DibujaPanel() {
15 setBackground( Color.WHITE );
16
17 lineas = new MiLinea[ 5 + numerosAleatorios.nextInt( 5 ) ];
18
19 // crear lı́neas
20 for ( int i = 0; i < lineas.length; i++ ) {
21 // generar números aleatorios
22 int x1 = numerosAleatorios.nextInt( 300 );
23 int y1 = numerosAleatorios.nextInt( 300 );
24 int x2 = numerosAleatorios.nextInt( 300 );
25 int y2 = numerosAleatorios.nextInt( 300 );
28 CAPÍTULO 2. CASO DE ESTUDIO
26
27 // generar un color aleatorio
28 Color color = new Color( numerosAleatorios.nextInt( 256 ),
29 numerosAleatorios.nextInt( 256 ),
30 numerosAleatorios.nextInt( 256 ) );
31
32 // agregrar la lı́nea a la lista de lı́neas que serán mostradas.
33 lineas[ i ] = new MiLinea( x1, y1, x2, y2, color );
34 } // fin del for
35 } // fin del constructor DrawPanel
36
37 // para cada figura del arreglo, dibujar las figuras individuales
38 public void paintComponent( Graphics g ) {
39 super.paintComponent( g );
40 // dibujar las lı́neas
41 for ( MiLinea linea : lineas )
42 linea.dibujar( g );
43 } // fin del método paintComponent
44 } // fin de la clase DibujaPanel
1 // PruebaDibuja.java
2 // Aplicación de prueba para mostrar un DibujaPanel.
3
4 import javax.swing.JFrame;
5
6 public class PruebaDibujo {
7
8 public static void main( String args[] ) {
9
10 DibujaPanel panel = new DibujaPanel();
11 JFrame application = new JFrame();
12
13 application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
14 application.add( panel );
15 application.setSize( 300, 300 );
16 application.setVisible( true );
17 } // fin de main
18 } // fin de la clase PruebaDibujo
2.7.1. Ejercicios
1. Extender el programa de esta sección para dibujar aleatoriamente rectángu-
los y elipses. Crear las clases MiRectangulo y MiElipse. Ambas clases
deberán incluir coordenadas x1, y1, x2, y2, un color y un valor boo-
2.7. USANDO OBJETOS CON GRÁFICAS 29
1 // LabelDemo.java
2 // Muestra el uso de etiquetas
3 import java.awt.BorderLayout;
4 import javax.swing.ImageIcon;
5 import javax.swing.JLabel;
6 import javax.swing.JFrame;
7
8 public class LabelDemo {
9
10 public static void main( String args[] ) {
11 // crear una etiqueta plana con texto
12 JLabel etiquetaNorte = new JLabel( "Norte" );
13
14 // crear un icono desde una imagen para ponerlo en un JLabel
15 ImageIcon iconoEtiqueta = new ImageIcon( "gnome-gnibbles.png" );
16
17 // crear una etiqueta con un icono en vez de texto
18 JLabel etiquetaCentro = new JLabel( iconoEtiqueta );
19
20 // crear otra etiqueta con un icono
21 JLabel etiquetaSur = new JLabel( iconoEtiqueta );
22
23 // configurar etiqueta para mostrar texto, al igual que el icono
24 etiquetaSur.setText( "Sur" );
25
26 // crear una ventana para poner las etiquetas
27 JFrame aplicacion = new JFrame();
28
29 aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
30
31 // agregar las etiquetas a la ventana, el segundo argumento indica
32 // en que lugar de la ventana se pondra la etiqueta
33 aplicacion.add( etiquetaNorte, BorderLayout.NORTH );
34 aplicacion.add( etiquetaCentro, BorderLayout.CENTER );
2.8. TEXTO E IMÁGENES CON ETIQUETAS 31
En las lı́neas 3–6 se importan las clases que se requieren para mostrar las
etiquetas. BorderLayout del paquete java.awt tiene constantes para indicar
donde se pueden colocar componentes GUI en un JFrame. La clase ImageIcon
representa una imagen que puede ser mostrada en un JLabel, y la clase
JFrame representa la ventana que contendrá todas las etiquetas.
La lı́nea 12 crea un JLabel que muestra su argumento para el constructor
—la cadena "Norte". La lı́nea 15 declara la variable local iconoEtiqueta
y le asigna un nuevo ImageIcon. El constructor para ImageIcon recibe una
cadena que indica el camino a la imagen. Como solamente se indica un nom-
bre de archivo, Java supone se encuentra en el mismo directorio de la cla-
se LabelDemo. ImageIcon puede cargar imágenes en formato GIF, JPEG y
PNG. La lı́ena 18 declara e inicializa la variable local etiquetaCentro con
un JLabel que muestra a iconoEtiqueta. Sin embargo, en la lı́nea 24 se
llama al método setText para cambiar el texto que la etiqueta muestra. El
método setText puede ser llamado por cualquier JLabel para cambiar su
texto. Este JLabel mostrará el icono y el texto.
En la lı́nea 27 se crea un JFrame que mostrará los JLabels, y la lı́nea
29 indica que el programa deberá terminar cuando el JFrame se cierre. Se
ponene las etiquetas en la ventana en las lı́neas 33–35 llamando una versión
sobrecargada del método add que toma dos parámetros. El primer método es
el componente que se quiere poner, y el segundo es la región en la cual este
deberá ser puesto. Cada JFrame tiene asociado un manejador que ayuda en
la posición de los componentes que tiene puestos. El manejado por defecto
para un JFrame es el conocido como BorderLayout y tiene cinco regiones —
NORTH (superior), SOUTH (inferior), EAST (lado derecho), WEST (lado izquierdo)
y CENTER (centro). Cada uno de estos está declarado como una constante en
la clase BorderLayout. Cuando se llama al método add con un argumento,
el JFrame coloca al componente usando CENTER automáticamente. Si una
posición ya contenı́a un componente, entonces el nuevo componente toma su
lugar. En las lı́neas 27 y 39 se pone el tamaño de la ventana y se hace visible
en pantalla.
32 CAPÍTULO 2. CASO DE ESTUDIO
2.8.1. Ejercicio
1. Modificar el ejercicio 1 de la sección 2.7.1 para incluir un JLabel como
una barra de estado que muestre la cantidad de cada figura dibujada,
podrı́a tener un texto como: ”Lı́neas 3, Elipses 2, Rectángulos 4 ”. La
clase DibujaPanel deberá declarar un método que regrese una cadena
conteniendo el texto del estado. En el método main, primero crear el
DibujaPanel, después crear el JLabel con el texto del estado como
un argumento del constructor JLabel. Poner el JLabel en la región
inferior de la ventana.
2.9.1. Ejercicios
1. Modificar las clases MiLinea, MiElipse y MiRectangulo del ejercicio
uno de la sección 2.7.1 y 2.8.1 para crear la siguiente jerarquı́a de clases:
método dibujar sin saber exactamente que figura es. Los datos re-
presentando las coordenadas y el color de las figuras en la jerarquı́a
deberán ser declarados como miembros private de la clase MiFigura.
Además de los datos comunes, la clase MiFigura deberá declarar los
siguientes métodos:
[1] H. M. Deitel, Java How to Program, Sevent Edition, Prentice Hall, 2007.
35