construcción de la interfaz gráfica

Nychol Bazurto Gómez

Interfaz gráfica

 

Nivel

5

Distribuciones

Creación de la interfaz

Manejo de eventos

VEREMOS lo siguiente

  • 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

POR QUé es importante la interfaz

POR QUé es importante la interfaz

medio de comunicación entre el usuario y el modelo del mundo

Ejecuta operaciones sobre el modelo del mundo.

 

Ve el resultado de sus acciones.

Interfaz de usuario ideal

Usuario siente que está visualizando e interactuando directamente con los elementos del modelo del mundo

Un proceso sencillo y natural

Esperamos que sea  agradable y fácil de utilizar

Agradable y fácil de utilizar

Condiciones mínimas que influyen en la percepción

  • Combinación de colores
  • Organización de los elementos en las ventanas
  • Los gráficos
  • Los tipos de letra

Los elementos de interacción se comporten de forma intuitiva.





Cantidad de conocimiento que el usuario debe tener para utilizar el programa.

DIseño de la interfaz

Diseño funcional y gráfico

Arquitectura

  • Colores
  • Distribución de elementos gráficos (menús, botones, …)
  • Estructura clara
  • Fácil de mantener

Asignación de responsabilidades

Cómo estructurar la interfaz de usuario y cómo comunicarla con las clases del modelo del mundo, sin mezclar en ningún momento las responsabilidades de esos dos componentes de un programa.

Interfaz gráfica

Interfaz gráfica

Etiquetas

Botones

Campos de texto

Caja de chequeo

Imágenes

Interfaz gráfica

Etiquetas

  • Sirven para mostrar información estática (que no cambia)
  • En Java se llama JLabel

Interfaz gráfica

Botónes

  • Sirven para crear (generar) eventos que modifican el estado de la aplicación
  • En Java se llaman JButton

Interfaz gráfica

Campos de texto

  • Muestra información dinámica (que varía)
  • Permite ingresar información al usuario.
  • En Java se llaman JTextField.

Interfaz gráfica

Caja de chequeo

  • Permite seleccionar elementos de una lista
  • Permite mostrar una condición booleana.
  • En Java se llama JCheckBox

Interfaz gráfica

Imágenes

  • No son elementos gráficos propios, remplazan el texto de etiquetas  y/o botones por la ruta de la imagen.
  • En Java son ImageIcon.

Interfaz gráfica

  • Para declarar los componentes como atributos:
  • Etiquetas (JLabel):
    • private JLabel <nombreComienzaPor:lbl>;
  • Botones (JButton):
    • private JButton <nombreComienzaPor:btn>;
  • Campos de texto (JTextField)
    • private JTextField <nombreComienzaPor:txt>;
  • Caja de chequeo (JCheckBox):
    • private JCheckBox <nombreComienzaPor:cb>;

    

Interfaz gráfica

  • Cuando los declaren en su ejercicio les aparecerán de la siguiente forma:

    

Interfaz gráfica

  • Para solucionar el problema deben “importar”  cada uno de los componentes haciendo click izquierdo sobre  el signo de alerta  al igual que hicieron  con ArrayList.
  • Después del click izquierdo seleccionar la opción Import para cada componente:

Interfaz gráfica

  • Para inicializar los componentes, dentro del constructor de la clase que los contiene:
  • Etiquetas (JLabel):
    • nombreEtiqueta = new JLabel (“Texto de la etiqueta”);
  • Botones (JButton):
    • nombreBoton = new JButton (“Texto del bótón”);​                                   
  • Campos de texto (JTextField)
    • nombreCampoTexto = new JTextField (“Texto campo”);
  • Caja de chequeo (JCheckBox):
    • nombreCajaChequeo = new JCheckBox (“Texto caja”);

 

Ventana principal

Ventana principal

 

  • Contiene TODOS los elementos de visualización e interacción
  • UNICA FUNCION: Servir como marco para los demás elementos de la interfaz (AGRUPA)

 

  • Es un contenedor gráfico

Ventana principal

Controles para cerrar el programa

Título

Ventana principal

La ventana principal será un objeto de la clase InterfazEmpleado

Ventana principal

La ventana principal será un objeto de la clase InterfazEmpleado

Clase interfazempleado

Como cualquier clase:

  • Está declarada en su propio archivo: InterfazEmpleado.java
  • Sigue las mismas reglas que cualquier clase del mundo​​.

​​Diferencia:

  • Está declarada en otro paquete: uniandes.cupi2.empleado.interfaz (ver en Eclipse).

Clase interfazempleado

package uniandes.cupi2.empleado.interfaz;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;

import uniandes.cupi2.empleado.mundo.Empleado;
import uniandes.cupi2.empleado.mundo.Fecha;

/**
 * Ventana principal de la aplicación.
 */
public class InterfazEmpleado extends JFrame
{
}

Se importan las clases del modelo del mundo

Se agrega extends JFrame para indicar que es una ventana

Clase interfazempleado

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

Con los métodos de la clase JFrame  que nos permiten

  • Cambiar el título de la ventana
  • Cambiar el tamaño de la ventana
  • Agregar componentes gráficos

Métodos del frame

 

  • setSize ( ancho, alto )
  • setResizable ( true/false )
  • setTitle ( titulo )
  • setDefaultCloseOperation (EXIT_ON_CLOSE)
  • setVisible ( true/false )
  • setLayout( layout )
  • add ( componente )

DISTRIBUCIONES

DISTRIBUCIONES

  • Permiten darle un orden a la interfaz gráfica y determinar en qué posición se ubica cada uno de sus componentes.
  • Partimos de que las aplicaciones tienen una ventana principal (JFrame)

DISTRIBUCIONES

Al tener la interfaz principal (ventana principal), debemos dividirla en páneles (que en Java son JPanel) según alguna de las siguientes dos distribuciones (Layout):

BorderLayout: distribución de bordes geográficos (norte, sur, este, oeste y centro).

GridLayout: distribución de cuadrícula en la que cada casilla tiene la misma dimensión, se debe especificar la cantidad de filas y columnas de la cuadrícula.

DISTRIBUCIONES

Al tener la interfaz principal (ventana principal), debemos dividirla en páneles (que en Java son JPanel) según alguna de las siguientes dos distribuciones (Layout):

BorderLayout

GridLayout

add( panelVehiculo, BorderLayout.NORTH );

Objeto que se va a adicionar

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

Al agregar un componente a la ventana, NO SE DEBE especificar la posición. Esta es asignada en el orden de llegada (fila 1, fila 2, …)

setLayout( new GridLayout ( 4, 3 ) );
add( panelVehiculo);

 

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

DISTRIBUCIONES

¿Para el museo cuál es la distribución?

DISTRIBUCIONES

Norte

centro

sur

este

DISTRIBUCIONES

A su vez cada pánel tiene su distribución

 

 

 

 

 

 

El panel ubicado en el Norte de interfaz principal, su distribución puede ser BorderLayout (con una imagen en el centro ó GridLayout (con tamaño 1x1).

DISTRIBUCIONES

A su vez cada pánel tiene su distribución

 

 

 

Panel ubicado en Sur de interfaz principal, su distribución es GridLayout, con tamaño 1x3 (1 fila y 3 columnas).

Panel ubicado en Este de Interfaz principal, su distribución es GridLayout, con tamaño 6x1 (6 filas y 1 columna).

DISTRIBUCIONES

A su vez cada pánel tiene su distribución

 

 

Panel ubicado en Centro de Interfaz principal, su distribución es BoderLayout, con tamaño 3 sub-páneles.

centro

oeste

sur

DISTRIBUCIONES

A su vez cada pánel tiene su distribución

 

 

centro

sur

  • El sub-panel Oeste puede tener distribución BorderLayout con la imagen en el Centro, ó GridLayout de tamaño 1x1.

oeste

DISTRIBUCIONES

A su vez cada pánel tiene su distribución

 

 

centro

  • El sub-panel Sur tiene distribución GridLayout, con tamaño 1x4 (1 fila y columnas).

oeste

DISTRIBUCIONES

A su vez cada pánel tiene su distribución

 

 

  • El sub-panel Centro tiene distribución GridLayout, con tamaño 5x2 (5 filas y 2 columnas). Se puede decir que el tamaño es 6x2 si se cuenta los espacios vacíos debajo de “está en remate”.

sur

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
    • PanelInformacion
    • PanelOpciones
    • PanelCalificacion

clase interfazmuseo

/**
 * Ventana principal de la aplicación.
 */
public class InterfazMuseo extends JFrame
{
    // -----------------------------------------------------------------
    // Atributos
    // -----------------------------------------------------------------

    /**
     * Clase principal del mundo.
     */
    private Museo museo;

    // -----------------------------------------------------------------
    // Atributos de la interfaz
    // -----------------------------------------------------------------

    /**
     * Panel con la imagen del banner.
     */
    private PanelImagen panelImagen;

    /**
     * Panel con la información de la obra.
     */
    private PanelInformacion panelInformacion;

    /**
     * Panel para calificar la obra.
     */
    private PanelCalificacion panelCalificacion;


    /**
     * Panel para ejecutar las extensiones a la aplicación.
     */
    private PanelOpciones panelOpciones;

clase interfazmuseo

public InterfazMuseo( )
{
setLayout( new BorderLayout( ) );

panelInformacion = new PanelInformacion( this );
add( panelInformacion, BorderLayout.CENTER );

panelCalificacion = new panelCalificacion( );
add( panelOpciones, BorderLayout.EAST );

panelOpciones = new panelOpciones( this );
add( panelOpciones, BorderLayout.SOUTH );
}

Atributo panelInformacion de la clase InterfazMuseo

Llamado al constructor de la clase PanelInformacion

clase interfazmuseo

public InterfazMuseo( )
{
setLayout( new BorderLayout( ) );

panelInformacion = new PanelInformacion( this );
add( panelInformacion, BorderLayout.CENTER );

panelCalificacion = new panelCalificacion( );
add( panelOpciones, BorderLayout.EAST );

panelOpciones = new panelOpciones( this );
add( panelOpciones, BorderLayout.SOUTH );
}

Parámetro que requiere el constructor.

CONCEPTO NUEVO!

Es una variable de JAVA

Hace referencia al objeto que está ejecutando un método

Es la ventana principal, (objeto de la clase InterfazMuseo, que es el “padre” del panel)

CREación de la interfaz

Creación de la interfaz

  • Para el Museo, definimos la distribución BorderLayout para la ventana principal (interfaz principal) de la aplicación.
  • En Eclipse deben crear 5 clases: 1 para la interfaz principal y una para cada panel (los sub-paneles del panel centro no necesitan clases a parte).
  • La primera clase en ser creada debe ser la Interfaz principal, por convención el nombre debe ser Interfaz+Nombreaplicacion, por ejemplo, para el Museo se llamará InterfazMuseo.
  • Al crearla debe aparecer algo como lo siguiente:

Creación de la interfaz

  • Dado que estamos hablando de la ventana principal, la clase InterfazMuseo DEBE extender JFrame (no olvidar importar JFrame)

Creación de la interfaz

  • A continuación se crea 1 clase por cada panel, por convención el nombre de cada panel debe ser Panel+información que contiene por ejemplo para este caso:
  • Norte: PanelImagen
  • Centro: PanelInfoObra
  • Este: PanelCalificaciones
  • Sur: PanelOpciones

Creación de la interfaz

  • Cada una de las clases creadas para los páneles DEBE extender JPanel (no olvidar importar):

Creación de la interfaz

  • Luego se procede, dentro del constructor de InterfazMuseo, a crear y agregar los paneles como se definió anteriormente, los páneles que tienen botones, necesitan como parámetro la InterfazMuseo, para poder ejecutar sus acciones, por lo que se utiliza el parámetro this (que hace referencia a la clase actual, en este caso InterfazMuseo).
  • Los errores que marcan en rojo se resolverán en el paso siguiente cuando definamos los constructores de cada pánel.

Creación de la interfaz

  • Para los páneles que no tienen botones, se define un constructor sin parámetros. (PanelImagen)
  • Para los páneles que tienen botones se define un atributo de tipo InterfazMuseo y un constructor con un parámetro de tipo InterfazMuseo.

Creación de la interfaz

  • Al guardar los cambios en los páneles (Ctrl+Shift+S) se solucionarán los problemas en el constructor de InterfazMuseo.

Creación de la interfaz

  • En la clase InterfazMuseo se debe crear un método que Eclipse (y Java) necesita para poder ejecutar el proyecto como una aplicación. Este método se llama “main” y siempre es:
  • public static void main (String [] pArgs)

Adentro del método se crea una nueva InterfazMuseo y se vuelve visible.

Creación de la interfaz

  • Al ejecutar, la aplicación debe lucir asi:

Creación de la interfaz

  • Métodos para usar dentro de los páneles:
    • setSize(ancho, alto);  aunque con el BorderLayout y GridLayout ocupan todo el espacio que pueden.
    • setLayout (Layout);
    • setBorder (Border); para darle un borde al pánel, para los ejercicios de Nivel 5 se utilizan borders con título que en Java se llaman TitledBorder.
      • setBorder( new TitledBorder(“Titulo”));

Creación de la interfaz

  • Para el museo al definir el borde de cada pánel, dentro del constructor de cada pánel se tendrá:
  • PanelOpciones:
  • PanelInfoObra:
  • PanelCalificaciones:

Creación de la interfaz

  • Al poner bordes como fueron definidos anteriormente la interfaz queda asi:
  • El PanelCalificaciones ocupará espacio cuando se le agreguen componentes.

Creación de la interfaz

Para mostrar ventanas de mensajes al usuario, se utiliza la clase JOptionPane y dos métodos

 

  • showMessageDialog: para mostrar mensaje con información (usualmente mensaje de error).
  • showInputDialog: para pedirle al usuario que ingrese algún valor (texto o números).

 

En el manejo de eventos se explicará como utilizar cada uno de estos métodos.

Manejo de eventos

usuario

interfaz usuario

modelo del mundo

evento

llamada a un método

El usuario ejecuta acciones:

  • Hace click sobre un botón
  • Chequea una caja de chequeo
  • Selecciona una opción de un Menú

Las acciones se convierten en objetos llamados eventos:

  • Describen lo que el usuario hizo
  • Se puede analizar su contenido para que el programa reaccione de acuerdo a la acción del usuario.

Hay tres pasos que se deben seguir para decidir la manera de manejar un evento con un botón de la interfaz

Decidir el nombre del evento y asociarlo con un botón.

Implementar el método que va a atender el evento

Declarar que el panel es el responsable de atender los eventos de sus botones.

1

2

3

Decidir el nombre del evento y asociarlo con un botón.

1

public class PanelConsultas extends JPanel implements ActionListener
{

    // -----------------------------------------------------------------
    // Constantes
    // -----------------------------------------------------------------

    /**
     * Constante para calcular la edad del empleado.
     */
    private final static String CALCULAR_EDAD = "CALCULAR EDAD";

    /**
     * Constante para calcular la antigüedad del empleado.
     */
    private final static String CALCULAR_ANTIGUEDAD = "CALCULAR ANTIGUEDAD";

...

 public PanelConsultas( InterfazEmpleado pPrincipal )
    {
       ...

        btnEdad = new JButton( );
        btnEdad.setText( "Calcular edad" );
        btnEdad.setActionCommand( PanelConsultas.CALCULAR_EDAD );
   

        btnAntiguedad = new JButton( );
        btnAntiguedad.setText( "Calcular antigüedad" );
        btnAntiguedad.setActionCommand( PanelConsultas.CALCULAR_ANTIGUEDAD );
     }    

}

En la clase del panel que contiene el botón

Se declaran constantes para los nombres de los eventos

 

En el método constructor del panel

Se asocian los nombres de los eventos con cada botón

Atender el evento

2

public class PanelConsultas extends JPanel implements ActionListener
{    

...

     /**
     * Manejo de los eventos de los botones.
     * @param pEvento Acción que generó el evento. pEvento != null.
     */
    public void actionPerformed( ActionEvent pEvento )
    {
        String command = pEvento.getActionCommand( );

        if( command.equals( CALCULAR_EDAD ) )
        {
            principal.calcularEdadEmpleado( );
        }
        else if( command.equals( CALCULAR_ANTIGUEDAD ) )
        {
            principal.calcularAntiguedadEmpleado( );
        }
        else if( command.equals( CALCULAR_PRESTACIONES ) )
        {
            principal.calcularPrestacionesEmpleado( );
        }
    }
}

Agregar una declaración en el encabezado de la clase del panel que contiene el botón (para que pueda “percibir” las acciones del usuario)

Atender el evento

2

public class PanelConsultas extends JPanel implements ActionListener
{    

...

     /**
     * Manejo de los eventos de los botones.
     * @param pEvento Acción que generó el evento. pEvento != null.
     */
    public void actionPerformed( ActionEvent pEvento )
    {
        String command = pEvento.getActionCommand( );

        if( command.equals( CALCULAR_EDAD ) )
        {
            principal.calcularEdadEmpleado( );
        }
        else if( command.equals( CALCULAR_ANTIGUEDAD ) )
        {
            principal.calcularAntiguedadEmpleado( );
        }
        else if( command.equals( CALCULAR_PRESTACIONES ) )
        {
            principal.calcularPrestacionesEmpleado( );
        }
    }
}

Implementar en la clase del panel que contiene el botón, el método especial actionPerformed

Atender el evento

2

public class PanelConsultas extends JPanel implements ActionListener
{    

...

     /**
     * Manejo de los eventos de los botones.
     * @param pEvento Acción que generó el evento. pEvento != null.
     */
    public void actionPerformed( ActionEvent pEvento )
    {
        String command = pEvento.getActionCommand( );

        if( command.equals( CALCULAR_EDAD ) )
        {
            principal.calcularEdadEmpleado( );
        }
        else if( command.equals( CALCULAR_ANTIGUEDAD ) )
        {
            principal.calcularAntiguedadEmpleado( );
        }
        else if( command.equals( CALCULAR_PRESTACIONES ) )
        {
            principal.calcularPrestacionesEmpleado( );
        }
    }
}

parámetro del método: evento ocurrido en el panel

Atender el evento

2

public class PanelConsultas extends JPanel implements ActionListener
{    

...

     /**
     * Manejo de los eventos de los botones.
     * @param pEvento Acción que generó el evento. pEvento != null.
     */
    public void actionPerformed( ActionEvent pEvento )
    {
        String command = pEvento.getActionCommand( );

        if( command.equals( CALCULAR_EDAD ) )
        {
            principal.calcularEdadEmpleado( );
        }
        else if( command.equals( CALCULAR_ANTIGUEDAD ) )
        {
            principal.calcularAntiguedadEmpleado( );
        }
        else if( command.equals( CALCULAR_PRESTACIONES ) )
        {
            principal.calcularPrestacionesEmpleado( );
        }
    }
}

Se analiza cuál fue el evento que ocurrió

 

Se llaman métodos de la ventana principal

Cada vez que el usuario hace click en un botón del panel, se ejecuta el método actionPerformed

Decir que el panel es el encargado de atender el evento

3

Mediante el método addActionListener de la clase JButton. Se le pasa como parámetro del método el objeto que lo está ejecutando, es decir el panel mismo

 public PanelConsultas( InterfazEmpleado pPrincipal )
    {
        ...

        btnEdad = new JButton( );
        btnEdad.setText( "Calcular edad" );
        btnEdad.setActionCommand( PanelConsultas.CALCULAR_EDAD );
        btnEdad.addActionListener( this );

        btnAntiguedad = new JButton( );
        btnAntiguedad.setText( "Calcular antigüedad" );
        btnAntiguedad.setActionCommand( PanelConsultas.CALCULAR_ANTIGUEDAD );
        btnAntiguedad.addActionListener( this );

        btnPrestaciones = new JButton( );
        btnPrestaciones.setText( "Calcular prestaciones" );
        btnPrestaciones.setActionCommand( PanelConsultas.CALCULAR_PRESTACIONES );
        btnPrestaciones.addActionListener( this );

      }

Arquitectura y distribución de responsabilidades

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 static void main( String[] args ) {

                InterfazEmpleado interfaz = new InterfazEmpleado( );
                interfaz.setVisible( true );
            }

Quién crea el modelo del mundo?

  • La interfaz

  • En el método constructor de la ventana principal

public InterfazEmpleado( )
    {

        setTitle( "Sistema de un empleado" );
        setSize( 600, 580 );
        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        // Construir el empleado

        empleado = new Empleado( );
...
}

Arquitectura propuesta

 

Los requerimientos funcionales se implementan en la ventana principal:

 

  • Hay UN método por REQUERIMIENTO
  • La ventana principal coordina todas las acciones

Arquitectura propuesta

  1. El usuario realiza una acción.
  2. El panel reacciona a su evento con el ActionPerformed: Llama un método de la ventana principal. Cada requerimiento tiene su método.
  3. El método de la ventana principal completa la información: La saca de otros páneles y verifica que la información esté completa y válida.
  4. El método pide al modelo del mundo que haga una modificación o calcule un valor.
  5. Si se pidió una modificación, se llaman los métodos que retornan los nuevos valores que se deben desplegar

  6. Pide a todos los paneles que tienen información que pudo haber cambiado, que actualicen sus valores (REFRESCO)

     

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
  •  

PRACTIQUEMOS

  • ¿PREGUNTAS?

  • ¿PREGUNTAS?

  • Text
  • GRACIAS

  • J. Villalobos and R. Casallas, Fundamentos de Programación. https://cupi2.virtual.uniandes.edu.co/libro-del-curso-pdf/libro-completo
  •  
  • Icons made by wanicon from Flaticonis licensed by Creative Commons BY 3.0

Nivel5

By nychi713

Nivel5

  • 623