Aprende Java Aprende Php Aprende C++ Aprende HTML 5 Aprende JavaScript Aprende JSON Aprende MySQL Aprende SQLServer Aprende Visual Basic 6 Aprende PostgreSQL Aprende SQLite Aprende Redis Aprende Kotlin Aprende XML Aprende Linux VSC Aprende Wordpress Aprende Laravel Aprende VueJS Aprende JQuery Aprende Bootstrap Aprende Netbeans Aprende Android
Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube Sigueme en TikTok Sigueme en Whatsapp
Home / Ejercicios / Java / Java / Juegos / MVC / Proyectos / 3 en raya java con MVC y Netbeans

3 en raya java con MVC y Netbeans

Por jc mouse lunes, enero 9, 2012

Modelo Vista Controlador (MVC) es un patrón de arquitectura de software que separa los datos de una aplicación, la interfaz de usuario, y la lógica de negocio en tres componentes distintos. (Según Santa Wikpedia)

Arquitectura.

  • Modelo: Esta es la representación específica de la información con la cual el sistema opera. En resumen, el modelo se limita a lo relativo de la vista y su controlador facilitando las presentaciones visuales complejas. El sistema también puede operar con más datos no relativos a la presentación, haciendo uso integrado de otras lógicas de negocio y de datos afines con el sistema modelado.
  • Vista: Este presenta el modelo en un formato adecuado para interactuar, usualmente la interfaz de usuario.
  • Controlador: Este responde a eventos, usualmente acciones del usuario, e invoca peticiones al modelo y, probablemente, a la vista.

Basta de teoria y tratemos de implementar este en una aplicación GUI de Java con el IDE de netbeans, existen ejemplos sobre este patron y java en aplicación Web, pero encontre pocos y la mayoria en ingles sobre este modelo orientado a GUI, pero eso no quiere decir que no se pueda, Java cuenta con sus propias herramientas para implementar MVC, por ejemplo Observer y Observable, pero en esta ocasión nosotros no haremos uso de ellas.

El proyecto.

1. Creamos un nuevo proyecto en Netbeans siguiendo la estructura MVC, creamos un paquete para cada uno de ellos, una carpeta Controlador, otra Vista y una más para el Modelo.

2. Comenzando por la interfaz, creamos un JFrame con 9 botones, estos los ordenamos utilizando un GridLayout en una matriz 3×3, renombramos cada boton con el nombre «casilla1», «casilla2» y asi sucesivamente, ahora lo importante, Netbeans crea los objetos como PRIVATE, esto no nos sirve, entonces selecciona todos los botones y dirigete a sus propiedades, clic derecho PROPIEDADES, en la pestala CODIGO, busva la opción «Modificadores de Variable», entonces eliges la opcion PUBLIC y le das a aceptar. Si no sabes como hacer esto, fijate en el video que esta al final del post.

El nombre de la vista es «interfaz.java».

3. Crea una nueva clase en el paquete Modelo, llamalo «juego.java», es ahi donde colocamos la logica del juego 3 en Raya, el codigo es el siguiente:

package modelo;
/**
 * @web www.jc-mouse.net/
 * @author Mouse
 */
public class juego {

    private byte turno = 1;//1=>jugador 1 2=> jugador 2
    private String marca_X = "X";
    private String marca_O = "O";
    private boolean error=false;//por si se produce algun mensaje
    private byte ganador_es=0;//1=>jugador 1 2=> jugador 2 3=>Empate
    //matriz para almacenar los movimientos del juego
    private String tablero[][] ={{"","",""},
                                 {"","",""},
                                 {"","",""}
                                };

    public juego(){}

    //reinicia los valores y limpia el tablero
    public void Jugar_otra_vez()
    {
        for ( int i = 0 ; i < tablero.length ; i++ )
            for ( int j = 0 ; j < tablero.length ; j++)
                tablero[i][j]="";
        this.error=false;
        this.ganador_es=0;
        this.turno=1;

    }
    //dado una posicion y segun el turno que corresponda
    //coloca la marca "X" o "O" en el tablero
    //Salida: La marca que se coloco en la matriz
    public String set_movimiento(int posicion)
    {
        String out="";
        if(turno==1)
        {
            out = marcar(posicion , this.marca_X);
            //si no se pudo marcar => continua con su turno
            turno = 2;
            if ( gano(this.tablero, this.marca_X) )
                this.ganador_es=1;
            else if ( empate() )
                this.ganador_es=3;
        }
        else
        {
            out =  marcar(posicion , this.marca_O);
            turno = 1;
            if ( gano(this.tablero, this.marca_O) )
                this.ganador_es=2;
            else if ( empate() )
                this.ganador_es=3;
        }
        return out;
    }
    /* MARCA LA CASILLA CON EL MOVIMIENTO DEL JUGADOR, */
    private String marcar(int Posicion, String value)
    {
       String marca="";
       switch (Posicion)
       {
           case 1:marca = sub_marcar(0,0,value); break;
           case 2:marca = sub_marcar(0,1,value); break;
           case 3:marca = sub_marcar(0,2,value); break;
           case 4:marca = sub_marcar(1,0,value); break;
           case 5:marca = sub_marcar(1,1,value); break;
           case 6:marca = sub_marcar(1,2,value); break;
           case 7:marca = sub_marcar(2,0,value); break;
           case 8:marca = sub_marcar(2,1,value); break;
           case 9:marca = sub_marcar(2,2,value); break;
       }
       return marca;
    }

    //funcion privada que sigue a funcion marcar, esto para no repetir codigo
    //si al marcar en la matriz , existe algun error, coloca la bandera a TRUE
    private String sub_marcar(int x, int y, String value)
    {
        String marca="";
        this.error=false;
        if( this.tablero[x][y].equals("") ) //se puede marcar
        {
            this.tablero[x][y] = value;
            marca = value;
        }
        else//ya esta marcado
        {
            marca = this.tablero[x][y];
            this.error=true;//Error=>se trata de marcar casilla ya marcada
        }
        return marca;
    }

    public boolean get_error()
    {
        return this.error;
    }

    public String get_turno()
    {
        return (this.turno==1)? "Turno: X":"Turno: O";
    }

    public byte ganador()
    {
        return this.ganador_es;
    }

    //funcion que determina quien gano la partida
    public boolean gano( String matriz[][], String marca )
    {
        //busqueda de ganador por filas
        for ( int i = 0 ; i < matriz.length ; i++ )
        {
            byte count=0;
            for ( int j = 0 ; j < matriz.length ; j++)
                count+=( matriz[i][j].equals(marca) )?1:0;
            if( count == 3)
                 return true;
        }
        //busqueda de ganador por columnas
        for ( int j = 0 ; j < matriz.length ; j++ )
        {
            byte count=0;
            for ( int i = 0 ; i < matriz.length ; i++)
                count+=( matriz[i][j].equals(marca) )?1:0;
            if( count == 3)
                 return true;
        }
        //diagonales
        if(  matriz[0][0].equals(marca) && matriz[1][1].equals(marca) && matriz[2][2].equals(marca) )
            return true;

        if(  matriz[0][2].equals(marca) && matriz[1][1].equals(marca) && matriz[2][0].equals(marca) )
            return true;

        return false;
    }

    //Funcion que determina si se puede continuar jugando
    private boolean empate()
    {
        for ( int i = 0 ; i < tablero.length ; i++ )
           for ( int j = 0 ; j < tablero.length ; j++)
                if( tablero[i][j].equals(""))
                    return false;
        return true;
    }

}

Como ves, es un juego sencillo y no necesitamos de otras clases ni de base de datos, aunque si asi fuera, las demas clases y la persistena se colocan en esta carpeta.

4. Toca el turno del Controlador, crea una clase en este paquete y llamalo «controlador.java» (que original no), esta clase nos permite la interacción entre la Vista y el Modelo, aunque en ocasiones la vista puede recuperar datos del modelo directamente o viceversa, eso ya depende del programador. El codigo es el siguiente:

package controlador;
import modelo.juego;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import vista.interfaz;
/**
 * @web www.jc-mouse.net/
 * @author Mouse
 */
public class controlador implements ActionListener {

    private interfaz vista;
    private juego juego;
    private String titulo = "3 en Raya MVC * jc-mouse.net ";

     //En el constructor inicializamos nuestros objetos 
    public controlador( interfaz vista , juego modelo){
        this.vista = vista;
        this.juego = modelo;
    }

    //Inicia los valores del jFrame VISTA con los datos del MODELO
    // tambien añadimos el ActionListener a los botones de la VISTA
    public void iniciar_vista(){
        vista.setTitle( this.titulo );
        vista.setLocationRelativeTo(null);
        this.vista.casilla1.addActionListener(this);
        this.vista.casilla2.addActionListener(this);
        this.vista.casilla3.addActionListener(this);
        this.vista.casilla4.addActionListener(this);
        this.vista.casilla5.addActionListener(this);
        this.vista.casilla6.addActionListener(this);
        this.vista.casilla7.addActionListener(this);
        this.vista.casilla8.addActionListener(this);
        this.vista.casilla9.addActionListener(this);
    }

    //La accion de los botones de la VISTA es capturado, asi como los valores
    //dependiendo del boton pulsado, se envia la informacion al modelo
    //y se espera la respuesta
    public void actionPerformed(ActionEvent e) {
        Object boton = e.getSource();

        if( this.juego.ganador()== 0 )
        {
        if( boton == this.vista.casilla1 )
            this.vista.casilla1.setText( this.juego.set_movimiento(1) );
        else if(boton == this.vista.casilla2)
            this.vista.casilla2.setText( this.juego.set_movimiento(2) );
        else if(boton == this.vista.casilla3)
            this.vista.casilla3.setText( this.juego.set_movimiento(3) );
        else if(boton == this.vista.casilla4)
            this.vista.casilla4.setText( this.juego.set_movimiento(4) );
        else if(boton == this.vista.casilla5)
            this.vista.casilla5.setText( this.juego.set_movimiento(5) );
        else if(boton == this.vista.casilla6)
            this.vista.casilla6.setText( this.juego.set_movimiento(6) );
        else if(boton == this.vista.casilla7)
            this.vista.casilla7.setText( this.juego.set_movimiento(7) );
        else if(boton == this.vista.casilla8)
            this.vista.casilla8.setText( this.juego.set_movimiento(8) );
        else if(boton == this.vista.casilla9)
            this.vista.casilla9.setText( this.juego.set_movimiento(9) );
        if( this.juego.get_error())
            JOptionPane.showMessageDialog(null, "Error: la casilla ya esta marcada \n Perdiste tu turno");            

        this.vista.setTitle( this.titulo + this.juego.get_turno());

        }

        if( this.juego.ganador()== 1 )
            mensaje(" 'X' ");
        else if( this.juego.ganador()== 2 )
            mensaje(" 'O' ");
        else if( this.juego.ganador()== 3 )
            mensaje(" 'Es un empate' ");
    }

    //dependiendo de la respuesta del modelo, se muestra un mensaje al usuario
    private void mensaje(String s)
    {
           int seleccion = JOptionPane.showOptionDialog(null,"Gano el jugador " + s + "\n ¿Que desea hacer?", "Fin del juego",
                        JOptionPane.YES_NO_CANCEL_OPTION,
                        JOptionPane.QUESTION_MESSAGE,
                        null,    // null para icono por defecto.
                       new Object[] { " Jugar otra vez ", " Salir de Programa " },
                       "Jugar otra vez");

            if (seleccion != -1)
                if( (seleccion+1)==1 )
                {
                    this.juego.Jugar_otra_vez();
                    this.vista.setTitle(titulo);
                    this.vista.casilla1.setText( "" );
                    this.vista.casilla2.setText( "" );
                    this.vista.casilla3.setText( "" );
                    this.vista.casilla4.setText( "" );
                    this.vista.casilla5.setText( "" );
                    this.vista.casilla6.setText( "" );
                    this.vista.casilla7.setText( "" );
                    this.vista.casilla8.setText( "" );
                    this.vista.casilla9.setText( "" );
                }
                else
                    System.exit(0);
    }
}

5. muy bien, ya vamos terminando, fijate que no escribimos nada de codigo en la clase interfaz 😉

Para terminar debemos escribir un poco de codigo en la clase MAIN, el código es:

package mvc3nraya;

import vista.interfaz;
import controlador.controlador;
import modelo.juego;
/**
 * @web www.jc-mouse.net/
 * @author Mouse
 */
public class Main {

    public static void main(String[] args) {
         //nuevas instancias de clase
        juego modelo = new juego();
        interfaz vista = new interfaz();
        controlador controlador = new controlador( vista , modelo );
        controlador.iniciar_vista();
        vista.setVisible(true);
    }
}

En la clase Main, lo que hacemos es crear instancias de nuestros objetos pasando la Vista y el Modelo al Controlador, y despues lanzamos la interfaz al usuario y … eso es todo. Ejecuta el juego y revisa que todo este bien.

El código del proyecto esta AQUI

Tags

Artículos similares

JCPanel 3.0

Nueva versión de un viejo proyecto swing «JCMousePanel» que nos permitía agregar imágenes en los contenedores JPanel. En[...]

Instalación de Netbeans en Ubuntu

Netbeans es uno de los entornos de desarrollo integrado (Integrated Development Environment – IDE)  más conocidos[...]

Lo nuevo de HTTP Client

Una de las novedades de Java 9 y 10 aunque por el momento en modo de prueba (jdk.incubator.http) es el Cliente HTTP el c[...]

JASYPT : Cifrado simplificado Java

Jasypt es una biblioteca java que permite agregar capacidades básicas de encriptación a proyectos con el mínimo esfuerzo[...]

JCheckBox dentro JTable con Netbeans

Para colocar un JCheckBox dentro una celda de un JTable debemos sobre escribir algunas clases para que el componente pue[...]

Crea un reproductor de video con VLCJ y Java

VLC Media Player es un reproductor multimedia de código abierto muy popular desarrollado por el proyecto VideoLAN. VLCJ[...]