SlideShare una empresa de Scribd logo
1 de 159
Descargar para leer sin conexión
ALGORITMICA Y PROGRAMACION POR OBJETOS I




             Nivel 5

        Construyendo la
        Interfaz Gráfica




           Marcela Hernández Hoyos
Motivación
                         Interfaz
                         usuario


  Modelo del mundo



                                    Usuario




Único medio de comunicación entre el usuario
           y el modelo del mundo
Motivación
                       Interfaz
                       usuario


Modelo del mundo



                                       Usuario


                                  •   Ejecuta
                                      operaciones
  A través de la interfaz:            sobre el modelo
                                      del mundo.
                                  •   Ve el resultado de
                                      sus acciones.
Aspectos importantes




    Diseño funcional y         Arquitectura
          gráfico
•    Colores               •   Estructura clara
•    Distribución de       •   Fácil de mantener
     elementos gráficos
     (menús, botones, …)
Qué vamos a aprender en este
            nivel:
Cómo proponer una arquitectura para un
programa simple:
– Repartir responsabilidades entre interfaz, mundo y
  pruebas.


Cómo construir las clases que implementan una
interfaz usuario

Cómo integrar las clases de la interfaz con las
clases del mundo
Caso de estudio: Calculador
      de Impuestos
El Calculador de Impuestos
•   Funcionalidad
•   Interfaz usuario
•   Requerimientos Funcionales
•   Arquitectura
    – Mundo
    – Interfaz
El Calculador de Impuestos -
           Funcionalidad
•   Calcula el valor de los impuestos que una persona
    debe pagar por su carro
•   Vehículo se caracteriza por:
    –   Marca, línea, modelo y precio
•   Cálculo de impuestos como porcentaje del precio
    del vehículo (% determinado por un rango)
•   Hay tres tipos de descuento
    –   Pronto pago, servicio público, traslado de cuenta
El Calculador de Impuestos –
       Interfaz usuario

                            Ventana Principal

3 Zonas de trabajo:

Información del vehículo

Descuentos

Cálculo de impuestos +
inicializar la aplicación
El Calculador de Impuestos –
Requerimientos Funcionales
R1    Buscar el avalúo de un vehículo
R2    Calcular el pago de impuesto de un vehículo
RNF   Requerimiento NO FUNCIONAL (inicializar la aplicación
      sin tener que volver a ejecutarla)
Tarea No. 1
• RF1: Buscar el avalúo de un vehículo
  – Resumen:
    • Dada la información del vehículo, presentar el
      valor de avalúo del mismo


  – Entradas:



  – Resultado:
Tarea No. 1
• RF2:Calcular el pago de impuesto de un
  vehículo
  – Resumen:
     • Dada la información de un vehículo, y el conjunto de
       descuentos que le aplican, dar el valor a pagar por los
       impuestos del vehículo


  – Entradas:



  – Resultado:
El Calculador de Impuestos –
         Arquitectura




  Mundo             Interfaz
El Calculador de Impuestos
                (Mundo)

                           0 .. n
                         rangos




0 .. n marcas
                0 .. n       0 .. n
                lineas      modelos
Tarea No. 2
• CalculadorImpuestos
  – Constantes
  – Asociaciones
• Marca
  – Atributos
  – Asociaciones
• Linea
  – Atributos
  – Asociaciones
• Modelo
  – Atributos
• RangoImpuesto
  – Atributos
Métodos de la clase
        CalculadorImpuestos (pag. 3)
                         buscarAvaluoVehiculo


/**
    * Retorna el valor de avalúo de un vehiculo de la marca, línea y modelo dado.
    * @param unaMarca - marca del vehiculo
    * @param unaLinea - linea del vehiculo
    * @param unModelo - modelo del vehiculo
    * @return precio de avalúo del vehiculo
    * @throws Exception si no encuentra la marca o la linea o el modelo registrados
    */
   public double buscarAvaluoVehiculo( String unaMarca, String unaLinea, String unModelo )
throws Exception
Métodos de la clase
        CalculadorImpuestos (pag. 3)
                                  calcularPago

/**
    * Calcular el pago de impuesto que debe hacer un vehículo de un modelo dado. Si no
encuentra un rango para el modelo devuelve 0
    * @param unaMarca - marca del vehiculo
    * @param unaLinea - linea del vehiculo
    * @param unModelo - modelo del vehiculo
    * @param descProntoPago - indica si aplica el descuento por pronto pago
    * @param descServicioPublico - indica si aplica el descuento por servicio público
    * @param descTrasladoCuenta - indica si aplica el descuento por traslado de cuenta
    * @return valor a pagar
    * @throws Exception si no encuentra el vehiculo dado por la marca, la linea y el modelo
    */
   public double calcularPago( String unaMarca, String unaLinea, String unModelo,
boolean descProntoPago, boolean descServicioPublico, boolean descTrasladoCuenta
) throws Exception
Construcción de
interfaces gráficas
El Calculador de Impuestos –
       Interfaz usuario

                            Ventana Principal

3 Zonas de trabajo:

Información del vehículo

Descuentos

Cálculo de impuestos +
inicializar la aplicación
El Calculador de Impuestos –
       Interfaz usuario

                           InterfazImpuestosCarro (JFrame)

3 Zonas de trabajo:

PanelVehiculo (JPanel)

PanelDescuentos (JPanel)

PanelResultados (JPanel)
El Calculador de Impuestos –
       Interfaz usuario

                           InterfazImpuestosCarro
                                   (JFrame)


PanelVehiculo (JPanel)
                                 Clases
PanelDescuentos (JPanel)
                                  JAVA

PanelResultados (JPanel)
Entidades

Mundo del Problema         Mundo Gráfico y de
                              Interacción
•   Estudiante        •   Ventana (JFrame)
•   Tienda            •   Panel (JPanel)
•   Banco             •   Botón (JButton)
•   Recurso           •   Zona de texto (JTextField)
•   Avion             •   Etiqueta (JLabel)
•   …                 •   Caja de chequeo (JCheckBox)
Entidades del mundo gráfico y
       de interacción
                    Ventana
Entidades del mundo gráfico y
       de interacción




          Panel
Entidades del mundo gráfico y
       de interacción


       Zona de
         texto
Entidades del mundo gráfico y
       de interacción




       Caja de
       chequeo
Entidades del mundo gráfico y
       de interacción


       Etiqueta
Entidades del mundo gráfico y
       de interacción




          Boton
El Calculador de Impuestos
         (Interfaz)

    principal



                principal
El Calculador de Impuestos –
       Interfaz usuario

                           InterfazImpuestosCarro (JFrame)

3 Zonas de trabajo:

PanelVehiculo (JPanel)

PanelDescuentos (JPanel)

PanelResultados (JPanel)
El Calculador de Impuestos –
       Interfaz usuario

                           InterfazImpuestosCarro
                                   (JFrame)


PanelVehiculo (JPanel)
                                 Clases
PanelDescuentos (JPanel)
                                  JAVA

PanelResultados (JPanel)
El Calculador de Impuestos –
       Interfaz usuario

                           InterfazImpuestosCarro
                                   (JFrame)


PanelVehiculo (JPanel)
                            •Se encuentran en una
PanelDescuentos (JPanel)
                            biblioteca gráfica (swing)
                            •Paquete: java.swing
PanelResultados (JPanel)    •Deber ser importado
Elementos gráficos
   estructurales
La Ventana Principal
La Ventana Principal
• Contiene TODOS los elementos de
  visualización e interacción (con los que el
  usuario va a utilizar el programa)

• UNICA FUNCION:
  – Servir como marco para los demás elementos
    de la interfaz (AGRUPA)

• Es un contenedor gráfico
La Ventana Principal
Título


                           Controles para
                              cerrar el
                             programa
La Ventana Principal


 principal



             principal




                    Ventana principal =
                     Objeto de la clase
                  InterfazImpuestosCarro
Clase InterfazImpuestosCarro
• Como cualquier clase:
  – Está declarada en su propio archivo:
    InterfazImpuestosCarro.java (pag. 8)
  – Sigue las mismas reglas que cualquier clase
    del mundo
• Diferencia:
  – Está declarada en otro paquete:
    uniandes.cupi2.impuestosCarro.interfaz (ver
    en Eclipse)
Clase InterfazImpuestosCarro
package uniandes.cupi2.impuestosCarro.interfaz;
import java.awt.*;
import javax.swing.*;
import uniandes.cupi2.impuestosCarro.mundo.*;
/**
 * Interfaz de cálculo de impuestos de carros
 */
public class InterfazImpuestosCarro extends
    JFrame
{
}
Clase InterfazImpuestosCarro
package uniandes.cupi2.impuestosCarro.interfaz;




La clase se declara dentro del paquete de las clases de la interfaz usuario
Clase InterfazImpuestosCarro
package uniandes.cupi2.impuestosCarro.interfaz;
import java.awt.*;
import javax.swing.*;




Se importan las clases de los dos paquetes mostrados (swing y awt)
Clase InterfazImpuestosCarro
package uniandes.cupi2.impuestosCarro.interfaz;
import java.awt.*;
import javax.swing.*;
import uniandes.cupi2.impuestosCarro.mundo.*;




Se importan las clases del modelo del mundo
Clase InterfazImpuestosCarro


     principal



                 principal
Clase InterfazImpuestosCarro
package uniandes.cupi2.impuestosCarro.interfaz;
import java.awt.*;
import javax.swing.*;
import uniandes.cupi2.impuestosCarro.mundo.*;
/**
 * Interfaz de cálculo de impuestos de carros
 */
public class InterfazImpuestosCarro extends
    JFrame
{
}
    La clase se declara con la misma sintáxis de las clases del
                        modelo del mundo
Clase InterfazImpuestosCarro
package uniandes.cupi2.impuestosCarro.interfaz;
import java.awt.*;
import javax.swing.*;
import uniandes.cupi2.impuestosCarro.mundo.*;
/**
 * Interfaz de cálculo de impuestos de carros
 */
public class InterfazImpuestosCarro extends
    JFrame
{
}
   Se agrega extends JFrame para indicar que es una ventana
Clase InterfazImpuestosCarro
                             Clase de swing
                              que se está
                              extendiendo


     principal



                 principal
Clase InterfazImpuestosCarro

Cómo cambiar el
estado (apariencia)
de la ventana?
Clase InterfazImpuestosCarro

Cómo cambiar el
estado (apariencia)
de la ventana?
                          R// Con los métodos
                          de la clase JFrame
           Cambiar el        Cambiar el      Agregar
           título de la     tamaño de la   componentes
             ventana          ventana        gráficos
Métodos de JFrame
•   setSize ( ancho, alto )
•   setResizable ( true/false )
•   setTitle ( titulo )
•   setDefaultCloseOperation ( EXIT_ON_CLOSE)
•   setVisible ( true/false )
•   add ( componente )
Configuración de la ventana en
      el método Constructor
public InterfazImpuestosCarro( )
  {
    setTitle( "Cálculo impuestos" );
    setSize( 290, 350 );
    setResizable( false );
    setDefaultCloseOperation( EXIT_ON_CLOSE );
    setLayout( new BorderLayout( ) );
 }
Distribuidor gráfico de
       elementos (layout)
• Se encarga de distribuir los elementos
  (NO tenemos que hacerlo)
• Sólo tenemos que asociar a la ventana un
  objeto de este tipo (clase) que se
  encargue de hacerlo
• Java (swing) tiene varios distribuidores
  gráficos (varias clases). En APO1 vamos a
  ver dos:
  – BorderLayout
  – GridLayout
Configuración de la ventana en
      el método Constructor
public InterfazImpuestosCarro( )
  {
    setTitle( "Cálculo impuestos" );
    setSize( 290, 350 );
    setResizable( false );
    setDefaultCloseOperation( EXIT_ON_CLOSE );
    setLayout( new BorderLayout( ) );
 }
Divisiones y Paneles
El Calculador de Impuestos –
       Interfaz usuario

                           InterfazImpuestosCarro (JFrame)

3 Zonas de trabajo:

PanelVehiculo (JPanel)

PanelDescuentos (JPanel)

PanelResultados (JPanel)
Un Panel
• Se encarga de agrupar elementos gráficos
  por contenido y uso
• Facilita al usuario su localización y su uso
• Cada panel se implementa como una clase
  aparte en el modelo
  – PanelVehiculo
  – PanelDescuentos
  – PanelResultados
El Calculador de Impuestos
         (Interfaz)

    principal



                principal
Clase InterfazImpuestosCarro
Creación de los paneles en el
          método Constructor
 public class InterfazImpuestosCarro extends JFrame
{
   private PanelVehiculo panelVehiculo;               Se declara un
   private PanelDescuentos panelDescuentos;           atributo por cada una
   private PanelResultados panelResultados;           de las divisiones
  public InterfazImpuestosCarro( ) throws Exception
  {
    setLayout( new BorderLayout( ) );




  }
Creación de los paneles en el
          método Constructor
 public class InterfazImpuestosCarro extends JFrame
{
   private PanelVehiculo panelVehiculo;
   private PanelDescuentos panelDescuentos;
   private PanelResultados panelResultados;

  public InterfazImpuestosCarro( ) throws Exception
  {                                                   Se asocia a la
    setLayout( new BorderLayout( ) );                 ventana un
                                                      distribuidor gráfico




  }
Creación de los paneles en el
          método Constructor
 public class InterfazImpuestosCarro extends JFrame
{
   private PanelVehiculo panelVehiculo;
   private PanelDescuentos panelDescuentos;
   private PanelResultados panelResultados;

  public InterfazImpuestosCarro( ) throws Exception
  {
    setLayout( new BorderLayout( ) );

      panelVehiculo = new PanelVehiculo( this );
      add( panelVehiculo, BorderLayout.NORTH );
                                                       Se crea una instancia
      panelDescuentos = new PanelDescuentos( );        de cada uno de los
      add( panelDescuentos, BorderLayout.CENTER );     paneles
      panelResultados = new PanelResultados( this );
      add( panelResultados, BorderLayout.SOUTH );
  }
Creación de los paneles en el
          método Constructor
 public class InterfazImpuestosCarro extends JFrame
{
   private PanelVehiculo panelVehiculo;
   private PanelDescuentos panelDescuentos;
   private PanelResultados panelResultados;

  public InterfazImpuestosCarro( ) throws Exception
  {
    setLayout( new BorderLayout( ) );

      panelVehiculo = new PanelVehiculo( this );
      add( panelVehiculo, BorderLayout.NORTH );
                                                       Se agrega cada
      panelDescuentos = new PanelDescuentos( );        panel en una posición
      add( panelDescuentos, BorderLayout.CENTER );     de las definidas en el
                                                       distribuidor gráfico
      panelResultados = new PanelResultados( this );
      add( panelResultados, BorderLayout.SOUTH );
  }
Creación de los paneles en el
          método Constructor
 public class InterfazImpuestosCarro extends JFrame
{
   private PanelVehiculo panelVehiculo;
   private PanelDescuentos panelDescuentos;
   private PanelResultados panelResultados;

  public InterfazImpuestosCarro( ) throws Exception
  {
    setLayout( new BorderLayout( ) );

      panelVehiculo = new PanelVehiculo( this );
      add( panelVehiculo, BorderLayout.NORTH );

      panelDescuentos = new PanelDescuentos( );
      add( panelDescuentos, BorderLayout.CENTER );

      panelResultados = new PanelResultados( this );
      add( panelResultados, BorderLayout.SOUTH );
  }
Analicemos la creación del
        panelVehiculo

Atributo panelVehiculo de la
clase InterfazImpuestosCarro

 panelVehiculo = new PanelVehiculo( this );
 add( panelVehiculo, BorderLayout.NORTH );
Analicemos la creación del
      panelVehiculo

                  Llamado al constructor de la
                      clase PanelVehiculo

panelVehiculo = new PanelVehiculo( this );
add( panelVehiculo, BorderLayout.NORTH );
Analicemos la creación del
      panelVehiculo
                            Parámetro del método
                 Concepto       constructor de la
                  nuevo
                              clase PanelVehiculo


panelVehiculo = new PanelVehiculo( this );
add( panelVehiculo, BorderLayout.NORTH );
Analicemos la creación del
      panelVehiculo



panelVehiculo = new PanelVehiculo( this );
add( panelVehiculo, BorderLayout.NORTH );

Método de la clase JFrame para
    adicionar un componente
Analicemos la creación del
      panelVehiculo



panelVehiculo = new PanelVehiculo( this );
add( panelVehiculo, BorderLayout.NORTH );

  Objeto que se va a adicionar
Analicemos la creación del
      panelVehiculo



panelVehiculo = new PanelVehiculo( this );
add( panelVehiculo, BorderLayout.NORTH );

                  Zona (posición relativa dentro de la
       Concepto
        nuevo
                        ventana) donde se va a
                       adicionar el objeto. Es una
                         constante de la clase
                             BorderLayout.
Dos conceptos nuevos


• BorderLayout   • this
Dos conceptos nuevos


    • BorderLayout                                       NORTH
•   Distribuidor gráfico “en los Bordes”
•   Divide el espacio de la ventana en 5 zonas:
    NORTH, CENTER, SOUTH, WEST, EAST.
•   Al agregar un componente a la ventana, SE     WEST   CENTER   EAST
    DEBE pasar como parámetro la zona
    donde se va a ubicar. Ejemplo:
      – add( panelVehiculo,                              SOUTH
         BorderLayout.NORTH );
•   Utiliza el tamaño definido para cada uno de
    los componentes y asigna TODO el espacio
    sobrante al componente que se encuentre
    en la zona del centro
Dos conceptos nuevos


     • Otro distribuidor: GridLayout
•   Distribuidor gráfico “en Malla”
•   Divide el espacio de la ventana en filas y columnas.
•   La cantidad de filas y columnas se establecen en el
    método constructor del GridLayout. Ejemplo:
     – setLayout( new GridLayout ( 4, 3 ) );               Fila 1    1 2 3
•   Al agregar un componente a la ventana, NO SE
    DEBE especificar la posición. Esta es asignada en
                                                           Fila 2    4 5 6
    el orden de llegada (fila 1, fila 2, …)                Fila 3    7 8 9
•   Ignora el tamaño definido para cada componente.
    Hace una distribución uniforme del espacio.            Fila 4   10 11 12
Dos conceptos nuevos


• BorderLayout   • this
Dos conceptos nuevos


                 • this
          • Es una variable de JAVA

          • Hace referencia al objeto
            que está ejecutando un
            método
Ejemplo de uso de this
 public class InterfazImpuestosCarro extends JFrame
{
   private PanelVehiculo panelVehiculo;
   private PanelDescuentos panelDescuentos;
   private PanelResultados panelResultados;

  public InterfazImpuestosCarro( ) throws Exception
  {
    setLayout( new BorderLayout( ) );

      panelVehiculo = new PanelVehiculo( this );
      add( panelVehiculo, BorderLayout.NORTH );

      panelDescuentos = new PanelDescuentos( );
      add( panelDescuentos, BorderLayout.CENTER );

      panelResultados = new PanelResultados( this );
      add( panelResultados, BorderLayout.SOUTH );
  }
Ejemplo de uso de this
               Es la ventana principal, (objeto de
                la clase InterfazImpuestosCarro,
                    que es el “padre” del panel)


panelVehiculo = new PanelVehiculo( this );
add( panelVehiculo, BorderLayout.NORTH );


   Para qué sirve? … VER MAS ADELANTE
Hasta aquí hemos visto …
• Cómo construir la clase de la ventana
  principal (InterfazImpuestosCarro)


       Ahora vamos a ver …
• Cómo construir las clases de los paneles
  (PanelVehiculo, PanelDescuentos,
  PanelResultados)
Construcción de las clases de
         los paneles
• Proceso similar a la construcción de la clase de
  la ventana principal
• Al igual que la ventana principal, los paneles
  también son contenedores gráficos


  Ventana Principal


       JFrame
Construcción de las clases de
         los paneles
• Proceso similar a la construcción de la clase de
  la ventana principal
• Al igual que la ventana principal, los paneles
  también son contenedores gráficos


  Ventana Principal              Panel


       JFrame                    JPanel
PanelVehiculo
 public class PanelVehiculo extends JPanel
{
   public PanelVehiculo( )
   {
                                                    Creación y asociación de
     …
                                                    un GridLayout de 5 filas y
     setLayout( new GridLayout( 5, 2 ) );
     setPreferredSize( new Dimension( 0, 130 ) );
                                                    2 columnas
     …




  }
PanelVehiculo
 public class PanelVehiculo extends JPanel
{
   public PanelVehiculo( )                          Definir la altura del panel.
   {                                                No se define el ancho
     …                                              porque va a ser igual al
     setLayout( new GridLayout( 5, 2 ) );           de la ventana
     setPreferredSize( new Dimension( 0, 130 ) );
     …


                                                                        130
                     Clase de Java que
                     permite definir un ancho
                     y un alto usando un
                     objeto
  }
PanelVehiculo
 public class PanelVehiculo extends JPanel
{
   public PanelVehiculo( )
                                                             Se crea y se asocia un
   {
                                                             borde al panel para
     …
                                                             facilitar la identificación
     setLayout( new GridLayout( 5, 2 ) );
     setPreferredSize( new Dimension( 0, 130 ) );
                                                             de las divisiones dentro
     TitledBorder border = BorderFactory.createTitleBorder
                                                             de la ventana
                           (“Datos del vehículo”);
     border.SetTitleColor( Color.BLUE );
     setBorder( border );
     …




  }
PanelDescuentos
 public class PanelDescuentos extends JPanel
{
   public PanelVehiculo( )
   {                                           Creación y asociación de
     …                                         un GridLayout de 2 filas y
     setLayout( new GridLayout( 2, 2 ) );      2 columnas
     …




  }
PanelDescuentos
 public class PanelDescuentos extends JPanel
{
   public PanelVehiculo( )
   {                                                         Se crea y se asocia un
     …                                                       borde
     setLayout( new GridLayout( 2, 2 ) );
     TitledBorder border = BorderFactory.createTitleBorder
                           (“Descuentos”);
     border.SetTitleColor( Color.BLUE );
     setBorder( border );
     …




  }
Etiquetas
       y
Zonas de Texto
Etiquetas
• Permiten agregar un texto corto en la interfaz
• Son objetos de la clase JLabel de Java
• Algunos métodos de la clase JLabel:
   – setText (texto);
   – setForeground ( color );




                                Cualquier constante de la
                                clase Color de Java
                                (BLACK, GREEN, RED,
                                BLUE, …) o un nuevo
                                color creado con 3
                                índices RGB
Zonas de texto
• Cumplen dos funciones:
   – Permiten el ingreso de información por parte del usuario
     (ENTRADAS de los requerimientos funcionales)
   – Permiten mostrar las respuestas calculadas por el programa
• Son objetos de la clase JText de Java
• Algunos métodos de la clase JLabel:
   – getText ( );                         Retorna la cadena de
                                          caracteres tecleada por el
                                          usuario. SIEMPRE es
                                          String.
Zonas de texto
• Cumplen dos funciones:
   – Permiten el ingreso de información por parte del usuario
     (ENTRADAS de los requerimientos funcionales)
   – Permiten mostrar las respuestas calculadas por el programa
• Son objetos de la clase JText de Java
• Algunos métodos de la clase JLabel:
   – getText ( );
   – setText ( texto );                   Despliega el texto que se
                                          pasa como parámetro. Se
                                          usa para mostrar los
                                          resultados del programa.
Zonas de texto
• Cumplen dos funciones:
   – Permiten el ingreso de información por parte del usuario
     (ENTRADAS de los requerimientos funcionales)
   – Permiten mostrar las respuestas calculadas por el programa
• Son objetos de la clase JText de Java
• Algunos métodos de la clase JLabel:
   – getText ( );
   – setText ( texto );                   Indica si el usuario puede
   – setEditable ( true / false)          o no modificar el texto
                                          (escribir encima)
Zonas de texto
• Cumplen dos funciones:
   – Permiten el ingreso de información por parte del usuario
     (ENTRADAS de los requerimientos funcionales)
   – Permiten mostrar las respuestas calculadas por el programa
• Son objetos de la clase JTextField de Java
• Algunos métodos de la clase JLabel:
   –   getText ( );
   –   setText ( texto );
   –   setEditable ( true / false)
   –   setForeground (color )        Definen respectivamente
   –   setBackground ( color )       el color del texto y del
                                     fondo
Cómo agregar una etiqueta (o
una zona de texto) a un panel
Declarar en el panel un atributo de la clase
JLabel (o JTextField)
Crear la etiqueta (o la zona de texto) (new) en el
método constructor del panel
Configurar las características de la etiqueta (o
de la zona de texto) con los métodos de la clase
JLabel (o JTextField)
Agregar la etiqueta (o la zona de texto) al panel
(add)
Ejemplo en PanelVehiculo
 public class PanelVehiculo extends JPanel
{
  …
  private JLabel labMarca;
  private JLabel labLinea;
  private JLabel labModelo;
  private JLabel labValor;
                                      Declararen el panel los
                                    atributos de clases JLabel y
    private JTextField txtMarca;    JTextField
    private JTextField txtLinea;
    private JTextField txtModelo;
    private JTextField txtValor;
…
    }
Ejemplo en PanelVehiculo
 public PanelVehiculo ( )
{
   …
   labMarca = new JLabel ( “Marca” );
   labLinea = new JLabel ( “Línea” );      Crear las etiquetas
   labModelo = new JLabel ( “ Modelo” );   y las zonas de
   labValor = new JLabel ( “ Valor” );
                                           texto (new) en el
  txtMarca = new JTextField( );
  txtLinea = new JTextField( );
                                           método constructor
  txtModelo = new JTextField( );           del panel
  txtValor = new JTextField( “$ 0” );
  …
  }
Ejemplo en PanelVehiculo
 public PanelVehiculo ( )
{
   …
   labMarca = new JLabel ( “Marca” );
   labLinea = new JLabel ( “Línea” );
   labModelo = new JLabel ( “ Modelo” );
   labValor = new JLabel ( “ Valor” );

  txtMarca = new JTextField( );
                                           Configurar las
  txtLinea = new JTextField( );            características de las
  txtModelo = new JTextField( );
  txtValor = new JTextField( “$ 0” );      etiquetas o de las zonas
  txtValor.SetEditable(false);
                                           de texto con los
  txtValor.SetForeground(Color.BLUE);      métodos de las clases
  txtValor.SetBackground(Color.WHITE);
  …
                                           JLabel o JTextField
  }
Ejemplo en PanelVehiculo
 public PanelVehiculo ( )
{
  …
  labMarca = new JLabel ( “Marca” );
  labLinea = new JLabel ( “Línea” );
  labModelo = new JLabel ( “ Modelo” );
  labValor = new JLabel ( “ Valor” );

  txtMarca = new JTextField( );
  txtLinea = new JTextField( );
  txtModelo = new JTextField( );
  txtValor = new JTextField( “$ 0” );

  txtValor.SetEditable(false);
  txtValor.SetForeground(Color.BLUE);
  txtValor.SetBackground(Color.WHITE);

  add( labMarca );
  add( txtMarca );
  add( labLinea );                        Agregar las etiquetas
  add( txtLinea );
  add( labModelo );                       y las zonas de texto
  add( txtModelo );
  add( labValor );                        al panel (add)
  add( txtValor );
Selección de Opciones
por medio de Cajas de
       Chequeo
Cajas de chequeo
• Permiten al usuario seleccionar o deseleccionar una
  opción.
• Son objetos de la clase JCheckBox de Java
• Algunos métodos de la clase JCheckBox:
                                       Indica (true/false) si el
   – isSelected ( );
                                       usuario seleccionó la
                                       opción
Cajas de chequeo
• Permiten al usuario seleccionar o deseleccionar una
  opción.
• Son objetos de la clase JCheckBox de Java
• Algunos métodos de la clase JCheckBox:

   – isSelected ( );


                                       Marca como seleccionado
   – setSelected ( true/false );
                                       o no, la caja de chequeo
Ejemplo en PanelDescuentos
public class PanelDescuentos extends JPanel
{
  …
  private JCheckBox cbPago;
  private JCheckBox cbSPublico;        Declarar
                                            en el panel los
  private JCheckBox cbTCuenta;         atributos
                                            de clase
                                     JCheckBox
    …
}
Ejemplo en PanelDescuentos
public PanelDescuentos ( )
{
  …
  cbPago = new JCheckBox ( “Pronto pago” );
  cbSPublico = new JCheckBox ( “Servicio público” );
  cbTCuenta = new JCheckBox ( “Traslado de cuenta” );
  …
}                                                       Crear las cajas de
                                                        chequeo (new) en
                                                        el método
                                                        constructor del
                                                        panel
Ejemplo en PanelDescuentos
public PanelDescuentos ( )
{
  …
  cbPago = new JCheckBox ( “Pronto pago” );
  cbSPublico = new JCheckBox ( “Servicio público” );
  cbTCuenta = new JCheckBox ( “Traslado de cuenta” );

    add( cbPago );
    add( cbTCuenta );
    add( cbSPublico );                       Agregar las cajas de
                                             chequeo al panel
    …                                        (add)
}
Interacción con la
aplicación mediante
      Botones
Botones
• Permiten al usuario expresar sus órdenes
  al programa (es el mecanismo más
  simple de interacción).
• Son objetos de la clase JButton de Java
• La clase JButton tiene DOS METODOS
  especiales:
  – setActionCommand ( evento );
  – addActionListener ( panel );
Ejemplo en PanelResultados
public class PanelResultados extends JPanel
{
  …
  private JLabel labTotal;
  private JTextField txtTotal;

    private JButton butLimpiar;       Declarar en el panel los
    private JButton butCalcular;
    …
                                      atributos de clase JButton
}
Ejemplo en PanelResultados
public PanelResultados ( )
{
  …
  labTotal = new JLabel ( “Total a pagar” );
  txtTotal = new JTextField ( “$ 0” );

    butLimpiar = new JButton ( “Limpiar” );
    butCalcular = new JButton ( “Calcular” );   Crear los botones
    …
}
                                                (new) en el método
                                                constructor del
                                                panel
Ejemplo en PanelResultados
public PanelResultados ( )
{
  …
  labTotal = new JLabel ( “Total a pagar”
    );
  txtTotal = new JTextField ( “$ 0” );

 butLimpiar = new JButton ( “Limpiar” );
 butCalcular = new JButton ( “Calcular” );

 txtTotal.SetEditable( false );
 txtTotal.SetForeground( Color.BLUE );
 txtTotal.SetBackground( Color.WHITE );

 add( new Jlabel( “”) );
 add( new Jlabel( “”) );            Agregar los botones
 add(butLimpiar);
 add(labTotal);
                                    al panel (add)
 add(txtTotal);
 add(butCalcular);
 …
Acciones del Usuario
          y
Eventos de la aplicación
Acciones y Eventos
                                         llamada a
                                         un método
                   evento
                              Interfaz
                              usuario


                                                         Modelo del mundo
      Usuario

•   El usuario ejecuta acciones:              •   Las acciones se convierten
     – Hace click sobre un botón                  en objetos llamados
     – Chequea una caja de                        eventos:
       chequeo                                       – Describen lo que el usuario
     – Selecciona una opción de                        hizo
       un Menú                                       – Se puede analizar su
     – …                                               contenido para que el
                                                       programa reaccione de
                                                       acuerdo a la acción del
                                                       usuario
Cómo manejar un evento con un botón de la
interfaz en 3 pasos … y no morir en el intento:

        Dar un nombre al evento y asociarlo a
        un botón
public class PanelResultados extends JPanel           En la clase del panel que
{                                                     contiene el botón
  …
  public final static String LIMPIAR = “limpiar”;
  public final static String CALCULAR = “calcular”;

    public PanelResultados( )
    {                                                  Se declaran constantes
      …                                                para los nombres de los
      butLimpiar.SetActionCommand ( LIMPIAR );         eventos
      butCalcular.SetActionCommand ( CALCULAR );
      …
    }
    …
}
Cómo manejar un evento con un botón de la
interfaz en 3 pasos … y no morir en el intento:

        Dar un nombre al evento y asociarlo a
        un botón
public class PanelResultados extends JPanel
{
  …
  public final static String LIMPIAR = “limpiar”;
  public final static String CALCULAR = “calcular”;

    public PanelResultados( )                         En el método constructor
    {                                                 del panel
      …
      butLimpiar.SetActionCommand ( LIMPIAR );            Se asocian los nombres
      butCalcular.SetActionCommand ( CALCULAR );          de los eventos con cada
      …                                                   botón
    }
    …
}
Cómo manejar un evento con un botón de la
interfaz en 3 pasos … y no morir en el intento:

      Atender el evento

public class PanelResultados extends JPanel implements ActionListener
{
  …
  public void actionPerformed (ActionEvent evento )
  {
    String comando = evento.getActionCommand( );                Agregar una declaración
    if ( (comando.equals( LIMPIAR) )                            en el encabezado de la
    {                                                           clase del panel que
         // Reacción al evento de LIMPIAR                       contiene el botón (para
    }                                                           que pueda “percibir” las
    else if (comando.equals( CALCULAR ) )                       acciones del usuario)
         // Reacción al evento de CALCULAR
    }
  }
Cómo manejar un evento con un botón de la
interfaz en 3 pasos … y no morir en el intento:

      Atender el evento

public class PanelResultados extends JPanel implements ActionListener
{
                                                           Implementar en la clase
  …
                                                           del panel que contiene el
  public void actionPerformed (ActionEvent evento )
                                                           botón, el método especial
  {
                                                           actionPerformed
    String comando = evento.getActionCommand( );
    if ( (comando.equals( LIMPIAR) )
    {
         // Reacción al evento de LIMPIAR
    }
                                                            parámetro del método:
    else if (comando.equals( CALCULAR ) )
                                                            evento ocurrido en el
    {                                                       panel
         // Reacción al evento de CALCULAR
    }
  }
Cómo manejar un evento con un botón de la
interfaz en 3 pasos … y no morir en el intento:

      Atender el evento

public class PanelResultados extends JPanel implements ActionListener
{
                                                           Implementar en la clase
  …
                                                           del panel que contiene el
  public void actionPerformed (ActionEvent evento )
                                                           botón, el método especial
  {
                                                           actionPerformed
    String comando = evento.getActionCommand( );
    if ( (comando.equals( LIMPIAR) )
    {
         // Reacción al evento de LIMPIAR
    }
                                                            parámetro del método:
    else if (comando.equals( CALCULAR ) )
                                                            evento ocurrido en el
    {                                                       panel
         // Reacción al evento de CALCULAR
    }
  }
Cómo manejar un evento con un botón de la
interfaz en 3 pasos … y no morir en el intento:

      Atender el evento

public class PanelResultados extends JPanel implements ActionListener
{
  …
  public void actionPerformed (ActionEvent evento )
  {
    String comando = evento.getActionCommand( );
    if ( (comando.equals( LIMPIAR) )
    {
         // Reacción al evento de LIMPIAR
    }
                                                            Métodos de la ventana
    else if (comando.equals( CALCULAR ) )
                                                            principal !!!
    {
         // Reacción al evento de CALCULAR
    }
  }
Cómo manejar un evento con un botón de la
interfaz en 3 pasos … y no morir en el intento:

      Atender el evento

public class PanelResultados extends JPanel implements ActionListener
{
  …
  public void actionPerformed (ActionEvent evento )
  {
                                                       Cada vez que el
    String comando = evento.getActionCommand( );
                                                      usuario hace click
    if ( (comando.equals( LIMPIAR) )                   en un botón del
    {                                                panel, se ejecuta el
         // Reacción al evento de LIMPIAR                   método
    }                                                  actionPerformed
    else if (comando.equals( CALCULAR ) )
    {
         // Reacción al evento de CALCULAR
    }
  }
Cómo manejar un evento con un botón de la
interfaz en 3 pasos … y no morir en el intento:

      Decir que el panel es el encargado de
      atender el evento
public class PanelResultados extends JPanel implements ActionListener
{
  …
                                                           Mediante el método
  public PanelResultados ( )
                                                           addActionListener de la
  {
                                                           clase JButton
     butLimpiar.addActionListener (this);
     butCalcular.addActionListener (this);
  }
  …
}
                                                  parámetro del método: el
                                                  objeto que lo está
                                                  ejecutando, es decir el
                                                  panel mismo
Arquitectura y
 Distribución de
Responsabilidades
Qué vamos a aprender …
• Coordinar los elementos de la interfaz y del
  modelo del mundo para satisfacer los
  requerimientos funcionales
• Estructurar y repartir las responsabilidades
• Una propuesta de arquitectura:
  – Facilita la localización de componentes del programa
  – Aumenta la claridad
  – Facilita el mantenimiento
Por dónde comienza la
        ejecución del programa?
• Por el método main de la ventana principal
• Su función: crear una instancia de la
  ventana y hacerla visible en la pantalla
 public class InterfazImpuestosCarro extends JFrame
 {
   …

     public static void main( String[] args )
     {
          InterfazImpuestosCarro vent = new InterfazImpuestosCarro( );
          vent.setVisible( true );
     }
     …
 }
Quién crea el modelo del mundo?
• La interfaz
• En el método constructor de la ventana
  principal
 public class InterfazImpuestosCarro extends JFrame
 {
   …
   private CalculadorImpuestos calculador;

     public InterfazImpuestosCarro( ) throws Exception
     {
          calculador = new CalculadorImpuestos( );
          …
     }
     …
 }
Arquitectura propuesta
• Los requerimientos funcionales se
  implementan en la ventana principal:

  – Hay UN método por REQUERIMIENTO

  – La ventana principal coordina todas las
    acciones
Reacción a un evento generado
 por el usuario (1 de 6 pasos)

               El usuario genera un
               evento oprimiendo un
               botón en uno de los
               paneles de la interfaz
Reacción a un evento generado
    por el usuario (2 de 6 pasos)

public class PanelResultados extends JPanel implements ActionListener
{
  …
  public void actionPerformed (ActionEvent evento )
  {
    String comando = evento.getActionCommand( );
    if ( (comando.equals( LIMPIAR) )                      El panel reacciona
    {                                                     al evento con SU
         // Reacción al evento de LIMPIAR
    }
                                                          método
    else if (comando.equals( CALCULAR ) )                 actionPerformed
    {
         // Reacción al evento de CALCULAR
    }
  }
  …
Reacción a un evento generado
    por el usuario (2 de 6 pasos)

public class PanelResultados extends JPanel implements ActionListener
{
  …
  public void actionPerformed (ActionEvent evento )
  {
    String comando = evento.getActionCommand( );
    if ( (comando.equals( LIMPIAR) )
    {
         // Reacción al evento de LIMPIAR
                                                         Llamado a métodos de la
    }
                                                         ventana principal !!!
    else if (comando.equals( CALCULAR ) )
    {
         // Reacción al evento de CALCULAR                Hay UN método por
    }                                                     REQUERIMIENTO
  }
  …
Reacción a un evento generado
    por el usuario (2 de 6 pasos)

public class PanelResultados extends JPanel implements ActionListener
{
  …
  public void actionPerformed (ActionEvent evento )
  {
    String comando = evento.getActionCommand( );
    if ( (comando.equals( LIMPIAR) )
    {
         principal.limpiar( );                               Método “limpiar” de la
    }                                                        ventana principal
    else if (comando.equals( CALCULAR ) )
    {
         principal.calcularImpuestos( );
                                                             Método “calcularImpuestos”
    }
                                                             de la ventana principal
  }
  …
Reacción a un evento generado
    por el usuario (2 de 6 pasos)

public class PanelResultados extends JPanel implements ActionListener
{
  …
  public void actionPerformed (ActionEvent evento )
  {
    String comando = evento.getActionCommand( );
    if ( (comando.equals( LIMPIAR) )
    {
         principal.limpiar( );                      • Quién es “principal”?
    }
    else if (comando.equals( CALCULAR ) )           • Dónde está ?
    {                                               • Quién lo conoce ?
         principal.calcularImpuestos( );
    }
  }
  …
principal


                                   principal




• Quién es “principal”?
   R// Es el objeto que contiene la ventana principal
• Dónde está ?
   R// Es un atributo (asociación) de las clases panelResultados y
     panelVehiculo
• Quién lo conoce ?
Entonces …
public class PanelVehiculo extends JPanel implements ActionListener
{
  …
  private InterfazImpuestosCarro principal;                La clase del panel
  …                                                        contiene un atributo del
                                                          tipo de la ventana
    public PanelVehiculo( InterfazImpuestosCarro v)       principal
    {
      …
      principal = v;
      …
    }
    …
}
Entonces …
public class PanelVehiculo extends JPanel implements ActionListener
{
  …
  private InterfazImpuestosCarro principal;
  …

    public PanelVehiculo( InterfazImpuestosCarro v)
    {
      …
      principal = v;
      …                                                     El método constructor
    }                                                       del panel DEBE recibir
    …                                                       como parámetro, el
}                                                           objeto correspondiente a
                                                            la ventana principal
Entonces …
public class PanelVehiculo extends JPanel implements ActionListener
{
  …
  private InterfazImpuestosCarro principal;
  …

    public PanelVehiculo( InterfazImpuestosCarro v)
    {
      …
      principal = v;
      …
    }
    …                Se asigna el parámetro
}                 al atributo
Entonces …
 public class InterfazImpuestosCarro extends JFrame
{
   private PanelVehiculo panelVehiculo;
   private PanelDescuentos panelDescuentos;
   private PanelResultados panelResultados;

  public InterfazImpuestosCarro( ) throws Exception    En el método
  {                                                    constructor de la
    setLayout( new BorderLayout( ) );                  ventana principal

      panelVehiculo = new PanelVehiculo( this );
      add( panelVehiculo, BorderLayout.NORTH );

      panelDescuentos = new PanelDescuentos( );
      add( panelDescuentos, BorderLayout.CENTER );

      panelResultados = new PanelResultados( this );
      add( panelResultados, BorderLayout.SOUTH );
  }
Entonces …
 public class InterfazImpuestosCarro extends JFrame
{
   private PanelVehiculo panelVehiculo;
   private PanelDescuentos panelDescuentos;
   private PanelResultados panelResultados;

  public InterfazImpuestosCarro( ) throws Exception
  {
    setLayout( new BorderLayout( ) );

      panelVehiculo = new PanelVehiculo( this );       Cuando se crean los
      add( panelVehiculo, BorderLayout.NORTH );        paneles
      panelDescuentos = new PanelDescuentos( );
      add( panelDescuentos, BorderLayout.CENTER );

      panelResultados = new PanelResultados( this );
      add( panelResultados, BorderLayout.SOUTH );
  }
Entonces …
 public class InterfazImpuestosCarro extends JFrame
{
   private PanelVehiculo panelVehiculo;
   private PanelDescuentos panelDescuentos;
   private PanelResultados panelResultados;

  public InterfazImpuestosCarro( ) throws Exception
  {
    setLayout( new BorderLayout( ) );

      panelVehiculo = new PanelVehiculo( this );
                                                       Se pasa como parámetro la
      add( panelVehiculo, BorderLayout.NORTH );
                                                       ventana principal (this) a los
      panelDescuentos = new PanelDescuentos( );        métodos constructores de los
      add( panelDescuentos, BorderLayout.CENTER );     paneles que la necesitan

      panelResultados = new PanelResultados( this );
      add( panelResultados, BorderLayout.SOUTH );
  }
Entonces …
 public class InterfazImpuestosCarro extends JFrame
{
   private PanelVehiculo panelVehiculo;
   private PanelDescuentos panelDescuentos;
   private PanelResultados panelResultados;

  public InterfazImpuestosCarro( ) throws Exception    En el método
  {                                                    constructor de la
    setLayout( new BorderLayout( ) );                  ventana principal

      panelVehiculo = new PanelVehiculo( this );
      add( panelVehiculo, BorderLayout.NORTH );
                                                          Se agrega cada
      panelDescuentos = new PanelDescuentos( );           panel en una posición
      add( panelDescuentos, BorderLayout.CENTER );        de las definidas en el
                                                          distribuidor gráfico
      panelResultados = new PanelResultados( this );
      add( panelResultados, BorderLayout.SOUTH );
  }
Recordemos (1 de 6 pasos)…


             El usuario genera un
             evento oprimiendo un
             botón en uno de los
             paneles de la interfaz
Recordemos (2 de 6 pasos)…

public class PanelResultados extends JPanel implements ActionListener
{
  …
  public void actionPerformed (ActionEvent evento )
  {
    String comando = evento.getActionCommand( );
                                                      El panel reacciona al
    if ( (comando.equals( LIMPIAR) )
    {
                                                      evento con SU método
          principal.limpiar( );
                                                      actionPerformed dentro
    }                                                 del cual se analiza el
    else if (comando.equals( CALCULAR ) )             evento y se llama al
    {                                                 método correspondiente
          principal.calcularImpuestos( );             de la ventana principal
    }
  }
  …
Reacción a un evento generado
     por el usuario (3 de 6 pasos)

public void calcularImpuestos( )                   El método de la ventana
 {                                                 principal:
   String unaMarca = panelVehiculo.darMarca( );      Completa la información
   String unaLinea = panelVehiculo.darLinea( );      necesaria, pidiéndola a los
   String unModelo = panelVehiculo.darModelo( );     demás paneles




}
Entonces …
 public class PanelVehiculo extends JPanel implements ActionListener
{
  …

    public String darMarca( )                                    En la clase del panel
    {                                                            respectivo
      return txtMarca.getText( );
    }
                                                                  Existen métodos para
    …
                                                                  pasar la información
}                                                                 a la ventana principal
Volviendo al paso 3 de 6

public void calcularImpuestos( )                   El método de la ventana
 {                                                 principal:
   String unaMarca = panelVehiculo.darMarca( );      Completa la información
   String unaLinea = panelVehiculo.darLinea( );      necesaria, pidiéndola a los
   String unModelo = panelVehiculo.darModelo( );     demás paneles




}
Volviendo al paso 3 de 6
    public void calcularImpuestos( )
     {
       String unaMarca = panelVehiculo.darMarca( );
       String unaLinea = panelVehiculo.darLinea( );
       String unModelo = panelVehiculo.darModelo( );

       if( unaMarca.equals( "" ) || unaLinea.equals( "" ) || unModelo.equals( "" ) )
       {
           JOptionPane.showMessageDialog( this, "Por favor llene todos los datos",
                             "Cálculo de Impuestos", JOptionPane.ERROR_MESSAGE );
       }
       else                                                 El método de la ventana
       {                                                    principal:
            ….
       }
                                                                         Completa la información
                                                                necesaria, pidiéndola a los
}
                                                                demás paneles
                                                                Verifica que la información
                                                                esté completa y sea válida
Volviendo al paso 3 de 6
    public void calcularImpuestos( )
     {
       String unaMarca = panelVehiculo.darMarca( );
       String unaLinea = panelVehiculo.darLinea( );
       String unModelo = panelVehiculo.darModelo( );

       if( unaMarca.equals( "" ) || unaLinea.equals( "" ) || unModelo.equals( "" ) )
       {
           JOptionPane.showMessageDialog( this, "Por favor llene todos los datos",
                             "Cálculo de Impuestos", JOptionPane.ERROR_MESSAGE );
       }
       else
       {
            ….
                                          En caso de problema, puede
       }                                  cancelar la reacción y notificar al
}                                     usuario del problema
Reacción a un evento generado por el
              usuario (4 de 6 pasos)
public void calcularImpuestos( )
 {
   …
   if( unaMarca.equals( "" ) || …
   {
       JOptionPane.showMessageDialog …                                                         El método de
   }                                                                                           la ventana
   else
   {
                                                                                               principal:
       boolean descProntoPago = panelDescuentos.hayDescuentoProntoPago( );                         Pide al
       boolean descServicioPublico = panelDescuentos.hayDescuentoServicioPublico( );               modelo del
       boolean descTrasladoCuenta = panelDescuentos.hayDescuentoTrasladoCuenta( );                 mundo que
       try                                                                                         haga una
       {                                                                                           modificación
            double pago = calculador.calcularPago( unaMarca, unaLinea, unModelo, descProntoPago,   o calcule un
                                                  descServicioPublico, descTrasladoCuenta );
            panelResultados.refrescarPago( pago );
                                                                                                   valor
       }
       catch( Exception e )
       {
           JOptionPane.showMessageDialog( this, e.getMessage( ), "Cálculo de Impuestos",
   JOptionPane.WARNING_MESSAGE );
       }
   }
 }
Entonces …
La ventana principal DEBE conocer el mundo para poder llamar a sus
métodos




               principal
                                                   calculador


                                      principal
Entonces …
 public class InterfazImpuestosCarro extends JFrame
{
  /** Calculador de impuestos */
  private CalculadorImpuestos calculador;               La clase de la ventana
                                                        principal contiene un
     ….                                                 atributo que es el objeto
                                                        del mundo (de la clase
                                                        principal del mundo)
    public InterfazImpuestosCarro( ) throws Exception
     {
         // Crea el calculador de impuestos
         calculador = new CalculadorImpuestos( );

         // Configura la información de la ventana
         setTitle( "Cálculo impuestos" );
         …
     }

}
Entonces …
 public class InterfazImpuestosCarro extends JFrame
{
  /** Calculador de impuestos */
  private CalculadorImpuestos calculador;

     ….



    public InterfazImpuestosCarro( ) throws Exception
     {
         // Crea el calculador de impuestos             En el método constructor
         calculador = new CalculadorImpuestos( );       de la ventana principal,
                                                        se crea el objeto del
         // Configura la información de la ventana      mundo
         setTitle( "Cálculo impuestos" );
         …
     }

}
Volviendo al paso 4 de 6
public void calcularImpuestos( )
 {
   …
   if( unaMarca.equals( "" ) || …
   {
       JOptionPane.showMessageDialog …                                                         El método de
   }                                                                                           la ventana
   else
   {
                                                                                               principal:
       boolean descProntoPago = panelDescuentos.hayDescuentoProntoPago( );                         Pide al
       boolean descServicioPublico = panelDescuentos.hayDescuentoServicioPublico( );               modelo del
       boolean descTrasladoCuenta = panelDescuentos.hayDescuentoTrasladoCuenta( );                 mundo que
       try                                                                                         haga una
       {                                                                                           modificación
            double pago = calculador.calcularPago( unaMarca, unaLinea, unModelo, descProntoPago,   o calcule un
                                                  descServicioPublico, descTrasladoCuenta );
            panelResultados.refrescarPago( pago );
                                                                                                   valor
       }
       catch( Exception e )
       {
           JOptionPane.showMessageDialog( this, e.getMessage( ), "Cálculo de Impuestos",
   JOptionPane.WARNING_MESSAGE );
       }
   }
 }
Reacción a un evento generado por el
              usuario (5 de 6 pasos)
public void calcularImpuestos( )
 {                                                                                             El método de
   …                                                                                           la ventana
   if( unaMarca.equals( "" ) || …
   {
                                                                                               principal:
       JOptionPane.showMessageDialog …                                                             Pide al
   }                                                                                               modelo del
   else                                                                                            mundo que
   {                                                                                               haga una
       boolean descProntoPago = panelDescuentos.hayDescuentoProntoPago( );
                                                                                                   modificación
       boolean descServicioPublico = panelDescuentos.hayDescuentoServicioPublico( );
       boolean descTrasladoCuenta = panelDescuentos.hayDescuentoTrasladoCuenta( );
                                                                                                   o calcule un
       try
                                                                                                   valor
       {                                                                                           Si se pidió
            double pago = calculador.calcularPago( unaMarca, unaLinea, unModelo, descProntoPago,   una
                                                  descServicioPublico, descTrasladoCuenta );       modificación,
            panelResultados.refrescarPago( pago );                                                 se llaman los
       }
       catch( Exception e )
                                                                                                   métodos que
       {
                                                                                                   retornan los
           JOptionPane.showMessageDialog( this, e.getMessage( ), "Cálculo de Impuestos",           nuevos
   JOptionPane.WARNING_MESSAGE );                                                                  valores que
       }                                                                                           se deben
   }                                                                                               desplegar
 }
Reacción a un evento generado por el
              usuario (6 de 6 pasos)
public void calcularImpuestos( )
 {                                                                                           El método de
   …                                                                                         la ventana
   if( unaMarca.equals( "" ) || …
   {
                                                                                             principal:
       JOptionPane.showMessageDialog …                                                             Pide a todos
   }                                                                                               los paneles
   else                                                                                            que tienen
   {                                                                                               información
       boolean descProntoPago = panelDescuentos.hayDescuentoProntoPago( );
                                                                                                   que pudo
       boolean descServicioPublico = panelDescuentos.hayDescuentoServicioPublico( );
       boolean descTrasladoCuenta = panelDescuentos.hayDescuentoTrasladoCuenta( );
                                                                                                   haber
       try
                                                                                                   cambiado,
       {                                                                                           que actualicen
            double pago = calculador.calcularPago( unaMarca, unaLinea, unModelo, descProntoPago,   sus valores
                                                  descServicioPublico, descTrasladoCuenta );       (REFRESCO)
            panelResultados.refrescarPago( pago );
       }
       catch( Exception e )
       {
           JOptionPane.showMessageDialog( this, e.getMessage( ), "Cálculo de Impuestos",
   JOptionPane.WARNING_MESSAGE );
       }
   }
 }
Entonces …
/**                                                En la clase del panel
   * Cambia el valor desplegado del pago
                                                     (Panelresultados) existe
   * @param pago - nuevo pago a desplegar
   */                                                el método refrescarPago
  public void refrescarPago( double pago )
  {
      //Despliega el valor del vehiculo
      DecimalFormat df = ( DecimalFormat )NumberFormat.getInstance( );
      df.applyPattern( "$ ###,###.##" );
      txtTotal.setText( df.format( pago ) );
  }
Entonces …
/**
   * Cambia el valor desplegado del pago             Utiliza la clase
   * @param pago - nuevo pago a desplegar            DecimalFormat de Java
   */                                                para dar un formato
  public void refrescarPago( double pago )
                                                     especial a un número
  {
      //Despliega el valor del vehiculo
      DecimalFormat df = ( DecimalFormat )NumberFormat.getInstance( );
      df.applyPattern( "$ ###,###.##" );
      txtTotal.setText( df.format( pago ) );
  }
Entonces …
/**
   * Cambia el valor desplegado del pago
   * @param pago - nuevo pago a desplegar
   */
  public void refrescarPago( double pago )
  {
      //Despliega el valor del vehiculo
      DecimalFormat df = ( DecimalFormat )NumberFormat.getInstance( );
      df.applyPattern( "$ ###,###.##" );
      txtTotal.setText( df.format( pago ) );
  }


                                    Pone el valor del pago
                                    en la zona de texto
                                    llamada txtTotal, en
                                    formato String
Validación y Formateo de
          Datos
Qué pasa con la información
 tecleada por el usuario en una
         zona de texto
• La información SIEMPRE es recibida por la
  interfaz como cadena de caracteres
• La interfaz tiene la responsabilidad de:
     Convertirla al tipo adecuado (ej: entero o
    minúsculas)
    Advertir al usuario si hay algún error, cuando el
    usuario teclea algo que no corresponde a lo esperado
    (ej: teclea una letra y se espera un número)
Para convertir la cadena de
  caracteres al tipo adecuado …
• A un número:
  – Se usa el método parseInt de la clase Integer de Java.
  – Se captura la excepción NumberFormatException que lanza el método
    parseInt si la cadena no se puede convertir en número

  try
  {
    int nCantidad = Integer.parseInt ( strCantidad );
  }
   catch (NumberFormatException e)
  {
     // Mensaje al usuario
  }
Para convertir la cadena de
  caracteres al tipo adecuado …
• A mayúsculas/minúsculas (y otros tipos de
  conversión de cadenas de caracteres):
  – La clase String de Java provee métodos para
    transformar la cadena de caracteres tecledada
    por el usuario (y en general cualquier cadena de
    caracteres):
    • toLowerCase(): pasa a minúsculas
    • toUpperCase(): pasa a mayúsculas
    • Trim: elimina espacios en blanco al inicio y final de la
      cadena
Mensajes al Usuario y
Lectura Simple de Datos
Mensajes en la Consola
System.out.println(“Este en un mensaje de prueba de ERROR”);

  Si se ejecuta desde eclipse, el mensaje
  aparece en la ventana Console




                                            Si se ejecuta por fuera de eclipse (con
                                                           run.bat)
Mensajes en una ventana
JOptionPane.showMessageDialog
                                                Debe ser null si se usa
                                                en el main

        JOptionPane.showMessageDialog( this, "Por favor llene todos los
        datos", "Calculo de Impuestos", JOptionPane.ERROR_MESSAGE );




        JOptionPane.showMessageDialog( null, "La marca ferrari no está
        registrada", "Calculo de Impuestos", JOptionPane.WARNING_MESSAGE );




        JOptionPane.showMessageDialog( this, "El valor total es de $12.000",
        "Calculo de Impuestos", JOptionPane.INFORMATION_MESSAGE );
Para pedir información al usuario
JOptionPane.showInputDialog                             Debe ser null si se usa
                                                        en el main

                 String clave = JOptionPane.showInputDialog( this, "Introduzca su
                 clave");

                 if ( clave != null)
                 {
                     …
                 }


JOptionPane.showConfirmDialog
             int resp = JOptionPane.showConfirmDialog( null, "Está seguro que lo
             desea borrar?", "Confirmacion", JOptionPane.YES_NO_OPTION);

             if ( resp == JOptionPane.YES_OPTION)
             {
                     ...
             }

Más contenido relacionado

Similar a interfaz grafica

Lps 15 gu-iconswing
Lps 15 gu-iconswingLps 15 gu-iconswing
Lps 15 gu-iconswingjbersosa
 
Programa
ProgramaPrograma
Programapau
 
Algoritmos, dfd, pseudocodigo
Algoritmos, dfd, pseudocodigoAlgoritmos, dfd, pseudocodigo
Algoritmos, dfd, pseudocodigoAdolfoReyes24
 
Introducción a la Programación
Introducción a la ProgramaciónIntroducción a la Programación
Introducción a la ProgramaciónPablo Parola
 
Introducción A La Programación
Introducción A La ProgramaciónIntroducción A La Programación
Introducción A La ProgramaciónPablo Parola
 
Algoritmos y programas 1 arena
Algoritmos y programas 1   arenaAlgoritmos y programas 1   arena
Algoritmos y programas 1 arenaRomario Fajardo
 
Clase 3-algoritmos[1]
Clase 3-algoritmos[1]Clase 3-algoritmos[1]
Clase 3-algoritmos[1]tanztanz
 
Clase 3-algoritmos
Clase 3-algoritmosClase 3-algoritmos
Clase 3-algoritmos142918
 
Attachment.ashx (2)
Attachment.ashx (2)Attachment.ashx (2)
Attachment.ashx (2)samantha
 
Clase 3-algoritmos
Clase 3-algoritmosClase 3-algoritmos
Clase 3-algoritmosRamon
 
Clase 3-algoritmos
Clase 3-algoritmosClase 3-algoritmos
Clase 3-algoritmoskristel24
 
3 resolucion de problemas con la computadora
3 resolucion de problemas con la computadora3 resolucion de problemas con la computadora
3 resolucion de problemas con la computadoraMIGUEL
 

Similar a interfaz grafica (20)

Graficas matlab
Graficas matlabGraficas matlab
Graficas matlab
 
Uso de tics
Uso de ticsUso de tics
Uso de tics
 
Lps 15 gu-iconswing
Lps 15 gu-iconswingLps 15 gu-iconswing
Lps 15 gu-iconswing
 
Matlab
MatlabMatlab
Matlab
 
Matlab
MatlabMatlab
Matlab
 
Programa
ProgramaPrograma
Programa
 
Algoritmos, dfd, pseudocodigo
Algoritmos, dfd, pseudocodigoAlgoritmos, dfd, pseudocodigo
Algoritmos, dfd, pseudocodigo
 
Programación.pptx
Programación.pptxProgramación.pptx
Programación.pptx
 
Diagrama de-flujo
Diagrama de-flujoDiagrama de-flujo
Diagrama de-flujo
 
Algoritmos
AlgoritmosAlgoritmos
Algoritmos
 
Introducción a la Programación
Introducción a la ProgramaciónIntroducción a la Programación
Introducción a la Programación
 
Introducción A La Programación
Introducción A La ProgramaciónIntroducción A La Programación
Introducción A La Programación
 
Algoritmos y programas 1 arena
Algoritmos y programas 1   arenaAlgoritmos y programas 1   arena
Algoritmos y programas 1 arena
 
Clase 3-algoritmos[1]
Clase 3-algoritmos[1]Clase 3-algoritmos[1]
Clase 3-algoritmos[1]
 
Clase 3-algoritmos
Clase 3-algoritmosClase 3-algoritmos
Clase 3-algoritmos
 
Clase 3
Clase 3Clase 3
Clase 3
 
Attachment.ashx (2)
Attachment.ashx (2)Attachment.ashx (2)
Attachment.ashx (2)
 
Clase 3-algoritmos
Clase 3-algoritmosClase 3-algoritmos
Clase 3-algoritmos
 
Clase 3-algoritmos
Clase 3-algoritmosClase 3-algoritmos
Clase 3-algoritmos
 
3 resolucion de problemas con la computadora
3 resolucion de problemas con la computadora3 resolucion de problemas con la computadora
3 resolucion de problemas con la computadora
 

Último

Code name Anastasia parte - 1(1)-páginas-3.pdf
Code name Anastasia parte - 1(1)-páginas-3.pdfCode name Anastasia parte - 1(1)-páginas-3.pdf
Code name Anastasia parte - 1(1)-páginas-3.pdfnaladosol
 
TRIFOLIO DIA DE LA TIERRA.pdf Perdida libertad y educación social. • Pérdida ...
TRIFOLIO DIA DE LA TIERRA.pdf Perdida libertad y educación social. • Pérdida ...TRIFOLIO DIA DE LA TIERRA.pdf Perdida libertad y educación social. • Pérdida ...
TRIFOLIO DIA DE LA TIERRA.pdf Perdida libertad y educación social. • Pérdida ...univerzalworld
 
Matemática universitaria de AlgebraLineal.pdf
Matemática universitaria de AlgebraLineal.pdfMatemática universitaria de AlgebraLineal.pdf
Matemática universitaria de AlgebraLineal.pdfFAUSTODANILOCRUZCAST
 
(HOTD) Las Grandes Casas de Westeros y su estado previo a la Danza de los Dra...
(HOTD) Las Grandes Casas de Westeros y su estado previo a la Danza de los Dra...(HOTD) Las Grandes Casas de Westeros y su estado previo a la Danza de los Dra...
(HOTD) Las Grandes Casas de Westeros y su estado previo a la Danza de los Dra...patriciooviedo3
 
20 poemas de amor y una canción desesperada.pdf
20 poemas de amor y una canción desesperada.pdf20 poemas de amor y una canción desesperada.pdf
20 poemas de amor y una canción desesperada.pdfalbertozb15
 
RESUMEN DE LA PELÍCULA DE CHERNOBYL ENFOCADO A MEDICINA DEL TRABAJO
RESUMEN DE LA PELÍCULA DE CHERNOBYL ENFOCADO A MEDICINA DEL TRABAJORESUMEN DE LA PELÍCULA DE CHERNOBYL ENFOCADO A MEDICINA DEL TRABAJO
RESUMEN DE LA PELÍCULA DE CHERNOBYL ENFOCADO A MEDICINA DEL TRABAJOLuisFigueroa230128
 
Mujeres que corren con los lobos en la noche.pdf
Mujeres que corren con los lobos en la noche.pdfMujeres que corren con los lobos en la noche.pdf
Mujeres que corren con los lobos en la noche.pdfKeilly Merlo
 
Code name Anastasia parte - 1(1)-páginas-1.pdf
Code name Anastasia parte - 1(1)-páginas-1.pdfCode name Anastasia parte - 1(1)-páginas-1.pdf
Code name Anastasia parte - 1(1)-páginas-1.pdfnaladosol
 
Programación de las Fiestas de San Isidro 2024.pdf
Programación de las Fiestas de San Isidro 2024.pdfProgramación de las Fiestas de San Isidro 2024.pdf
Programación de las Fiestas de San Isidro 2024.pdf20minutos
 

Último (9)

Code name Anastasia parte - 1(1)-páginas-3.pdf
Code name Anastasia parte - 1(1)-páginas-3.pdfCode name Anastasia parte - 1(1)-páginas-3.pdf
Code name Anastasia parte - 1(1)-páginas-3.pdf
 
TRIFOLIO DIA DE LA TIERRA.pdf Perdida libertad y educación social. • Pérdida ...
TRIFOLIO DIA DE LA TIERRA.pdf Perdida libertad y educación social. • Pérdida ...TRIFOLIO DIA DE LA TIERRA.pdf Perdida libertad y educación social. • Pérdida ...
TRIFOLIO DIA DE LA TIERRA.pdf Perdida libertad y educación social. • Pérdida ...
 
Matemática universitaria de AlgebraLineal.pdf
Matemática universitaria de AlgebraLineal.pdfMatemática universitaria de AlgebraLineal.pdf
Matemática universitaria de AlgebraLineal.pdf
 
(HOTD) Las Grandes Casas de Westeros y su estado previo a la Danza de los Dra...
(HOTD) Las Grandes Casas de Westeros y su estado previo a la Danza de los Dra...(HOTD) Las Grandes Casas de Westeros y su estado previo a la Danza de los Dra...
(HOTD) Las Grandes Casas de Westeros y su estado previo a la Danza de los Dra...
 
20 poemas de amor y una canción desesperada.pdf
20 poemas de amor y una canción desesperada.pdf20 poemas de amor y una canción desesperada.pdf
20 poemas de amor y una canción desesperada.pdf
 
RESUMEN DE LA PELÍCULA DE CHERNOBYL ENFOCADO A MEDICINA DEL TRABAJO
RESUMEN DE LA PELÍCULA DE CHERNOBYL ENFOCADO A MEDICINA DEL TRABAJORESUMEN DE LA PELÍCULA DE CHERNOBYL ENFOCADO A MEDICINA DEL TRABAJO
RESUMEN DE LA PELÍCULA DE CHERNOBYL ENFOCADO A MEDICINA DEL TRABAJO
 
Mujeres que corren con los lobos en la noche.pdf
Mujeres que corren con los lobos en la noche.pdfMujeres que corren con los lobos en la noche.pdf
Mujeres que corren con los lobos en la noche.pdf
 
Code name Anastasia parte - 1(1)-páginas-1.pdf
Code name Anastasia parte - 1(1)-páginas-1.pdfCode name Anastasia parte - 1(1)-páginas-1.pdf
Code name Anastasia parte - 1(1)-páginas-1.pdf
 
Programación de las Fiestas de San Isidro 2024.pdf
Programación de las Fiestas de San Isidro 2024.pdfProgramación de las Fiestas de San Isidro 2024.pdf
Programación de las Fiestas de San Isidro 2024.pdf
 

interfaz grafica

  • 1. ALGORITMICA Y PROGRAMACION POR OBJETOS I Nivel 5 Construyendo la Interfaz Gráfica Marcela Hernández Hoyos
  • 2. Motivación Interfaz usuario Modelo del mundo Usuario Único medio de comunicación entre el usuario y el modelo del mundo
  • 3. Motivación Interfaz usuario Modelo del mundo Usuario • Ejecuta operaciones A través de la interfaz: sobre el modelo del mundo. • Ve el resultado de sus acciones.
  • 4. Aspectos importantes Diseño funcional y Arquitectura gráfico • Colores • Estructura clara • Distribución de • Fácil de mantener elementos gráficos (menús, botones, …)
  • 5. Qué vamos a aprender en este nivel: Cómo proponer una arquitectura para un programa simple: – Repartir responsabilidades entre interfaz, mundo y pruebas. Cómo construir las clases que implementan una interfaz usuario Cómo integrar las clases de la interfaz con las clases del mundo
  • 6. Caso de estudio: Calculador de Impuestos
  • 7. El Calculador de Impuestos • Funcionalidad • Interfaz usuario • Requerimientos Funcionales • Arquitectura – Mundo – Interfaz
  • 8. El Calculador de Impuestos - Funcionalidad • Calcula el valor de los impuestos que una persona debe pagar por su carro • Vehículo se caracteriza por: – Marca, línea, modelo y precio • Cálculo de impuestos como porcentaje del precio del vehículo (% determinado por un rango) • Hay tres tipos de descuento – Pronto pago, servicio público, traslado de cuenta
  • 9. El Calculador de Impuestos – Interfaz usuario Ventana Principal 3 Zonas de trabajo: Información del vehículo Descuentos Cálculo de impuestos + inicializar la aplicación
  • 10. El Calculador de Impuestos – Requerimientos Funcionales R1 Buscar el avalúo de un vehículo R2 Calcular el pago de impuesto de un vehículo RNF Requerimiento NO FUNCIONAL (inicializar la aplicación sin tener que volver a ejecutarla)
  • 11. Tarea No. 1 • RF1: Buscar el avalúo de un vehículo – Resumen: • Dada la información del vehículo, presentar el valor de avalúo del mismo – Entradas: – Resultado:
  • 12. Tarea No. 1 • RF2:Calcular el pago de impuesto de un vehículo – Resumen: • Dada la información de un vehículo, y el conjunto de descuentos que le aplican, dar el valor a pagar por los impuestos del vehículo – Entradas: – Resultado:
  • 13. El Calculador de Impuestos – Arquitectura Mundo Interfaz
  • 14. El Calculador de Impuestos (Mundo) 0 .. n rangos 0 .. n marcas 0 .. n 0 .. n lineas modelos
  • 15.
  • 16. Tarea No. 2 • CalculadorImpuestos – Constantes – Asociaciones • Marca – Atributos – Asociaciones • Linea – Atributos – Asociaciones • Modelo – Atributos • RangoImpuesto – Atributos
  • 17. Métodos de la clase CalculadorImpuestos (pag. 3) buscarAvaluoVehiculo /** * Retorna el valor de avalúo de un vehiculo de la marca, línea y modelo dado. * @param unaMarca - marca del vehiculo * @param unaLinea - linea del vehiculo * @param unModelo - modelo del vehiculo * @return precio de avalúo del vehiculo * @throws Exception si no encuentra la marca o la linea o el modelo registrados */ public double buscarAvaluoVehiculo( String unaMarca, String unaLinea, String unModelo ) throws Exception
  • 18. Métodos de la clase CalculadorImpuestos (pag. 3) calcularPago /** * Calcular el pago de impuesto que debe hacer un vehículo de un modelo dado. Si no encuentra un rango para el modelo devuelve 0 * @param unaMarca - marca del vehiculo * @param unaLinea - linea del vehiculo * @param unModelo - modelo del vehiculo * @param descProntoPago - indica si aplica el descuento por pronto pago * @param descServicioPublico - indica si aplica el descuento por servicio público * @param descTrasladoCuenta - indica si aplica el descuento por traslado de cuenta * @return valor a pagar * @throws Exception si no encuentra el vehiculo dado por la marca, la linea y el modelo */ public double calcularPago( String unaMarca, String unaLinea, String unModelo, boolean descProntoPago, boolean descServicioPublico, boolean descTrasladoCuenta ) throws Exception
  • 20. El Calculador de Impuestos – Interfaz usuario Ventana Principal 3 Zonas de trabajo: Información del vehículo Descuentos Cálculo de impuestos + inicializar la aplicación
  • 21. El Calculador de Impuestos – Interfaz usuario InterfazImpuestosCarro (JFrame) 3 Zonas de trabajo: PanelVehiculo (JPanel) PanelDescuentos (JPanel) PanelResultados (JPanel)
  • 22. El Calculador de Impuestos – Interfaz usuario InterfazImpuestosCarro (JFrame) PanelVehiculo (JPanel) Clases PanelDescuentos (JPanel) JAVA PanelResultados (JPanel)
  • 23. Entidades Mundo del Problema Mundo Gráfico y de Interacción • Estudiante • Ventana (JFrame) • Tienda • Panel (JPanel) • Banco • Botón (JButton) • Recurso • Zona de texto (JTextField) • Avion • Etiqueta (JLabel) • … • Caja de chequeo (JCheckBox)
  • 24. Entidades del mundo gráfico y de interacción Ventana
  • 25. Entidades del mundo gráfico y de interacción Panel
  • 26. Entidades del mundo gráfico y de interacción Zona de texto
  • 27. Entidades del mundo gráfico y de interacción Caja de chequeo
  • 28. Entidades del mundo gráfico y de interacción Etiqueta
  • 29. Entidades del mundo gráfico y de interacción Boton
  • 30. El Calculador de Impuestos (Interfaz) principal principal
  • 31. El Calculador de Impuestos – Interfaz usuario InterfazImpuestosCarro (JFrame) 3 Zonas de trabajo: PanelVehiculo (JPanel) PanelDescuentos (JPanel) PanelResultados (JPanel)
  • 32. El Calculador de Impuestos – Interfaz usuario InterfazImpuestosCarro (JFrame) PanelVehiculo (JPanel) Clases PanelDescuentos (JPanel) JAVA PanelResultados (JPanel)
  • 33. El Calculador de Impuestos – Interfaz usuario InterfazImpuestosCarro (JFrame) PanelVehiculo (JPanel) •Se encuentran en una PanelDescuentos (JPanel) biblioteca gráfica (swing) •Paquete: java.swing PanelResultados (JPanel) •Deber ser importado
  • 34. Elementos gráficos estructurales
  • 36. La Ventana Principal • Contiene TODOS los elementos de visualización e interacción (con los que el usuario va a utilizar el programa) • UNICA FUNCION: – Servir como marco para los demás elementos de la interfaz (AGRUPA) • Es un contenedor gráfico
  • 37. La Ventana Principal Título Controles para cerrar el programa
  • 38. La Ventana Principal principal principal Ventana principal = Objeto de la clase InterfazImpuestosCarro
  • 39. Clase InterfazImpuestosCarro • Como cualquier clase: – Está declarada en su propio archivo: InterfazImpuestosCarro.java (pag. 8) – Sigue las mismas reglas que cualquier clase del mundo • Diferencia: – Está declarada en otro paquete: uniandes.cupi2.impuestosCarro.interfaz (ver en Eclipse)
  • 40. Clase InterfazImpuestosCarro package uniandes.cupi2.impuestosCarro.interfaz; import java.awt.*; import javax.swing.*; import uniandes.cupi2.impuestosCarro.mundo.*; /** * Interfaz de cálculo de impuestos de carros */ public class InterfazImpuestosCarro extends JFrame { }
  • 41. Clase InterfazImpuestosCarro package uniandes.cupi2.impuestosCarro.interfaz; La clase se declara dentro del paquete de las clases de la interfaz usuario
  • 42. Clase InterfazImpuestosCarro package uniandes.cupi2.impuestosCarro.interfaz; import java.awt.*; import javax.swing.*; Se importan las clases de los dos paquetes mostrados (swing y awt)
  • 43. Clase InterfazImpuestosCarro package uniandes.cupi2.impuestosCarro.interfaz; import java.awt.*; import javax.swing.*; import uniandes.cupi2.impuestosCarro.mundo.*; Se importan las clases del modelo del mundo
  • 44. Clase InterfazImpuestosCarro principal principal
  • 45. Clase InterfazImpuestosCarro package uniandes.cupi2.impuestosCarro.interfaz; import java.awt.*; import javax.swing.*; import uniandes.cupi2.impuestosCarro.mundo.*; /** * Interfaz de cálculo de impuestos de carros */ public class InterfazImpuestosCarro extends JFrame { } La clase se declara con la misma sintáxis de las clases del modelo del mundo
  • 46. Clase InterfazImpuestosCarro package uniandes.cupi2.impuestosCarro.interfaz; import java.awt.*; import javax.swing.*; import uniandes.cupi2.impuestosCarro.mundo.*; /** * Interfaz de cálculo de impuestos de carros */ public class InterfazImpuestosCarro extends JFrame { } Se agrega extends JFrame para indicar que es una ventana
  • 47. Clase InterfazImpuestosCarro Clase de swing que se está extendiendo principal principal
  • 48. Clase InterfazImpuestosCarro Cómo cambiar el estado (apariencia) de la ventana?
  • 49. Clase InterfazImpuestosCarro Cómo cambiar el estado (apariencia) de la ventana? R// Con los métodos de la clase JFrame Cambiar el Cambiar el Agregar título de la tamaño de la componentes ventana ventana gráficos
  • 50. Métodos de JFrame • setSize ( ancho, alto ) • setResizable ( true/false ) • setTitle ( titulo ) • setDefaultCloseOperation ( EXIT_ON_CLOSE) • setVisible ( true/false ) • add ( componente )
  • 51. Configuración de la ventana en el método Constructor public InterfazImpuestosCarro( ) { setTitle( "Cálculo impuestos" ); setSize( 290, 350 ); setResizable( false ); setDefaultCloseOperation( EXIT_ON_CLOSE ); setLayout( new BorderLayout( ) ); }
  • 52. Distribuidor gráfico de elementos (layout) • Se encarga de distribuir los elementos (NO tenemos que hacerlo) • Sólo tenemos que asociar a la ventana un objeto de este tipo (clase) que se encargue de hacerlo • Java (swing) tiene varios distribuidores gráficos (varias clases). En APO1 vamos a ver dos: – BorderLayout – GridLayout
  • 53. Configuración de la ventana en el método Constructor public InterfazImpuestosCarro( ) { setTitle( "Cálculo impuestos" ); setSize( 290, 350 ); setResizable( false ); setDefaultCloseOperation( EXIT_ON_CLOSE ); setLayout( new BorderLayout( ) ); }
  • 55. El Calculador de Impuestos – Interfaz usuario InterfazImpuestosCarro (JFrame) 3 Zonas de trabajo: PanelVehiculo (JPanel) PanelDescuentos (JPanel) PanelResultados (JPanel)
  • 56. Un Panel • Se encarga de agrupar elementos gráficos por contenido y uso • Facilita al usuario su localización y su uso • Cada panel se implementa como una clase aparte en el modelo – PanelVehiculo – PanelDescuentos – PanelResultados
  • 57. El Calculador de Impuestos (Interfaz) principal principal
  • 59. Creación de los paneles en el método Constructor public class InterfazImpuestosCarro extends JFrame { private PanelVehiculo panelVehiculo; Se declara un private PanelDescuentos panelDescuentos; atributo por cada una private PanelResultados panelResultados; de las divisiones public InterfazImpuestosCarro( ) throws Exception { setLayout( new BorderLayout( ) ); }
  • 60. Creación de los paneles en el método Constructor public class InterfazImpuestosCarro extends JFrame { private PanelVehiculo panelVehiculo; private PanelDescuentos panelDescuentos; private PanelResultados panelResultados; public InterfazImpuestosCarro( ) throws Exception { Se asocia a la setLayout( new BorderLayout( ) ); ventana un distribuidor gráfico }
  • 61. Creación de los paneles en el método Constructor public class InterfazImpuestosCarro extends JFrame { private PanelVehiculo panelVehiculo; private PanelDescuentos panelDescuentos; private PanelResultados panelResultados; public InterfazImpuestosCarro( ) throws Exception { setLayout( new BorderLayout( ) ); panelVehiculo = new PanelVehiculo( this ); add( panelVehiculo, BorderLayout.NORTH ); Se crea una instancia panelDescuentos = new PanelDescuentos( ); de cada uno de los add( panelDescuentos, BorderLayout.CENTER ); paneles panelResultados = new PanelResultados( this ); add( panelResultados, BorderLayout.SOUTH ); }
  • 62. Creación de los paneles en el método Constructor public class InterfazImpuestosCarro extends JFrame { private PanelVehiculo panelVehiculo; private PanelDescuentos panelDescuentos; private PanelResultados panelResultados; public InterfazImpuestosCarro( ) throws Exception { setLayout( new BorderLayout( ) ); panelVehiculo = new PanelVehiculo( this ); add( panelVehiculo, BorderLayout.NORTH ); Se agrega cada panelDescuentos = new PanelDescuentos( ); panel en una posición add( panelDescuentos, BorderLayout.CENTER ); de las definidas en el distribuidor gráfico panelResultados = new PanelResultados( this ); add( panelResultados, BorderLayout.SOUTH ); }
  • 63. Creación de los paneles en el método Constructor public class InterfazImpuestosCarro extends JFrame { private PanelVehiculo panelVehiculo; private PanelDescuentos panelDescuentos; private PanelResultados panelResultados; public InterfazImpuestosCarro( ) throws Exception { setLayout( new BorderLayout( ) ); panelVehiculo = new PanelVehiculo( this ); add( panelVehiculo, BorderLayout.NORTH ); panelDescuentos = new PanelDescuentos( ); add( panelDescuentos, BorderLayout.CENTER ); panelResultados = new PanelResultados( this ); add( panelResultados, BorderLayout.SOUTH ); }
  • 64. Analicemos la creación del panelVehiculo Atributo panelVehiculo de la clase InterfazImpuestosCarro panelVehiculo = new PanelVehiculo( this ); add( panelVehiculo, BorderLayout.NORTH );
  • 65. Analicemos la creación del panelVehiculo Llamado al constructor de la clase PanelVehiculo panelVehiculo = new PanelVehiculo( this ); add( panelVehiculo, BorderLayout.NORTH );
  • 66. Analicemos la creación del panelVehiculo Parámetro del método Concepto constructor de la nuevo clase PanelVehiculo panelVehiculo = new PanelVehiculo( this ); add( panelVehiculo, BorderLayout.NORTH );
  • 67. Analicemos la creación del panelVehiculo panelVehiculo = new PanelVehiculo( this ); add( panelVehiculo, BorderLayout.NORTH ); Método de la clase JFrame para adicionar un componente
  • 68. Analicemos la creación del panelVehiculo panelVehiculo = new PanelVehiculo( this ); add( panelVehiculo, BorderLayout.NORTH ); Objeto que se va a adicionar
  • 69. Analicemos la creación del panelVehiculo panelVehiculo = new PanelVehiculo( this ); add( panelVehiculo, BorderLayout.NORTH ); Zona (posición relativa dentro de la Concepto nuevo ventana) donde se va a adicionar el objeto. Es una constante de la clase BorderLayout.
  • 70. Dos conceptos nuevos • BorderLayout • this
  • 71. Dos conceptos nuevos • BorderLayout NORTH • Distribuidor gráfico “en los Bordes” • Divide el espacio de la ventana en 5 zonas: NORTH, CENTER, SOUTH, WEST, EAST. • Al agregar un componente a la ventana, SE WEST CENTER EAST DEBE pasar como parámetro la zona donde se va a ubicar. Ejemplo: – add( panelVehiculo, SOUTH BorderLayout.NORTH ); • Utiliza el tamaño definido para cada uno de los componentes y asigna TODO el espacio sobrante al componente que se encuentre en la zona del centro
  • 72. Dos conceptos nuevos • Otro distribuidor: GridLayout • Distribuidor gráfico “en Malla” • Divide el espacio de la ventana en filas y columnas. • La cantidad de filas y columnas se establecen en el método constructor del GridLayout. Ejemplo: – setLayout( new GridLayout ( 4, 3 ) ); Fila 1 1 2 3 • Al agregar un componente a la ventana, NO SE DEBE especificar la posición. Esta es asignada en Fila 2 4 5 6 el orden de llegada (fila 1, fila 2, …) Fila 3 7 8 9 • Ignora el tamaño definido para cada componente. Hace una distribución uniforme del espacio. Fila 4 10 11 12
  • 73. Dos conceptos nuevos • BorderLayout • this
  • 74. Dos conceptos nuevos • this • Es una variable de JAVA • Hace referencia al objeto que está ejecutando un método
  • 75. Ejemplo de uso de this public class InterfazImpuestosCarro extends JFrame { private PanelVehiculo panelVehiculo; private PanelDescuentos panelDescuentos; private PanelResultados panelResultados; public InterfazImpuestosCarro( ) throws Exception { setLayout( new BorderLayout( ) ); panelVehiculo = new PanelVehiculo( this ); add( panelVehiculo, BorderLayout.NORTH ); panelDescuentos = new PanelDescuentos( ); add( panelDescuentos, BorderLayout.CENTER ); panelResultados = new PanelResultados( this ); add( panelResultados, BorderLayout.SOUTH ); }
  • 76. Ejemplo de uso de this Es la ventana principal, (objeto de la clase InterfazImpuestosCarro, que es el “padre” del panel) panelVehiculo = new PanelVehiculo( this ); add( panelVehiculo, BorderLayout.NORTH ); Para qué sirve? … VER MAS ADELANTE
  • 77. Hasta aquí hemos visto … • Cómo construir la clase de la ventana principal (InterfazImpuestosCarro) Ahora vamos a ver … • Cómo construir las clases de los paneles (PanelVehiculo, PanelDescuentos, PanelResultados)
  • 78. Construcción de las clases de los paneles • Proceso similar a la construcción de la clase de la ventana principal • Al igual que la ventana principal, los paneles también son contenedores gráficos Ventana Principal JFrame
  • 79. Construcción de las clases de los paneles • Proceso similar a la construcción de la clase de la ventana principal • Al igual que la ventana principal, los paneles también son contenedores gráficos Ventana Principal Panel JFrame JPanel
  • 80. PanelVehiculo public class PanelVehiculo extends JPanel { public PanelVehiculo( ) { Creación y asociación de … un GridLayout de 5 filas y setLayout( new GridLayout( 5, 2 ) ); setPreferredSize( new Dimension( 0, 130 ) ); 2 columnas … }
  • 81. PanelVehiculo public class PanelVehiculo extends JPanel { public PanelVehiculo( ) Definir la altura del panel. { No se define el ancho … porque va a ser igual al setLayout( new GridLayout( 5, 2 ) ); de la ventana setPreferredSize( new Dimension( 0, 130 ) ); … 130 Clase de Java que permite definir un ancho y un alto usando un objeto }
  • 82. PanelVehiculo public class PanelVehiculo extends JPanel { public PanelVehiculo( ) Se crea y se asocia un { borde al panel para … facilitar la identificación setLayout( new GridLayout( 5, 2 ) ); setPreferredSize( new Dimension( 0, 130 ) ); de las divisiones dentro TitledBorder border = BorderFactory.createTitleBorder de la ventana (“Datos del vehículo”); border.SetTitleColor( Color.BLUE ); setBorder( border ); … }
  • 83. PanelDescuentos public class PanelDescuentos extends JPanel { public PanelVehiculo( ) { Creación y asociación de … un GridLayout de 2 filas y setLayout( new GridLayout( 2, 2 ) ); 2 columnas … }
  • 84. PanelDescuentos public class PanelDescuentos extends JPanel { public PanelVehiculo( ) { Se crea y se asocia un … borde setLayout( new GridLayout( 2, 2 ) ); TitledBorder border = BorderFactory.createTitleBorder (“Descuentos”); border.SetTitleColor( Color.BLUE ); setBorder( border ); … }
  • 85. Etiquetas y Zonas de Texto
  • 86. Etiquetas • Permiten agregar un texto corto en la interfaz • Son objetos de la clase JLabel de Java • Algunos métodos de la clase JLabel: – setText (texto); – setForeground ( color ); Cualquier constante de la clase Color de Java (BLACK, GREEN, RED, BLUE, …) o un nuevo color creado con 3 índices RGB
  • 87. Zonas de texto • Cumplen dos funciones: – Permiten el ingreso de información por parte del usuario (ENTRADAS de los requerimientos funcionales) – Permiten mostrar las respuestas calculadas por el programa • Son objetos de la clase JText de Java • Algunos métodos de la clase JLabel: – getText ( ); Retorna la cadena de caracteres tecleada por el usuario. SIEMPRE es String.
  • 88. Zonas de texto • Cumplen dos funciones: – Permiten el ingreso de información por parte del usuario (ENTRADAS de los requerimientos funcionales) – Permiten mostrar las respuestas calculadas por el programa • Son objetos de la clase JText de Java • Algunos métodos de la clase JLabel: – getText ( ); – setText ( texto ); Despliega el texto que se pasa como parámetro. Se usa para mostrar los resultados del programa.
  • 89. Zonas de texto • Cumplen dos funciones: – Permiten el ingreso de información por parte del usuario (ENTRADAS de los requerimientos funcionales) – Permiten mostrar las respuestas calculadas por el programa • Son objetos de la clase JText de Java • Algunos métodos de la clase JLabel: – getText ( ); – setText ( texto ); Indica si el usuario puede – setEditable ( true / false) o no modificar el texto (escribir encima)
  • 90. Zonas de texto • Cumplen dos funciones: – Permiten el ingreso de información por parte del usuario (ENTRADAS de los requerimientos funcionales) – Permiten mostrar las respuestas calculadas por el programa • Son objetos de la clase JTextField de Java • Algunos métodos de la clase JLabel: – getText ( ); – setText ( texto ); – setEditable ( true / false) – setForeground (color ) Definen respectivamente – setBackground ( color ) el color del texto y del fondo
  • 91. Cómo agregar una etiqueta (o una zona de texto) a un panel Declarar en el panel un atributo de la clase JLabel (o JTextField) Crear la etiqueta (o la zona de texto) (new) en el método constructor del panel Configurar las características de la etiqueta (o de la zona de texto) con los métodos de la clase JLabel (o JTextField) Agregar la etiqueta (o la zona de texto) al panel (add)
  • 92. Ejemplo en PanelVehiculo public class PanelVehiculo extends JPanel { … private JLabel labMarca; private JLabel labLinea; private JLabel labModelo; private JLabel labValor; Declararen el panel los atributos de clases JLabel y private JTextField txtMarca; JTextField private JTextField txtLinea; private JTextField txtModelo; private JTextField txtValor; … }
  • 93. Ejemplo en PanelVehiculo public PanelVehiculo ( ) { … labMarca = new JLabel ( “Marca” ); labLinea = new JLabel ( “Línea” ); Crear las etiquetas labModelo = new JLabel ( “ Modelo” ); y las zonas de labValor = new JLabel ( “ Valor” ); texto (new) en el txtMarca = new JTextField( ); txtLinea = new JTextField( ); método constructor txtModelo = new JTextField( ); del panel txtValor = new JTextField( “$ 0” ); … }
  • 94. Ejemplo en PanelVehiculo public PanelVehiculo ( ) { … labMarca = new JLabel ( “Marca” ); labLinea = new JLabel ( “Línea” ); labModelo = new JLabel ( “ Modelo” ); labValor = new JLabel ( “ Valor” ); txtMarca = new JTextField( ); Configurar las txtLinea = new JTextField( ); características de las txtModelo = new JTextField( ); txtValor = new JTextField( “$ 0” ); etiquetas o de las zonas txtValor.SetEditable(false); de texto con los txtValor.SetForeground(Color.BLUE); métodos de las clases txtValor.SetBackground(Color.WHITE); … JLabel o JTextField }
  • 95. Ejemplo en PanelVehiculo public PanelVehiculo ( ) { … labMarca = new JLabel ( “Marca” ); labLinea = new JLabel ( “Línea” ); labModelo = new JLabel ( “ Modelo” ); labValor = new JLabel ( “ Valor” ); txtMarca = new JTextField( ); txtLinea = new JTextField( ); txtModelo = new JTextField( ); txtValor = new JTextField( “$ 0” ); txtValor.SetEditable(false); txtValor.SetForeground(Color.BLUE); txtValor.SetBackground(Color.WHITE); add( labMarca ); add( txtMarca ); add( labLinea ); Agregar las etiquetas add( txtLinea ); add( labModelo ); y las zonas de texto add( txtModelo ); add( labValor ); al panel (add) add( txtValor );
  • 96. Selección de Opciones por medio de Cajas de Chequeo
  • 97. Cajas de chequeo • Permiten al usuario seleccionar o deseleccionar una opción. • Son objetos de la clase JCheckBox de Java • Algunos métodos de la clase JCheckBox: Indica (true/false) si el – isSelected ( ); usuario seleccionó la opción
  • 98. Cajas de chequeo • Permiten al usuario seleccionar o deseleccionar una opción. • Son objetos de la clase JCheckBox de Java • Algunos métodos de la clase JCheckBox: – isSelected ( ); Marca como seleccionado – setSelected ( true/false ); o no, la caja de chequeo
  • 99. Ejemplo en PanelDescuentos public class PanelDescuentos extends JPanel { … private JCheckBox cbPago; private JCheckBox cbSPublico; Declarar en el panel los private JCheckBox cbTCuenta; atributos de clase JCheckBox … }
  • 100. Ejemplo en PanelDescuentos public PanelDescuentos ( ) { … cbPago = new JCheckBox ( “Pronto pago” ); cbSPublico = new JCheckBox ( “Servicio público” ); cbTCuenta = new JCheckBox ( “Traslado de cuenta” ); … } Crear las cajas de chequeo (new) en el método constructor del panel
  • 101. Ejemplo en PanelDescuentos public PanelDescuentos ( ) { … cbPago = new JCheckBox ( “Pronto pago” ); cbSPublico = new JCheckBox ( “Servicio público” ); cbTCuenta = new JCheckBox ( “Traslado de cuenta” ); add( cbPago ); add( cbTCuenta ); add( cbSPublico ); Agregar las cajas de chequeo al panel … (add) }
  • 102. Interacción con la aplicación mediante Botones
  • 103. Botones • Permiten al usuario expresar sus órdenes al programa (es el mecanismo más simple de interacción). • Son objetos de la clase JButton de Java • La clase JButton tiene DOS METODOS especiales: – setActionCommand ( evento ); – addActionListener ( panel );
  • 104. Ejemplo en PanelResultados public class PanelResultados extends JPanel { … private JLabel labTotal; private JTextField txtTotal; private JButton butLimpiar; Declarar en el panel los private JButton butCalcular; … atributos de clase JButton }
  • 105. Ejemplo en PanelResultados public PanelResultados ( ) { … labTotal = new JLabel ( “Total a pagar” ); txtTotal = new JTextField ( “$ 0” ); butLimpiar = new JButton ( “Limpiar” ); butCalcular = new JButton ( “Calcular” ); Crear los botones … } (new) en el método constructor del panel
  • 106. Ejemplo en PanelResultados public PanelResultados ( ) { … labTotal = new JLabel ( “Total a pagar” ); txtTotal = new JTextField ( “$ 0” ); butLimpiar = new JButton ( “Limpiar” ); butCalcular = new JButton ( “Calcular” ); txtTotal.SetEditable( false ); txtTotal.SetForeground( Color.BLUE ); txtTotal.SetBackground( Color.WHITE ); add( new Jlabel( “”) ); add( new Jlabel( “”) ); Agregar los botones add(butLimpiar); add(labTotal); al panel (add) add(txtTotal); add(butCalcular); …
  • 107. Acciones del Usuario y Eventos de la aplicación
  • 108. Acciones y Eventos llamada a un método evento Interfaz usuario Modelo del mundo Usuario • El usuario ejecuta acciones: • Las acciones se convierten – Hace click sobre un botón en objetos llamados – Chequea una caja de eventos: chequeo – Describen lo que el usuario – Selecciona una opción de hizo un Menú – Se puede analizar su – … contenido para que el programa reaccione de acuerdo a la acción del usuario
  • 109. Cómo manejar un evento con un botón de la interfaz en 3 pasos … y no morir en el intento: Dar un nombre al evento y asociarlo a un botón public class PanelResultados extends JPanel En la clase del panel que { contiene el botón … public final static String LIMPIAR = “limpiar”; public final static String CALCULAR = “calcular”; public PanelResultados( ) { Se declaran constantes … para los nombres de los butLimpiar.SetActionCommand ( LIMPIAR ); eventos butCalcular.SetActionCommand ( CALCULAR ); … } … }
  • 110. Cómo manejar un evento con un botón de la interfaz en 3 pasos … y no morir en el intento: Dar un nombre al evento y asociarlo a un botón public class PanelResultados extends JPanel { … public final static String LIMPIAR = “limpiar”; public final static String CALCULAR = “calcular”; public PanelResultados( ) En el método constructor { del panel … butLimpiar.SetActionCommand ( LIMPIAR ); Se asocian los nombres butCalcular.SetActionCommand ( CALCULAR ); de los eventos con cada … botón } … }
  • 111. Cómo manejar un evento con un botón de la interfaz en 3 pasos … y no morir en el intento: Atender el evento public class PanelResultados extends JPanel implements ActionListener { … public void actionPerformed (ActionEvent evento ) { String comando = evento.getActionCommand( ); Agregar una declaración if ( (comando.equals( LIMPIAR) ) en el encabezado de la { clase del panel que // Reacción al evento de LIMPIAR contiene el botón (para } que pueda “percibir” las else if (comando.equals( CALCULAR ) ) acciones del usuario) // Reacción al evento de CALCULAR } }
  • 112. Cómo manejar un evento con un botón de la interfaz en 3 pasos … y no morir en el intento: Atender el evento public class PanelResultados extends JPanel implements ActionListener { Implementar en la clase … del panel que contiene el public void actionPerformed (ActionEvent evento ) botón, el método especial { actionPerformed String comando = evento.getActionCommand( ); if ( (comando.equals( LIMPIAR) ) { // Reacción al evento de LIMPIAR } parámetro del método: else if (comando.equals( CALCULAR ) ) evento ocurrido en el { panel // Reacción al evento de CALCULAR } }
  • 113. Cómo manejar un evento con un botón de la interfaz en 3 pasos … y no morir en el intento: Atender el evento public class PanelResultados extends JPanel implements ActionListener { Implementar en la clase … del panel que contiene el public void actionPerformed (ActionEvent evento ) botón, el método especial { actionPerformed String comando = evento.getActionCommand( ); if ( (comando.equals( LIMPIAR) ) { // Reacción al evento de LIMPIAR } parámetro del método: else if (comando.equals( CALCULAR ) ) evento ocurrido en el { panel // Reacción al evento de CALCULAR } }
  • 114. Cómo manejar un evento con un botón de la interfaz en 3 pasos … y no morir en el intento: Atender el evento public class PanelResultados extends JPanel implements ActionListener { … public void actionPerformed (ActionEvent evento ) { String comando = evento.getActionCommand( ); if ( (comando.equals( LIMPIAR) ) { // Reacción al evento de LIMPIAR } Métodos de la ventana else if (comando.equals( CALCULAR ) ) principal !!! { // Reacción al evento de CALCULAR } }
  • 115. Cómo manejar un evento con un botón de la interfaz en 3 pasos … y no morir en el intento: Atender el evento public class PanelResultados extends JPanel implements ActionListener { … public void actionPerformed (ActionEvent evento ) { Cada vez que el String comando = evento.getActionCommand( ); usuario hace click if ( (comando.equals( LIMPIAR) ) en un botón del { panel, se ejecuta el // Reacción al evento de LIMPIAR método } actionPerformed else if (comando.equals( CALCULAR ) ) { // Reacción al evento de CALCULAR } }
  • 116. Cómo manejar un evento con un botón de la interfaz en 3 pasos … y no morir en el intento: Decir que el panel es el encargado de atender el evento public class PanelResultados extends JPanel implements ActionListener { … Mediante el método public PanelResultados ( ) addActionListener de la { clase JButton butLimpiar.addActionListener (this); butCalcular.addActionListener (this); } … } parámetro del método: el objeto que lo está ejecutando, es decir el panel mismo
  • 117. Arquitectura y Distribución de Responsabilidades
  • 118. Qué vamos a aprender … • Coordinar los elementos de la interfaz y del modelo del mundo para satisfacer los requerimientos funcionales • Estructurar y repartir las responsabilidades • Una propuesta de arquitectura: – Facilita la localización de componentes del programa – Aumenta la claridad – Facilita el mantenimiento
  • 119. Por dónde comienza la ejecución del programa? • Por el método main de la ventana principal • Su función: crear una instancia de la ventana y hacerla visible en la pantalla public class InterfazImpuestosCarro extends JFrame { … public static void main( String[] args ) { InterfazImpuestosCarro vent = new InterfazImpuestosCarro( ); vent.setVisible( true ); } … }
  • 120. Quién crea el modelo del mundo? • La interfaz • En el método constructor de la ventana principal public class InterfazImpuestosCarro extends JFrame { … private CalculadorImpuestos calculador; public InterfazImpuestosCarro( ) throws Exception { calculador = new CalculadorImpuestos( ); … } … }
  • 121. Arquitectura propuesta • Los requerimientos funcionales se implementan en la ventana principal: – Hay UN método por REQUERIMIENTO – La ventana principal coordina todas las acciones
  • 122. Reacción a un evento generado por el usuario (1 de 6 pasos) El usuario genera un evento oprimiendo un botón en uno de los paneles de la interfaz
  • 123. Reacción a un evento generado por el usuario (2 de 6 pasos) public class PanelResultados extends JPanel implements ActionListener { … public void actionPerformed (ActionEvent evento ) { String comando = evento.getActionCommand( ); if ( (comando.equals( LIMPIAR) ) El panel reacciona { al evento con SU // Reacción al evento de LIMPIAR } método else if (comando.equals( CALCULAR ) ) actionPerformed { // Reacción al evento de CALCULAR } } …
  • 124. Reacción a un evento generado por el usuario (2 de 6 pasos) public class PanelResultados extends JPanel implements ActionListener { … public void actionPerformed (ActionEvent evento ) { String comando = evento.getActionCommand( ); if ( (comando.equals( LIMPIAR) ) { // Reacción al evento de LIMPIAR Llamado a métodos de la } ventana principal !!! else if (comando.equals( CALCULAR ) ) { // Reacción al evento de CALCULAR Hay UN método por } REQUERIMIENTO } …
  • 125. Reacción a un evento generado por el usuario (2 de 6 pasos) public class PanelResultados extends JPanel implements ActionListener { … public void actionPerformed (ActionEvent evento ) { String comando = evento.getActionCommand( ); if ( (comando.equals( LIMPIAR) ) { principal.limpiar( ); Método “limpiar” de la } ventana principal else if (comando.equals( CALCULAR ) ) { principal.calcularImpuestos( ); Método “calcularImpuestos” } de la ventana principal } …
  • 126. Reacción a un evento generado por el usuario (2 de 6 pasos) public class PanelResultados extends JPanel implements ActionListener { … public void actionPerformed (ActionEvent evento ) { String comando = evento.getActionCommand( ); if ( (comando.equals( LIMPIAR) ) { principal.limpiar( ); • Quién es “principal”? } else if (comando.equals( CALCULAR ) ) • Dónde está ? { • Quién lo conoce ? principal.calcularImpuestos( ); } } …
  • 127. principal principal • Quién es “principal”? R// Es el objeto que contiene la ventana principal • Dónde está ? R// Es un atributo (asociación) de las clases panelResultados y panelVehiculo • Quién lo conoce ?
  • 128. Entonces … public class PanelVehiculo extends JPanel implements ActionListener { … private InterfazImpuestosCarro principal; La clase del panel … contiene un atributo del tipo de la ventana public PanelVehiculo( InterfazImpuestosCarro v) principal { … principal = v; … } … }
  • 129. Entonces … public class PanelVehiculo extends JPanel implements ActionListener { … private InterfazImpuestosCarro principal; … public PanelVehiculo( InterfazImpuestosCarro v) { … principal = v; … El método constructor } del panel DEBE recibir … como parámetro, el } objeto correspondiente a la ventana principal
  • 130. Entonces … public class PanelVehiculo extends JPanel implements ActionListener { … private InterfazImpuestosCarro principal; … public PanelVehiculo( InterfazImpuestosCarro v) { … principal = v; … } … Se asigna el parámetro } al atributo
  • 131. Entonces … public class InterfazImpuestosCarro extends JFrame { private PanelVehiculo panelVehiculo; private PanelDescuentos panelDescuentos; private PanelResultados panelResultados; public InterfazImpuestosCarro( ) throws Exception En el método { constructor de la setLayout( new BorderLayout( ) ); ventana principal panelVehiculo = new PanelVehiculo( this ); add( panelVehiculo, BorderLayout.NORTH ); panelDescuentos = new PanelDescuentos( ); add( panelDescuentos, BorderLayout.CENTER ); panelResultados = new PanelResultados( this ); add( panelResultados, BorderLayout.SOUTH ); }
  • 132. Entonces … public class InterfazImpuestosCarro extends JFrame { private PanelVehiculo panelVehiculo; private PanelDescuentos panelDescuentos; private PanelResultados panelResultados; public InterfazImpuestosCarro( ) throws Exception { setLayout( new BorderLayout( ) ); panelVehiculo = new PanelVehiculo( this ); Cuando se crean los add( panelVehiculo, BorderLayout.NORTH ); paneles panelDescuentos = new PanelDescuentos( ); add( panelDescuentos, BorderLayout.CENTER ); panelResultados = new PanelResultados( this ); add( panelResultados, BorderLayout.SOUTH ); }
  • 133. Entonces … public class InterfazImpuestosCarro extends JFrame { private PanelVehiculo panelVehiculo; private PanelDescuentos panelDescuentos; private PanelResultados panelResultados; public InterfazImpuestosCarro( ) throws Exception { setLayout( new BorderLayout( ) ); panelVehiculo = new PanelVehiculo( this ); Se pasa como parámetro la add( panelVehiculo, BorderLayout.NORTH ); ventana principal (this) a los panelDescuentos = new PanelDescuentos( ); métodos constructores de los add( panelDescuentos, BorderLayout.CENTER ); paneles que la necesitan panelResultados = new PanelResultados( this ); add( panelResultados, BorderLayout.SOUTH ); }
  • 134. Entonces … public class InterfazImpuestosCarro extends JFrame { private PanelVehiculo panelVehiculo; private PanelDescuentos panelDescuentos; private PanelResultados panelResultados; public InterfazImpuestosCarro( ) throws Exception En el método { constructor de la setLayout( new BorderLayout( ) ); ventana principal panelVehiculo = new PanelVehiculo( this ); add( panelVehiculo, BorderLayout.NORTH ); Se agrega cada panelDescuentos = new PanelDescuentos( ); panel en una posición add( panelDescuentos, BorderLayout.CENTER ); de las definidas en el distribuidor gráfico panelResultados = new PanelResultados( this ); add( panelResultados, BorderLayout.SOUTH ); }
  • 135. Recordemos (1 de 6 pasos)… El usuario genera un evento oprimiendo un botón en uno de los paneles de la interfaz
  • 136. Recordemos (2 de 6 pasos)… public class PanelResultados extends JPanel implements ActionListener { … public void actionPerformed (ActionEvent evento ) { String comando = evento.getActionCommand( ); El panel reacciona al if ( (comando.equals( LIMPIAR) ) { evento con SU método principal.limpiar( ); actionPerformed dentro } del cual se analiza el else if (comando.equals( CALCULAR ) ) evento y se llama al { método correspondiente principal.calcularImpuestos( ); de la ventana principal } } …
  • 137. Reacción a un evento generado por el usuario (3 de 6 pasos) public void calcularImpuestos( ) El método de la ventana { principal: String unaMarca = panelVehiculo.darMarca( ); Completa la información String unaLinea = panelVehiculo.darLinea( ); necesaria, pidiéndola a los String unModelo = panelVehiculo.darModelo( ); demás paneles }
  • 138. Entonces … public class PanelVehiculo extends JPanel implements ActionListener { … public String darMarca( ) En la clase del panel { respectivo return txtMarca.getText( ); } Existen métodos para … pasar la información } a la ventana principal
  • 139. Volviendo al paso 3 de 6 public void calcularImpuestos( ) El método de la ventana { principal: String unaMarca = panelVehiculo.darMarca( ); Completa la información String unaLinea = panelVehiculo.darLinea( ); necesaria, pidiéndola a los String unModelo = panelVehiculo.darModelo( ); demás paneles }
  • 140. Volviendo al paso 3 de 6 public void calcularImpuestos( ) { String unaMarca = panelVehiculo.darMarca( ); String unaLinea = panelVehiculo.darLinea( ); String unModelo = panelVehiculo.darModelo( ); if( unaMarca.equals( "" ) || unaLinea.equals( "" ) || unModelo.equals( "" ) ) { JOptionPane.showMessageDialog( this, "Por favor llene todos los datos", "Cálculo de Impuestos", JOptionPane.ERROR_MESSAGE ); } else El método de la ventana { principal: …. } Completa la información necesaria, pidiéndola a los } demás paneles Verifica que la información esté completa y sea válida
  • 141. Volviendo al paso 3 de 6 public void calcularImpuestos( ) { String unaMarca = panelVehiculo.darMarca( ); String unaLinea = panelVehiculo.darLinea( ); String unModelo = panelVehiculo.darModelo( ); if( unaMarca.equals( "" ) || unaLinea.equals( "" ) || unModelo.equals( "" ) ) { JOptionPane.showMessageDialog( this, "Por favor llene todos los datos", "Cálculo de Impuestos", JOptionPane.ERROR_MESSAGE ); } else { …. En caso de problema, puede } cancelar la reacción y notificar al } usuario del problema
  • 142. Reacción a un evento generado por el usuario (4 de 6 pasos) public void calcularImpuestos( ) { … if( unaMarca.equals( "" ) || … { JOptionPane.showMessageDialog … El método de } la ventana else { principal: boolean descProntoPago = panelDescuentos.hayDescuentoProntoPago( ); Pide al boolean descServicioPublico = panelDescuentos.hayDescuentoServicioPublico( ); modelo del boolean descTrasladoCuenta = panelDescuentos.hayDescuentoTrasladoCuenta( ); mundo que try haga una { modificación double pago = calculador.calcularPago( unaMarca, unaLinea, unModelo, descProntoPago, o calcule un descServicioPublico, descTrasladoCuenta ); panelResultados.refrescarPago( pago ); valor } catch( Exception e ) { JOptionPane.showMessageDialog( this, e.getMessage( ), "Cálculo de Impuestos", JOptionPane.WARNING_MESSAGE ); } } }
  • 143. Entonces … La ventana principal DEBE conocer el mundo para poder llamar a sus métodos principal calculador principal
  • 144. Entonces … public class InterfazImpuestosCarro extends JFrame { /** Calculador de impuestos */ private CalculadorImpuestos calculador; La clase de la ventana principal contiene un …. atributo que es el objeto del mundo (de la clase principal del mundo) public InterfazImpuestosCarro( ) throws Exception { // Crea el calculador de impuestos calculador = new CalculadorImpuestos( ); // Configura la información de la ventana setTitle( "Cálculo impuestos" ); … } }
  • 145. Entonces … public class InterfazImpuestosCarro extends JFrame { /** Calculador de impuestos */ private CalculadorImpuestos calculador; …. public InterfazImpuestosCarro( ) throws Exception { // Crea el calculador de impuestos En el método constructor calculador = new CalculadorImpuestos( ); de la ventana principal, se crea el objeto del // Configura la información de la ventana mundo setTitle( "Cálculo impuestos" ); … } }
  • 146. Volviendo al paso 4 de 6 public void calcularImpuestos( ) { … if( unaMarca.equals( "" ) || … { JOptionPane.showMessageDialog … El método de } la ventana else { principal: boolean descProntoPago = panelDescuentos.hayDescuentoProntoPago( ); Pide al boolean descServicioPublico = panelDescuentos.hayDescuentoServicioPublico( ); modelo del boolean descTrasladoCuenta = panelDescuentos.hayDescuentoTrasladoCuenta( ); mundo que try haga una { modificación double pago = calculador.calcularPago( unaMarca, unaLinea, unModelo, descProntoPago, o calcule un descServicioPublico, descTrasladoCuenta ); panelResultados.refrescarPago( pago ); valor } catch( Exception e ) { JOptionPane.showMessageDialog( this, e.getMessage( ), "Cálculo de Impuestos", JOptionPane.WARNING_MESSAGE ); } } }
  • 147. Reacción a un evento generado por el usuario (5 de 6 pasos) public void calcularImpuestos( ) { El método de … la ventana if( unaMarca.equals( "" ) || … { principal: JOptionPane.showMessageDialog … Pide al } modelo del else mundo que { haga una boolean descProntoPago = panelDescuentos.hayDescuentoProntoPago( ); modificación boolean descServicioPublico = panelDescuentos.hayDescuentoServicioPublico( ); boolean descTrasladoCuenta = panelDescuentos.hayDescuentoTrasladoCuenta( ); o calcule un try valor { Si se pidió double pago = calculador.calcularPago( unaMarca, unaLinea, unModelo, descProntoPago, una descServicioPublico, descTrasladoCuenta ); modificación, panelResultados.refrescarPago( pago ); se llaman los } catch( Exception e ) métodos que { retornan los JOptionPane.showMessageDialog( this, e.getMessage( ), "Cálculo de Impuestos", nuevos JOptionPane.WARNING_MESSAGE ); valores que } se deben } desplegar }
  • 148. Reacción a un evento generado por el usuario (6 de 6 pasos) public void calcularImpuestos( ) { El método de … la ventana if( unaMarca.equals( "" ) || … { principal: JOptionPane.showMessageDialog … Pide a todos } los paneles else que tienen { información boolean descProntoPago = panelDescuentos.hayDescuentoProntoPago( ); que pudo boolean descServicioPublico = panelDescuentos.hayDescuentoServicioPublico( ); boolean descTrasladoCuenta = panelDescuentos.hayDescuentoTrasladoCuenta( ); haber try cambiado, { que actualicen double pago = calculador.calcularPago( unaMarca, unaLinea, unModelo, descProntoPago, sus valores descServicioPublico, descTrasladoCuenta ); (REFRESCO) panelResultados.refrescarPago( pago ); } catch( Exception e ) { JOptionPane.showMessageDialog( this, e.getMessage( ), "Cálculo de Impuestos", JOptionPane.WARNING_MESSAGE ); } } }
  • 149. Entonces … /** En la clase del panel * Cambia el valor desplegado del pago (Panelresultados) existe * @param pago - nuevo pago a desplegar */ el método refrescarPago public void refrescarPago( double pago ) { //Despliega el valor del vehiculo DecimalFormat df = ( DecimalFormat )NumberFormat.getInstance( ); df.applyPattern( "$ ###,###.##" ); txtTotal.setText( df.format( pago ) ); }
  • 150. Entonces … /** * Cambia el valor desplegado del pago Utiliza la clase * @param pago - nuevo pago a desplegar DecimalFormat de Java */ para dar un formato public void refrescarPago( double pago ) especial a un número { //Despliega el valor del vehiculo DecimalFormat df = ( DecimalFormat )NumberFormat.getInstance( ); df.applyPattern( "$ ###,###.##" ); txtTotal.setText( df.format( pago ) ); }
  • 151. Entonces … /** * Cambia el valor desplegado del pago * @param pago - nuevo pago a desplegar */ public void refrescarPago( double pago ) { //Despliega el valor del vehiculo DecimalFormat df = ( DecimalFormat )NumberFormat.getInstance( ); df.applyPattern( "$ ###,###.##" ); txtTotal.setText( df.format( pago ) ); } Pone el valor del pago en la zona de texto llamada txtTotal, en formato String
  • 153. Qué pasa con la información tecleada por el usuario en una zona de texto • La información SIEMPRE es recibida por la interfaz como cadena de caracteres • La interfaz tiene la responsabilidad de: Convertirla al tipo adecuado (ej: entero o minúsculas) Advertir al usuario si hay algún error, cuando el usuario teclea algo que no corresponde a lo esperado (ej: teclea una letra y se espera un número)
  • 154. Para convertir la cadena de caracteres al tipo adecuado … • A un número: – Se usa el método parseInt de la clase Integer de Java. – Se captura la excepción NumberFormatException que lanza el método parseInt si la cadena no se puede convertir en número try { int nCantidad = Integer.parseInt ( strCantidad ); } catch (NumberFormatException e) { // Mensaje al usuario }
  • 155. Para convertir la cadena de caracteres al tipo adecuado … • A mayúsculas/minúsculas (y otros tipos de conversión de cadenas de caracteres): – La clase String de Java provee métodos para transformar la cadena de caracteres tecledada por el usuario (y en general cualquier cadena de caracteres): • toLowerCase(): pasa a minúsculas • toUpperCase(): pasa a mayúsculas • Trim: elimina espacios en blanco al inicio y final de la cadena
  • 156. Mensajes al Usuario y Lectura Simple de Datos
  • 157. Mensajes en la Consola System.out.println(“Este en un mensaje de prueba de ERROR”); Si se ejecuta desde eclipse, el mensaje aparece en la ventana Console Si se ejecuta por fuera de eclipse (con run.bat)
  • 158. Mensajes en una ventana JOptionPane.showMessageDialog Debe ser null si se usa en el main JOptionPane.showMessageDialog( this, "Por favor llene todos los datos", "Calculo de Impuestos", JOptionPane.ERROR_MESSAGE ); JOptionPane.showMessageDialog( null, "La marca ferrari no está registrada", "Calculo de Impuestos", JOptionPane.WARNING_MESSAGE ); JOptionPane.showMessageDialog( this, "El valor total es de $12.000", "Calculo de Impuestos", JOptionPane.INFORMATION_MESSAGE );
  • 159. Para pedir información al usuario JOptionPane.showInputDialog Debe ser null si se usa en el main String clave = JOptionPane.showInputDialog( this, "Introduzca su clave"); if ( clave != null) { … } JOptionPane.showConfirmDialog int resp = JOptionPane.showConfirmDialog( null, "Está seguro que lo desea borrar?", "Confirmacion", JOptionPane.YES_NO_OPTION); if ( resp == JOptionPane.YES_OPTION) { ... }