Modelo Vista Controlador

Ampliación del Modelo Vista Controlador en Java y MySQL

15 octubre, 2015 2 comentarios

En este artículo ampliaremos el tutorial (enlace al tutorial) que muestra paso a paso cómo construir una aplicación en Java usando el patrón Modelo Vista Controlador (MVC) ya que ha habido varias consultas y peticiones al respecto.

La ampliación consiste en añadir la posibilidad de filtrar en la gestión de clientes.  De este modo, se permite buscar un cliente en concreto mediante su id, nombre o apellido.

Este artículo parte del ejemplo del tutorial Modelo Vista Controlador en Java y MySQL, nivel básico. A él vamos a añadirle la opción de búsqueda de modo que el resultado final será el mostrado en la siguiente imagen:

Filtrar clientes - MVC

Filtrar clientes – MVC

Para ello:

  1. En la Vista se realizará una modificación para contemplar el JLabel, JTextField y JButton.
  2. En el Controlador se añadirá la escucha del botón Buscar. Y se sobrecargará el método cargarTabla con un parámetro de entrada.
  3. En la base de datos se añadirá un nuevo procedimiento almacenado para realizar la búsqueda de un cliente.

Vista

Como se ha comentado en el anterior artículo, en este fichero se lleva a cabo el diseño de la ventana de nuestra aplicación.

Se definen tres nuevas propiedades:

  • JLabel para la etiqueta Buscar.
  • JTextField donde se introducirá el identificador, nombre o apellido a buscar.
  • JButton para realizar la búsqueda.

En el constructor se crean dichas propiedades y se añaden al contenedor siguiendo la misma filosofía empleada de SpringLayout.

Por último, en el método conectaControlador se añade actionListener y actionCommand al botón para que desencadene una acción en el controlador.

El nuevo código quedaría tal y como se muestra a continuación:

package kadumMVC;
public class View extends JFrame {
    private static final long serialVersionUID = 1L;
    //ETIQUETAS
    [...]
    private JLabel lblBuscar;
    
    //CUADROS DE TEXTO
    [...]
    protected JTextField txtBuscar;
    
    //BOTONES
    [...]
    protected JButton btnBuscar;
    [...]
    
    /**************** MÉTODOS ***************************/
    //CONSTRUCTOR
    View(){
    [...]
        //etiqueta buscar
        lblBuscar = new JLabel("Buscar:");
        contenedor.add(lblBuscar);
        sp.putConstraint(SpringLayout.NORTH, lblBuscar, 120, SpringLayout.NORTH, contenedor);
        sp.putConstraint(SpringLayout.WEST, lblBuscar,  10, SpringLayout.WEST, contenedor);
        /**************** EOF ETIQUETAS  ^^^^^^^^^^^^^^^^^^^^ **/
        
        
        /**************** BOF CUADROS DE  TEXTO vvvvvvvvvvvvvvvvvvvv **/
    [...]
        //cuadro de texto para buscar
        txtBuscar    = new JTextField();
        contenedor.add(txtBuscar);                    //añadir al contenedor
        sp.putConstraint(SpringLayout.NORTH, txtBuscar, 120, SpringLayout.NORTH, contenedor);
        sp.putConstraint(SpringLayout.WEST, txtBuscar, 100, SpringLayout.WEST, contenedor);
        sp.putConstraint(SpringLayout.EAST, txtBuscar, 300, SpringLayout.WEST, contenedor);
        /**************** EOF CUADROS DE  TEXTO ^^^^^^^^^^^^^^^^^^^^ **/
    [...]

        /**************** BOF BOTONES vvvvvvvvvvvvvvvvvvvv **/
    [...]
        //boton buscar
        btnBuscar        = new JButton("Buscar");
        contenedor.add(btnBuscar);
        sp.putConstraint(SpringLayout.SOUTH, btnBuscar, 140, SpringLayout.NORTH, contenedor);
        sp.putConstraint(SpringLayout.WEST, btnBuscar,  310, SpringLayout.WEST, contenedor);
        /**************** EOF BOTONES ^^^^^^^^^^^^^^^^^^^^ **/
        
        //Se hace visible la ventana
        setVisible(true);
    }
    
    public void conectaControlador(  Controller c  ){
    [...]
        btnBuscar.addActionListener(c);
        btnBuscar.setActionCommand("BUSCAR");
        
        tabla.addMouseListener(c);
        tabla.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);    //sólo se puede pulsar una fila
    }
}

Controlador

En el método actionPerformed, se tiene un switch para cada comando ejectuado (INSERTAR, BORRAR y MODIFICAR). El método concluye con una llamada a cargarTabla().

La idea que se lleva a cabo es añadir una nueva opción al switch para contemplar el comando BUSCAR.

Al final del método, si se pulsa sobre el botón buscar, en lugar de llamar al método cargarTabla(), sin parámetros, se llamará a ese método pero con un parámetro de entrada, de modo que se deberá sobrecargar cargarTabla(String buscar). El parámetro de entrada con el cual se llama será la información que se escriba en el JTextField.

El método sobrecargado se encargará de llamar al procedimiento almacenado filtrarCliente que se describe posteriormente.

El código resultante es:

package kadumMVC;

[...]

public class Controller implements ActionListener, MouseListener {
    @Override
    public void actionPerformed(ActionEvent arg0) {
[...]
        //Se almacena la informacion a buscar
        String buscar = "";
        
[...]
        switch (comando) {
            case "INSERTAR":
[...]
            break;
            
            case "BORRAR":
[...]
            break;

            case "MODIFICAR":
[...]
            case "BUSCAR":
                //Obtener el valor buscado
                buscar    = this.view.txtBuscar.getText();
            break;
            
            default:
                System.err.println("Comando no definido");
            break;
        }
        
        
        //limpiar el formulario
        limpia();
        
        //Se añade la condición para cargar la tabla
        if(comando!="BUSCAR"){    //Carga normal
            cargarTabla();
        }else{    //Cargar la tabla con criterio de búsqueda
            cargarTabla(buscar);
        }
    }

    //Método para limpiar los campos de la ventana
    private void limpia(){
        this.view.txtNombre.setText("");
        this.view.txtApellido.setText("");
        this.view.txtNIF.setText("");
        //Limpiamos el nuevo campo de texto
        this.view.txtBuscar.setText("");

    }
    
    //No se modifica nada
    protected void cargarTabla(){
[...]
    }

/* SOBRECARGA DEL MÉTODO PARA OBTENER SOLO LOS CLIENTES QUE CUMPLEN CON LA CONDICIÓN DE BÚSQUEDA */
protected void cargarTabla(String buscar){
        CallableStatement cs;
        ResultSet rs;
        Vector<Object> fila;
        
        for(int i=this.view.dtm.getRowCount(); i>0; i--){
            this.view.dtm.removeRow(i-1);
        }
        
        
        //Cargar datos en la tabla CON LOS CLIENTES BUSCADOS
        try {
            //Preparar la llamada
            cs    = Bd.getConexion().prepareCall("{CALL filtrarCliente(?)}");
            cs.setString(1, buscar);
            
            //Ejecutarla y recoger el resultado
            rs    = cs.executeQuery();
            //Recorrer el resultado
            while(rs.next()){
                //Añadir registro a registro en el vector
                fila    = new Vector<Object>();
                fila.add(rs.getInt("id"));
                fila.add(rs.getString("nombre"));
                fila.add(rs.getString("nif"));
                //Añadir el vector a la tabla de la clase View
                this.view.dtm.addRow(fila);
            }
            
            
        } catch (SQLException e) {
            System.err.println("Error al CARGAR DATOS");
        }
    }
[...]
    
}

Procedimiento almacenado

Cuando se pulsa el botón buscar, el controlador llama al procedimiento almacenado filtrarCliente. Este método debe devolver el id, nombre y NIF de los clientes que coincidan con el parámetro de búsqueda.

Recordamos que se deben devolver esos 3 campos porque son los que se muestran en nuestra tabla.

El procedimiento en nuestra base de datos MySQL será:

DELIMITER $$
DROP PROCEDURE IF EXISTS filtrarCliente$$
CREATE PROCEDURE filtrarCliente(buscar VARCHAR(50))
BEGIN
    SELECT id, nombre, nif
    FROM cliente
    WHERE cliente.id= buscar
    OR cliente.nombre LIKE CONCAT('%',buscar,'%')
    OR cliente.apellido LIKE CONCAT('%',buscar,'%');
    
END
$$

Donde se observa que recibe un parámetro de entrada que se utiliza en el WHERE de la condición para obtener los clientes cuyo id, nombre o apellido coincidan con dicho parámetro.

MVC Resultado

Tras realizar estas ampliaciones se podrán realizar búsquedas sobre los clientes almacenados. En la siguiente captura de pantalla se realiza la búsqueda del cliente con identificador igual a 2.

Buscar cliente por id

Buscar cliente por id

Tras pulsar el botón Buscar, se carga en la tabla los clientes que coinciden con la búsqueda.

Resultado de la búsqueda

Resultado de la búsqueda

Al pulsar sobre el cliente que nos interesa, se cargarán sus datos en los diferentes JTextField por lo que se podrá llevar a cabo su modificación o eliminación.

Seleccionar cliente buscado

Seleccionar cliente buscado

Espero que esta ampliación de la funcionalidad de la aplicación sirva para afianzar los conceptos explicados sobre modelo vista controlador y emplearla como base para mejorar vuestro modelo con más funcionalidades.

Volver al blog

Comentarios (2)

diego dijo:

holaa men, me gustaria saber en donde van las validaciones y ese tipo de cosas en el mvc, gracias por este buen aportee

    Laura dijo:

    Buenas, Diego:
    Te refieres a realizar la validación del tipo: que se rellenen los campos para el nombre y apellidos, que el DNI sea correcto o, si existiera un campo para el correo electrónico, que el mail esté en un formato adecuado, ¿verdad?
    Cuando se emplea el patrón Modelo Vista Controlador lo idóneo es realizar ese tipo de validaciones en el Controlador. Por lo tanto, en la clase Controller en el método actionPerformed se debería llevar a cabo las validaciones oportunas.
    Un saludo.

Leave a Reply to diego Cancelar