programacion en java java swing parte i

Transcripción

programacion en java java swing parte i
UNIVERSIDAD DE EL SALVADOR
ESCUELA DE INGENIERIA DE SISTEMAS INFORMATICOS
PROGRAMACION III
PROGRAMACION EN JAVA
JAVA SWING
PARTE I
Contenido
Java Swing ................................................................................................................................................ 1
Mensajes de diálogo .............................................................................................................................. 1
Ejemplo Login....................................................................................................................................... 4
JFrame ................................................................................................................................................... 5
JLable .................................................................................................................................................... 7
JTextField .............................................................................................................................................. 9
JButton ................................................................................................................................................ 12
Componentes personalizados .................................................................................................................. 13
El administrador de disposición (Layout Manager) ............................................................................ 16
Eventos ................................................................................................................................................ 20
Ejemplo1 Registro de huéspedes ............................................................................................................ 22
TableModel ......................................................................................................................................... 25
Java Swing
Los programas que utilizan exclusivamente interfaces de usuario través de System.in y System.out son llamados
programas de consola. Los programas basados en interfaces gráficas (Graphical User Interfaces, GUI) en Java
son desarrollados a través de un conjunto de clases de los paquetes estándar javax.swing y java.awt. Estos
programas son usualmente llamados programas de escritorio.
Los programas de escritorio utilizan una serie de ventas para su funcionamiento. Un ejemplo de este tipo de
entornos es el mostrado en la figura 1.1.
JFrame
JMenu
JLabel
JText
JButton
Figura 1.1: Formulario realizado con Swing con algunos componentes de la librería
Mensajes de diálogo
Una forma intuitiva de escribir programar con entorno de ventanas, es usando la case JOptionPane, que ya
hemos utilizado en laboratorios anteriores. El código
JOptionPane.showMessageDialog(null, “Programación III);
Nos permite mostrar una ventana en la que podemos mostrar un contenido en forma de String.
1
Para conocer las constantes, atributos y métodos de los que consta alguna clase de Java, basta con consultar el
API (Application Programming Interface) de dicha clase. NetBeans integra la documentación disponible para las
clases en su ayuda contextual. Sin embargo, para que Netbeans pueda mostrar la documentación de dicha clase,
la librería donde se encuentra dicha clase debe incluir dicha documentación.
En la ventana de edición de Netbeans podemos acceder a las declaraciones de los métodos escribiendo
parcialmente el comando y presionando control+spacebar
Otra forma de acceder a la documentación puede ser consultado a través de Intenet, en la dirección:
http://docs.oracle.com/javase/7/docs/api/
2
En el API puede observarse que el método showMessageDialog es un método sobrecargado. Es decir, que tiene
varias definiciones y puede ser utilizado de varias formas.
El API de un conjunto de clases en Java generalmente generado a través del paquete Javadoc, que utiliza la
documentación realizada por el programador para generar la documentación en formato html.
La forma trivial del método showMessageDialog tiene la siguiente descripción Brings up an informationmessage dialog titled “Message” (Muestra un cuadro de diálogo de información o mensaje con el título
“Mensaje”). Recibe como parámetros la variable parentComponent (componente padre), de tipo Component, que
determina el Frame (ventana) en la que el dialogo será mostrado. Si es null, o si el parentComponent no tine
Frame, será usado el Frame por defecto.
El parámetro message, de tipo Object es el mensaje que se desplegará.
En este caso, hemos enviado null al parámetro parentComponent (componente padre), lo que significa que la
ventana será mostrada de forma independiente de cualquier otra ventana que se esté mostrando.
3
Para leer valores desde un cuadro de diálogo usamos el método showInputMessage, que despliega un cuadro de
diálogo con una cuadro de texto que permite ingresar valores. Sin embargo, el valor leído por le método y
devuelto como valor de retorno es de tipo String. Para resolver el problema de los valores numéricos, se utilizan
las llamadas clases de envoltorio (Wrapper) que permiten convertir valores String a tipos primitivos o en algunos
casos objetos de dichas clases.
Los métodos más usados para realizar esta conversión se describen en la tabla 1.1
Clase
Tabla 1.1: Métodos para
conversión de valores en
formato String a formatos
numéricos.
Método
Ejemplo
Integer
parseInt
Integer.parseInt(“25”) → 25
Integer.parseInt(“25.3”) → error
Long
parseLong
Long.parseLong(“25”) → 25L
Long.parseLong(“25.3”) → error
Float
parseFloat
Float.parseFloat(“25.3”) → 25.3F
Float.parseFloat(“ab3”) → error
Double
parseDouble
Double.parseDouble(“25”) → 25.0
Double.parseDouble(“ab3”) → error
String sNota = JOptionPane.showInputDialog("¿Cuánto sacaste en el examen de Programación III?");
float fNota = Float.parseFloat(sNota);
JOptionPane.showMessageDialog(null, fNota);
Para desarrollar aplicaciones de escritorio más completas, otras clases del paquete de clases javax.swing, que
permiten crear interfaces de usuario más complejas.
Ejemplo Login
Construyendo un formulario
Supongamos que tenemos el siguiente caso de uso como requerimiento para un programa.
4
Nombre:
Ingresar al sistema
Autor:
PRN315
Descripción:
Verificar las credenciales de acceso al sistema para permitir su acceso.
Actores:
Usuario
Precondiciones:
Flujo normal de los eventos:
1. El usuario solicita el ingreso al sistema
2. El sistema muestra la pantalla de ingreso con el nombre del usuario y la clave.
3. El actor ingresa los datos solicitados
4. Los datos son válidos, el sistema despliega el mensaje: Bienvenido al sistema
Flujos alternativos:
4.1 Las credenciales no son correctas, el sistema despliega el mensaje: Ud. no tiene las credenciales necesarias
para ingresar.
Postcondiciones:
JFrame
La clase JFrame es usada principalmente como
contenedor de otros componentes Swing.
Crearemos un JFrame al que iremos incorporando los
elementos solicitados por el enunciado.
Usaremos el constructor de JFrame que recibe como
parámetro una cadena de caracteres como el título del JFrame.
Si consultamos el API de la clase JFrame, veremos que cuenta con un método setSize, donde uno de sus formas,
recibe dos parámetros que conformarán el tamaño de la ventana en pixeles.
5
package prn315.guia03;
import javax.swing.JFrame;
public class EjemploFrame {
public static void main(String[] args){
JFrame frame = new JFrame("Pantalla de ingreso al sistema");
frame.setSize(300, 300);
frame.setVisible(true);
}
}
La ventana que hemos construido hasta ahora se verá como se muestra en la figura 2.1
Figura 2.1 Frame con título y sin contenido
La apariencia del frame está basada en el tema del sistema operativo sobre el que está ejecutándose el programa.
Para usar la decoración por defecto de las interfaces Java, debemos invocar al método estático
setDefaultLookAndFeelDecorated. Por ser un método de clase, esta configuración será aplicada a todos los
Frames que sean generados por el programa.
6
JLable
JLabel es una extensión de JComponent, por lo que tiene todas
las características de un componente Swing.
Crearemos el label usando el constructor que recibe como
parámetro el texto a mostrar. Una vez creado, agregaremos el
label al frame a través del método add, donde una de sus
implementaciones recibe como parámetro un componente.
public class EjemploFrame {
public static void main(String[] args){
final int FRAME_WITH = 300;
final int FRAME_HEIGTH = 300;
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Pantalla de ingreso al sistema");
frame.setSize(FRAME_WITH, FRAME_HEIGTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
JLabel lUsuario = new JLabel("Nombre de usuario: ");
frame.add(lUsuario);
}
}
Este es un ejemplo muy práctico del polimorfismo, ya que el método add utilizado, recibe como parámetro un
objeto de tipo Component, pero en nuestro código estamos agregando un objeto de tipo JLabel. Esto es posible
debido a que JLabel es una clase derivada de Component (una herencia de tercer nivel). Cualquier objeto de una
clase que herede de Component puede ser enviada como parámetro al método add.
7
El frame resultante después de los cambios tendrá la forma que se muestra en la figura 2.2
Figura 2.2 Frame de ingreso al sistema, con label para el nombre del usuario.
Nótese que también hemos establecido el cierre del programa, como la operación por defecto al cerrar el frame
(setDefaultCloseOperation). Esto es útil puesto que si no se establece esa acción, el programa quedará
ejecutándose aunque ya no veamos el frame.
8
JTextField
De una forma similar a como se agregó el label,
agregaremos un campo de texto para capturar el
nombre del usuario.
public class EjemploFrame {
public static void main(String[] args){
final int FRAME_WITH = 300;
final int FRAME_HEIGTH = 300;
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Pantalla de ingreso al sistema");
frame.setSize(FRAME_WITH, FRAME_HEIGTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
JLabel lUsuario = new JLabel("Nombre de usuario: ");
JTextField tUsuario = new JtextField(“Ingrese aquí el usuario”);
//Agregando componentes creados
frame.add(lUsuario);
frame.add(tUsuario);
}
}
Al ejecutar este código, ocurre un problema con el orden en que se muestran los componentes. El frame
únicamente muestra el campo de texto que es visible gracias a que se usó el constructor que le entrega un texto
por defecto.
Para resolver esto, debemos acudir al administrador de la disposición de los componentes. Usando el layout
básico para un componente JFrame.
9
public class EjemploFrame {
public static void main(String[] args){
final int FRAME_WITH = 300;
final int FRAME_HEIGTH = 300;
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Pantalla de ingreso al sistema");
frame.setSize(FRAME_WITH, FRAME_HEIGTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lUsuario = new JLabel("Nombre de usuario: ");
JTextField tUsuario = new JTextField("Ingrese aquí el usuario");
frame.setLayout(new FlowLayout());
//Agregando componentes creados
frame.add(lUsuario);
frame.add(tUsuario);
frame.setVisible(true);
}
}
Figura 2.3 Frame de ingreso al sistema con
dos controles.
10
Agregaremos ahora un campo de texto para capturar el password del usuario y un label que indique que se trata
de un control para el password.
public class EjemploFrame {
public static void main(String[] args) {
final int FRAME_WITH = 300;
final int FRAME_HEIGTH = 300;
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Pantalla de ingreso al sistema");
frame.setSize(FRAME_WITH, FRAME_HEIGTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lUsuario = new JLabel("Nombre de usuario:");
JTextField tUsuario = new JTextField("Ingrese aquí el usuario");
JLabel lPassword = new JLabel("Password:");
JTextField tPassword = new JTextField("Ingrese aquí el password");
frame.setLayout(new FlowLayout());
//Agregando componentes creados
frame.add(lUsuario);
frame.add(tUsuario);
frame.add(lPassword);
frame.add(tPassword);
frame.setVisible(true);
}
}
11
JButton
La clase JButton permite crear componentes de tipo
botón. Al igual que el resto de los componentes
usados hasta ahora, cuenta con una serie de
constructores dentro de los que se encuentra un
constructor que recibe como parámetro el texto que
se mostrará con el botón.
Usaremos este constructor para agregar los botones
Aceptar y Cancelar al formulario.
public class EjemploFrame {
public static void main(String[] args) {
final int FRAME_WITH = 300;
final int FRAME_HEIGTH = 300;
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Pantalla de ingreso al sistema");
frame.setSize(FRAME_WITH, FRAME_HEIGTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lUsuario = new JLabel("Nombre de usuario:");
JTextField tUsuario = new JTextField("Ingrese aquí el usuario");
JLabel lPassword = new JLabel("Password:");
JTextField tPassword = new JTextField("Ingrese aquí el password");
JButton bAceptar = new JButton("Aceptar");
JButton bCancelar = new JButton("Cancelar");
frame.setLayout(new FlowLayout());
//Agregando componentes creados
frame.add(lUsuario);
frame.add(tUsuario);
frame.add(lPassword);
frame.add(tPassword);
frame.add(bAceptar);
frame.add(bCancelar);
frame.setVisible(true);
}
}
12
Figura 2.4 Frame de ingreso al sistema, con controles de entrada.
Componentes personalizados
Hasta ahora hemos creado una clase a través de la cual hemos creado un frame y agregado controles Swing a él.
Sin embargo, si quisiéramos utilizar este frame más de una vez y personalizarlo para cada ocasión, deberemos
crear copiar el código que hemos escrito cuantas veces lo necesitamos y personalizarlo. Para resolver este
problema, podemos extender los componentes Swing para crear nuestros propios componentes. La creación de
componentes personalizados se realiza extendiendo los componentes básicos Swing.
13
package prn315.guia03;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class EjemploFrameExtendido extends JFrame {
final int ANCHO = 300;
final int ALTO = 300;
private JLabel lUsuario;
private JTextField tUsuario;
private JLabel lPassword;
private JTextField tPassword;
private JButton bAceptar;
private JButton bCancelar;
public EjemploFrameExtendido(String titulo) {
super(titulo);
initComponent();
}
...
14
private void initComponent() {
lUsuario = new JLabel("Nombre de usuario:");
tUsuario = new JTextField("Ingrese aquí el usuario");
lPassword = new JLabel("Password:");
tPassword = new JTextField("Ingrese aquí el password");
bAceptar = new JButton("Aceptar");
bCancelar = new JButton("Cancelar");
setSize(ANCHO, ALTO);
setLayout(new FlowLayout());
add(lUsuario);
add(tUsuario);
add(lPassword);
add(tPassword);
add(bAceptar);
add(bCancelar);
}
}
package prn315.guia03;
public class TestFrameExtendido {
public static void main(String[] args){
EjemploFrameExtendido frame = new EjemploFrameExtendido("Pantalla principal");
frame.setVisible(true);
}
}
Con el código anterior logramos la misma pantalla. Sin embargo, hemos construido nuestro propio componente
Swing, que podríamos utilizar de múltiples formas y proyectos.
15
El administrador de disposición (Layout Manager)
Hemos definido el ancho del frame en 300 pixeles, lo que hace que los componentes que se agregan al frame
tengan una disposición aceptable para el tipo de formulario que estamos editando. Sin embargo, si ampliamos el
ancho del frame, los componentes van alineándose horizontalmente debido a que la disposición configurada a
través de la clase FlowLayout no permite configurar una disposición en filas y columnas.
Existen varias clases para realizar esta configuración. Sin embargo, la clase que ofrece más flexibilidad para este
fin es la clase GroupLayout, que aunque muy útil, resulta muy compleja en cuanto a su uso.
package prn315.guia03;
import java.awt.FlowLayout;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class EjemploFrameExtendido extends JFrame {
final int ANCHO = 300;
final int ALTO = 300;
private JLabel lUsuario;
private JTextField tUsuario;
private JLabel lPassword;
private JTextField tPassword;
private JButton bAceptar;
private JButton bCancelar;
public EjemploFrameExtendido(String titulo) {
super(titulo);
initComponent();
}
private void initComponent() {
lUsuario = new JLabel("Nombre de usuario:");
tUsuario = new JTextField("Ingrese aquí el usuario");
lPassword = new JLabel("Password:");
tPassword = new JTextField("Ingrese aquí el password");
bAceptar = new JButton("Aceptar");
bCancelar = new JButton("Cancelar");
...
16
setSize(ANCHO, ALTO);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GroupLayout layout = new GroupLayout(getContentPane());
setLayout(layout);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
hGroup.addGroup(layout.createParallelGroup().addComponent(lUsuario).addComponent(lPassword).addComponent(bAcept
ar));
hGroup.addGroup(layout.createParallelGroup().addComponent(tUsuario).addComponent(tPassword).addComponent(bCanc
elar));
layout.setHorizontalGroup(hGroup);
GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(lPassword).addComponent(tPassword)
);
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(lUsuario).addComponent(tUsuario));
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(bAceptar).addComponent(bCancelar));
layout.setVerticalGroup(vGroup);
}
}
Figura 2.3 Frame extendido de ingreso al sistema
Hasta ahora hemos realizado nuestro formulario escribiendo nuestro propio código, lo que resulta no solamente
complejo, sino además podría requerir mucho tiempo de trabajo. Por ello, los IDEs de programación, en nuestro
caso NetBeans, nos ofrecen entornos de diseño de formularios, que nos permiten crear formularios de forma
gráfica.
17
Cuando creamos un formulario en este entorno, el IDE se ocupa de generar el código necesario para que el
formulario funcione adecuadamente.
Para crear un formulario análogo al que hemos creado, debemos crear no una clase Java tradicional, sino un
formulario JFrame. Para ello, hacer clic derecho en el nodo del paquete en el que queremos crear nuestro
formulario, elegir la opción Other (Otros). En el cuadro de diálogo que aparece, debemos elegir la opción Swing
GUI Forms y en el panel de la derecho elegir JFrame Form.
En este entorno nos aparece una pestaña llamada Paleta de controles donde el IDE nos permite elegir los
controles que deseamos usar.
Para agregar un componente al formulario, basta con elegirlo de la paleta y arrastrar el puntero del ratón al lugar
donde lo queremos colocar.
El IDE además nos mostrará las propiedades del objeto que se encuentre seleccionado, por defecto debajo de la
paleta de controles.
Puede observarse que el área de trabajo consta de tres pestañas para la edición del formulario: Source (o Fuente)
que muestra el código fuente de nuestro formulario, Design (Diseño) que permite realizar el diseño del
formulario a través de los controles que se encuentran en la paleta y History (Historial), que permite ver los
cambios realizados en el código.
Al seleccionar el frame, podemos observar las propiedades que se encuentran disponibles en tiempo de diseño.
Entre estas propiedades está el título (title) del frame. Algo que hicimos en el ejemplo anterior a la hora de
construir el frame.
18
Entre otras cosas, el entorno de edición nos permite definir la posición específica de los componentes que
agregamos y sus propiedades.
19
Para verificar como se verá en tiempo de ejecución el formulario, no es necesario ejecutar el proyecto, basta con
presionar el botón Previsualizar el diseño que nos mostrará la ventana que estamos editando.
Eventos
Un evento es una acción realizada por alguno de los actores del sistema: llenar un campo de texto, redimensionar
una ventana, hacer clic en un botón, etc. El modelo utilizado por Java para manejar los eventos es llamado
Modelo de delegación de eventos. En este modelo, los eventos son implementados en dos tipos de objetos:
objetos que originan eventos y objetos que escuchan eventos.
Un objeto GUI, como un botón, es un objeto de tipo origen de eventos. Si un usuario hace clic sobre el botón,
este generará un evento (action event). Un objeto escuchador de eventos o simplemente escuchador de eventos
es el objeto en el que se encuentran definidos los métodos que se ejecutarán en respuesta a ese evento. También
es posible encontrar ambos comportamientos en un mismo objeto.
En el formulario que ya hemos construido, programaremos la respuesta que dará el sistema al evento clic del
botón aceptar. Si el nombre del usuario es alumno y la clave prn315 (no importando si es minúscula o
mayúscula), deberá de mostrar el mensaje: “Bienvenido al sistema”. Si se escribe cualquier otra combinación, el
formulario deberá desplegar el mensaje: “Ud. no tiene las credenciales para entrar”.
Para programar el evento, hacemos clic derecho sobre el botón aceptar y elegimos la opción Events (Eventos),
Actions (Acciones) y ActionPerformed (Acción a realizar), en el entorno de diseño del formulario. NetBeans nos
creará un método llamado jButton1ActionPerformed que recibe como parámetro un objeto de la clase
ActionEvent, ya que este es el tipo de evento que se genera con el clic en el botón.
Nótese que en este caso, el botón es un objeto generador de eventos, el mismo botón se convierte en el
escuchador de eventos a través del método recién creado, por lo que requiere recibir un objeto de tipo evento.
20
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
if(jTextField1.getText().toUpperCase().equals("ALUMNO") && jTextField2.getText().toUpperCase().equals("PRN315")){
JOptionPane.showMessageDialog(this, "Bienvenido al sistema");
}else{
JOptionPane.showMessageDialog(this, "Ud. no tiene las credenciales para entrar");
}
}
Nótese que en este caso, hemos enviado como componente padre del mensaje al frame que estamos editando,
por lo que el cuadro de diálogo se mostrará como una ventana interna del frame, y no independiente como
ocurría cuando le enviamos null como parámetro.
21
Ejemplo1 Registro de huéspedes
Nombre:
Registrar cliente
Autor:
PRN315
Descripción:
Permite registrar a un cliente que desea hospedarse en el hotel
Actores:
Recepcionista
Precondiciones:
El actor debe haberse logeado en el sistema
Flujo normal de los eventos:
1 .El actor ingresa al sistema para ver si existen habitaciones disponibles
2. El sistema muestra una lista con las habitaciones que se encuentran disponibles con los siguientes datos:
Número de habitación, Nivel en el que se encuentra, Tipo de habitación: Doble, Sencilla o Triple y el precio por
defecto.
3. El actor selecciona la habitación que desee reservar/entregar al cliente.
4. El sistema muestra una pantalla de registro del cliente, en la que deberá de ingresarse: Nombre del cliente,
Fecha y Nacionalidad.
5. El actor ingresa los datos solicitados y guarda la información.
6. El sistema muestra un mensaje de confirmación.
Flujos alternativos:
3.1 No hay habitaciones disponibles, se cancela la operación.
4.1 El actor cancela la operación.
4.2 El sistema muestra el mensaje “Operación cancelada por el usuario”
Postcondiciones:
Primero diseñaremos el formulario de consulta. Para simplificar el problema, asumiremos que la consulta
siempre mostrará las habitaciones disponibles. Llamaremos a este formulario ConsultaHabitaciones.
22
El formulario deberá tener un label con el texto Habitaciones disponibles y una tabla de cuatro columnas.
Usaremos el componente JTable para mostrar los datos.
Al hacer clic derecho sobre la tabla, y elegir la opción Table content (o Contenido de la tabla), aparecerá un
cuadro de diálogo que permite especificar el contenido que mostrará la tabla. La opción por defecto es User
specified (especificado por el usuario). Esto habilita la definición de la cantidad de columnas y la cantidad de
filas que tendrá la tabla y sus valores.
23
24
Este método, aunque sencillo, hace que los valores que hemos ingresado en el cuadro de diálogo sean mostrados
en todas la ejecuciones, y que además, no sean susceptibles a cambios, hasta el momento de la ejecución del
formulario, siempre que sea programado un evento para ello.
El código que permitiría agregar una fila con datos, al hacer clic sobre un botón que llamaremos jBAgregarFila,
se muestra a continuación.
private void jBAgregarFilaActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
DefaultTableModel temp = (DefaultTableModel) jTable1.getModel();
Object nuevo[] = {"5D", new Integer(5), new Integer(3), new Double(50)};
temp.addRow(nuevo);
}
TableModel
Para que los datos mostrados por la tabla sean dinámicos, usaremos un TableModel (modelo de tabla), que define
las características que debe cumplir un conjunto de datos, para poder ser mostrados por la tabla.
Para ello, definiremos como modelo de la tabla el tipo Custom code (código personalizado), y asignaremos al
modelo de la tabla, la variable modeloHabitaciones.
Como es lógico, la variable modeloHabitaciones debe existir en el formulario que estamos editando (que es una
clase). Para ello, debemos primero crear la clase ModeloHabitaciones, que debe extender la clase abstracta
AbstracTableModel.
Una de las características que debe cumplir es tener una colección de habitaciones, que son los datos que se
mostrarán. Esa colección puede ser de cualquier clase que implemente la interfaz Iterable (Un arreglo común, un
objeto Collection, un objeto List, un objeto Iterator, etc).
El modelo conceptual de clases que necesitaremos programar para resolver de esta forma el problema, se
muestra a continuación.
25
Podemos observar que se requiere la programación de una clase Habitación, una clase que de soporte al modelo
de la tabla específicamente para las habitaciones, y una clase principal para ejecutar el programa.
26
package prn315.guia03.ejemplohotel;
public class Habitacion {
private String numero;
private int nivel;
private int tipo;
private double precio;
public String getNumero() {
return numero;
}
public void setNumero(String numero) {
this.numero = numero;
}
public int getNivel() {
return nivel;
}
public void setNivel(int nivel) {
this.nivel = nivel;
}
public int getTipo() {
return tipo;
}
public void setTipo(int tipo) {
this.tipo = tipo;
}
public double getPrecio() {
return precio;
}
public void setPrecio(double precio) {
this.precio = precio;
}
}
27
package prn315.guia03.ejemplohotel;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
public class HabitacionTableModel extends AbstractTableModel{
List<Habitacion> habitaciones = new ArrayList<Habitacion>();
private String tiposHabitacion[] = {"Sencilla", "Doble", "Triple"};
@Override
public int getRowCount() {
return habitaciones.size();
}
@Override
public int getColumnCount() {
return 4;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object valor = null;
switch(columnIndex){
case 0: valor = habitaciones.get(rowIndex).getNumero();
break;
case 1: valor = habitaciones.get(rowIndex).getNivel();
break;
case 2:
int iTipo = habitaciones.get(rowIndex).getTipo();
valor = tiposHabitacion[iTipo-1];
break;
case 3: valor = habitaciones.get(rowIndex).getPrecio();
}
return valor;
}
}
28
En el formulario que ya hemos creado, al que hemos llamado ConsultaHabitaciones, debemos agregar el atributo
modeloHabitaciones, como se muestra en el siguiente código.
package prn315.guia03.ejemplohotel;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class ConsultaHabitaciones extends javax.swing.JFrame {
/*
* Atributo modeloHabitaciones, usado con modelo de la tabla
*/
HabitacionTableModel modeloHabitaciones = new HabitacionTableModel();
Para ejecutar el proyecto deberemos programar la clase Principal, con el siguiente código.
29
package prn315.guia03.ejemplohotel;
import java.util.Random;
public class Principal {
public static void main(String[] args) {
final String[] UNIDADES = {"A ", "B", "C", "D", "E"};
Random random = new Random(new Long(13));
ConsultaHabitaciones consultas = new ConsultaHabitaciones();
for (int i = 0; i< 5; i++) {
Habitacion habitacion = new Habitacion();
habitacion.setNivel(i + 1);
habitacion.setNumero(UNIDADES[i] + (i+2));
habitacion.setTipo(1);
habitacion.setPrecio(random.nextDouble() * 105);
consultas.modeloHabitaciones.habitaciones.add(habitacion);
}
consultas.setVisible(true);
}
}
Nótese que el lazo for sirve para generar objetos de habitaciones de forma dinámica, que son agregados a la lista
de habitaciones, que será asignado posteriormente al objeto del modelo que deberá mostrarlos.
Al ejecutar el programa, mostrará la pantalla que se muestra a continuación.
30
Nótese que los encabezados de las columnas tienen valores A, B, C y D. Esto ocurre porque no se han definido
los títulos de las columnas del modelo de tabla. Para resolver este problema, agregaremos un método de
inicialización de los encabezados de las columnas de la tabla, como se muestra a continuación.
31
public class ConsultaHabitaciones extends javax.swing.JFrame {
HabitacionTableModel modeloHabitaciones = new HabitacionTableModel();
/**
* Creates new form ConsultaHabitaciones
*/
public ConsultaHabitaciones() {
initComponents();
inicializarColumnas();
}
private void inicializarColumnas() {
TableColumnModel tColumnModel = new DefaultTableColumnModel();
for (int i = 0; i < 4; i++) {
TableColumn col = new TableColumn(i);
switch (i) {
case 0:
col.setHeaderValue("Número");
break;
case 1:
col.setHeaderValue("Nivel");
break;
case 2:
col.setHeaderValue("Tipo");
break;
case 3:
col.setHeaderValue("Precio");
}
tColumnModel.addColumn(col);
}
jTable1.setColumnModel(tColumnModel);
}
...
32
Ahora podemos crear el segundo formulario. Que de acuerdo la especificación recibida, deberá permitirnos el
ingreso de los datos del cliente y algunos valores adicionales. El formulario que deberemos construir debe tener
la siguiente forma.
JTextField
JComboBox
JFormattedTextField
JFormattedTextField
El contenido del JComboBox lo asignaremos dinámicamente desde el código. Para ello, crearemos un método
que llamaremos inicializarTiposClientes.
Además, usaremos el valor recibido como parámetro en el constructor del formulario para asignar el valor al
label encargado de mostrar la habitación para la que se está haciendo la reservación/asignación (jLabel6).
33
package prn315.guia03.ejemplohotel;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
public class RegistroCliente extends javax.swing.JFrame {
List<String> tipos = new ArrayList<String>();
/**
* Creates new form RegistroCliente
*/
public RegistroCliente(String habitacionSeleccionada) {
initComponents();
iniciarlizarTiposCliente();
jLabel6.setText(habitacionSeleccionada);
}
private void iniciarlizarTiposCliente() {
tipos = new ArrayList<String>();
tipos.add("Primera vez");
tipos.add("Registrado");
tipos.add("Frecuente");
jComboBox1.setModel(new DefaultComboBoxModel(tipos.toArray()));
}
...
Los controles de tipo JFormattedTextField los configuraremos para que reciban el formato de fecha. Para ello,
seleccionamos el control correspondiente y hacemos clic sobre el botón junto a la propiedad formattedFactory.
34
Esto nos mostrará una pantalla en la que debemos especificar el formato de la entrada que recibirá el control.
35
El formulario resultante se muestra a continuación.
Ahora podemos programar los eventos de los botones, de acuerdo a la especificación del problema.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
JOptionPane.showMessageDialog(this, "Se ha registrado al cliente");
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
JOptionPane.showMessageDialog(this, "Operación cancelada por el usuario");
this.setVisible(false);
this.dispose();
}
Una vez creado el segundo formulario, podemos programar el evento en el formulario ConsultaHabitacion, que
invoque al formulario recién creado.
Para ello, hacemos clic derecho sobre la tabla, elegimos la opción Events (eventos), Mouse (ratón) y
mouseClicked.
36
...
private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {
int clics = evt.getClickCount();
int row = jTable1.rowAtPoint(evt.getPoint());
HabitacionTableModel habitacionTableModel = (HabitacionTableModel) jTable1.getModel();
//La acción se realizará cuando se realiza un doble clic
if(clics == 2){
String habitacionSeleccionada = (String) habitacionTableModel.habitaciones.get(row).getNumero();
RegistroCliente registroCliente = new RegistroCliente(habitacionSeleccionada);
registroCliente.setVisible(true);
}
}
...
37

Documentos relacionados