lunes, 23 de mayo de 2016

Fondo a JFRAME Java

Simplemente puedo decir ¡que complicado!, yo siempre he dicho a mis alumnos que todo es posible desde un lenguaje de programación en este caso JAVA. Pero poner fondo a un jFrame resulto algo que no era tan simple. Muchos de los códigos en internet no están lo suficientemente descritos y provocan algunos problemas de uso, he robado ideas de algunos y el resultado lo comparto a continuación.

Para dar solución a esta situación fue necesario crear una clase que hereda de jPanel para la sobreescritura de su método de PAINT. Se ha creado para eso un archivo por separado "MiPanel.java" (link de descarga) que debe colocarse junto al programa que lo va a utilizar.



Es importante modificar la linea "package" dentro del MiPanel.java por el nombre de paquete  utilizado por tu proyecto.

Ahora, una vez agregado los archivos necesarios, debemos crear un nuevo paquete de fuentes (carpeta) dando click derecho sobre el nombre del proyecto y seleccionado la opción "New folder" llamada "imagenes" (OJO es sin acento) donde se almacenará la imagen de fondo, en mi caso "tiempo.jpg"


Finalmente lo único restante es, agregar el código fuente dentro del programa al cual vamos a poner el fondo, primero debemos ubicar la función main, que debe ser parecida a la siguiente imagen:


Él cual tendremos que modificar, creando una instancia de la clase MiPanel llamando a la variable "fondo"; es importante recalcar que dicha clase permite indicar el nombre de la imagen a mostrar, así como también ancho y alto.

MiPanel fondo = new MiPanel("tiempo.jpg", 500, 300);

 Donde tiempo,jpg debe ser reemplazado por el nombre de la imagen que quieres mostrar como fondo; 500 es el ancho de la imagen y 300 es el alto. Quedando el código de la siguiente manera:



Espero que este material te ayude a colocar fondo a tus aplicaciones JAVA.


domingo, 22 de mayo de 2016

Generar archivo .JAR desde NetBeans para su distribución

Gusto en saludarles, como todos sabemos, si aprendemos y programamos soluciones de software en JAVA es para poder distribuirlos a nuestros clientes. Que mala idea seria obligar a nuestro cliente instalar una herramienta de desarrollo como NetBeans que muchas veces es soportado por maquinas con especificas características.

Es por ello ideal, tener una herramienta u opción para la generación de paquetes ejecutables (.jar) que puedan copiarse a una USB y poder instalarlos en los equipos clientes, Netbeans cuenta con una opción para dicha tarea.

A continuación les dejo una forma de hacerlo:

Primero cabe mencionar, que tengo un proyecto llamado ejemplosJFrame que contiene varios programas por lo cual, para compilarlo tendría que separarlos cada uno; afortunadamente en NetBeans puedes indicar el programa INICIAL mediante la propiedad "Main Class" del menú ejecutar como lo muestra la siguiente imagen.

También es importante tomar en cuenta que para poder compilar todos los programas incluidos en el proyecto NO DEBEN TENER ERRORES.


Una vez realizado esto lo que sigue es ir al menú RUN de Netbeans y presionar sobre "Clean and build project"


NetBeans nos debe confirmar que ya se construyo el archivo "car" de nuestra aplicación con un mensaje de BUILD SUCCESSFUL el cual nos indica que la construcción ha sido exitosa . Es en este momento que en la carpeta de nuestro proyecto se ha creado una nueva carpeta llamada dist en la cual esta nuestro archivo jar :
image
image

Este tutorial, inserta material del siguiente link:
http://javax-peru.blogspot.mx/2009/04/generar-un-archivo-jar-ejecutable.html

viernes, 4 de marzo de 2016

Regresa al GATO ahora es Android

Para la impartición de cátedra de asignaturas relacionadas a la programación de computadoras se han utilizado un sin fin de ejercicios, algoritmos, proyectos y artilugios para demostrar habilidades para el manejo de estructuras de control.

Es inevitable por lo tanto, no pensar en desarrollar un juego para motivar a los estudiantes, uno de los clásicos infaltables es sin duda el tres en raya, tres en línea, TIC - TAC - TOE, o el Gato o con el nombre que se conozca en cada país.


Es por ello, que por motivos de la programación de dispositivos móviles ANDROID hemos puesto manos a la obra y desarrollado nuestra app demostrativa mediante el empleo de orientación a objetos. Esperemos este material sea de ayuda a los que quieran aprender el desarrollo de apps móviles.

PASO 1. Lo que necesitamos

  • Y un poco de paciencia para la instalación de las herramientas 

Algo importante a mencionar, una vez finalizada la instalación del IDE será necesario definir cual será el lugar donde podremos ver y probar las aplicaciones, para ello existen algunas alternativas:

1.- Crear un AVD (Android Virtual Device) desde el menu "Tools-Android-AVD Manager" 


donde deberemos elegir "+ Create Virtual Device", yo personalmente he preferido crear una unidad virtual con la API 15 con Android 4.0.3 "Ice Cream Sandwich" con la finalidad de que mis aplicaciones sean soportadas por muchos mas dispositivos. Y para gozar de las ventajas de las nuevas APIs dejo la maquina virtual creada por default con la versión actual de android. Los detalles de las características del AVD no nos he analizado a profundidad, pero la imagen muestra algunos datos que podrán guiarles.

¡Aquí tenemos una pequeña nota importante a considerar! en muchas de las ocasiones el emulador no quiere arrancar pues indica que tu computadora no soporta aceleración de hardware o que falta la instalación del componente de aceleración; yo conozco dos formas de solucionarlo:  a) Debemos ir a la BIOS de la computadora e indicar soporte de HAXM , b) Podemos descargar el paquete de la aceleración de gráficos de Intel https://software.intel.com/en-us/android/articles/installation-instructions-for-intel-hardware-accelerated-execution-manager-windows no olvidando instalar el programa que queda en <sdk folder>/sdk/extras/intel/Hardware_Accelerated_Execution_Manager/ 


2.- Utilizar tu dispositivo android fisico o smartphone, todos los dispositivos que cuenten con el sistema operativo android tienen una opción denominada "Depuración USB", la localización de dicha opción ha variado con algunas versiones, aunque casi siempre se encuentra en el menu CONFIGURACIONES. 

Aqui hay un link donde puedes ver información relacionada http://www.elandroidelibre.com/2015/01/como-activar-el-modo-depuracion-usb-en-android.html

Una vez realizado los pasos anteriores solo habrá que conectar vía USB tu dispositivo para que el entorno de programación lo detecte al momento de ejecutar un programa Android.


3.- Utilizar un emulador externo de dispositivos Android, como lo es "Bluestacks"
Donde solo es necesario instalar la aplicación y cuando intente ejecutar un programa el IDE lo reconocerá siempre y cuando este funcionando dicho emulador.

Si has librado el paso 1, estas listo para empezar a desarrollar cualquier aplicación Android y realizar las pruebas necesarias.


PASO 2. El diseño

Para obtener un resultado visual agradable y evitando pelear con el código XML junto con "donde pongo esto", es necesario planear la interfaz final del proyecto.
Este gato en particular fue planeado como el siguiente diagrama:



Como los dispositivos android son muy variados en tamaño, es muy recomendable desarrollar una interfaz basada en tamaños relativos y no absolutos, por lo tanto, haciendo uso de los controles "LinearLayout" vertical y horizontal logramos el acomodo de las partes principales y además para indicar el "peso" de cada elemento dentro del layout utilizamos la propiedad android:layout_weight. En el siguiente link esta la explicación completa del manejo de esto:
http://androideity.com/2012/06/01/ui-fluidas-y-la-propiedad-weight-en-android/

Finalmente, el código XML de la vista de la aplicación quedo de la siguiente manera (las imágenes pueden descargarse a continuación y colocarse dentro de la carpeta "drawable":
















    

        

        
    

    

        

        

        
    


    

    

        

        

        
    

    


    

        

        

        
    

    

        

        

    





PASO 3. La programación

Una vez completado el diseño, es tiempo de empezar a programar, aunque si lo has notado en el mismo diseño del XML ya hemos agregado un poco de código mediante una propiedad llamada android:onClick="Tirando", más adelante platicaremos de ésta.

Sin lugar a dudas la parte más difícil de programar una aplicación es decidir por donde comenzar, nosotros hemos optado por programar una clase llamada Gato (además recuerdo que este juego tiene su origen dentro de una clase de programación orientada a objetos je).  Pues el diseño de la clase Gato y también una llamada Jugador son las siguientes:
quedando el código de ambas clase de la siguiente manera:

Clase GATO
/**
 * @author MartinC
 */
public class Gato {
    public int JugadorActual;
    public int Tamanio;
    public String Color;
    private String[] tablero;
    
    public Gato(){
        tablero = new String[10];
    }
    
    
    public boolean ColocarTiro(int posicion) {
        if (tablero[posicion]!=null) {
            return false;
        }
        
        if (JugadorActual==1) {
            tablero[posicion] = "X";
        } else {
            tablero[posicion] = "O";
        }
        
        return true;
    }
    
    public char BuscarGanador() {
        // Existen 8 combinaciones para ganar
        String cadena="";
        String valores = "";
        char resultado =' ';
        boolean ganador = false;
        
        if (JugadorActual ==1) 
            cadena = "XXX";
        else
            cadena = "OOO";
        
        valores = tablero[1] + tablero[2] + tablero[3];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[4] + tablero[5] + tablero[6];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[7] + tablero[8] + tablero[9];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[1] + tablero[4] + tablero[7];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[2] + tablero[5] + tablero[8];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[3] + tablero[6] + tablero[9];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[1] + tablero[5] + tablero[9];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[3] + tablero[5] + tablero[7];
        if (valores.equals(cadena)) { ganador = true; }
        
        if (ganador){ 
            if (JugadorActual ==1) 
                resultado = 'X';
            else
                resultado = 'O';
        }
        else {
            if (EstaLleno()) {
                resultado = '-';
            }
        }
        
        return resultado;
    }
    
    private boolean EstaLleno() {
        boolean lleno = true;
        for (int i=1; i<=9; i++) {
            if (tablero[i]==null) {
                lleno = false;
            }
        }
        return lleno;
    }
    
    public void CambiarTurno() {
        if (JugadorActual==1) {
            JugadorActual=2;
        }else
        {
            JugadorActual=1;
        }        
    }
}


Clase JUGADOR
/**
 * @author MartinC
 */
public class Jugador {
    public String Nombre;
    public String Simbolo;
}


Ahora,  recordemos el onClick de cada imageView del tablero del gato, dicho atributo permite el llamado de una función Java denominada "Tirando" que a su vez mandara a llamar al objeto Gato en este caso "Miau" para que este se encargue de procesar el tiro. NOTA: para que esta propiedad funcione debe indicarse también el atributo  "clickeable= true" como lo muestra el siguiente fragmento de código:

        

Otra cosa interesante es que cada ImageView se inicia con una imagen en blanco (algunos no están tan en blanco, al final de este paso se aclara la razón), y tiene un número de posición:



El código de la función "Tirando" que debe colocarse dentro de la clase que contiene el método Main(), es bueno aclarar que dicho método se vale de otros auxiliares llamados RealizarTiro (que hace uso del objeto "miau" para decidir la acción a realizar en la interfaz) y MostrarMarca (que muestra efectos visuales mediante la clase animation):

    public void Tirando(View v) {
        ImageView img = (ImageView) findViewById(v.getId());
        int index = Integer.parseInt(img.getTag().toString());
        RealizarTiro(index, img);
    }

    private void RealizarTiro(int posicion, ImageView btn) {
        if (!miau.ColocarTiro(posicion)) {
            return;
        }

        MostrarMarca(btn, posicion);

        char valor = miau.BuscarGanador();
        if (valor!=' ') {
            switch (valor){
                case 'X':
                    MostrarMensaje("Ganaste " + Jugador1.Simbolo);
                    break;
                case 'O':
                    MostrarMensaje("Ganaste " + Jugador2.Simbolo);
                    break;
                case '-':
                    MostrarMensaje("EMPATE!!!");
                    break;
            }
        }
        else {
            miau.CambiarTurno();
            if (miau.JugadorActual == 1) {
                txtNombre.setText(Jugador1.Nombre + " " + Jugador1.Simbolo);
                imagen.setImageResource(R.drawable.hombre);
            }
            else {
                txtNombre.setText(Jugador2.Nombre + " " + Jugador2.Simbolo);
                imagen.setImageResource(R.drawable.hombre2);
            }
        }
    }

    private void MostrarMarca(ImageView btn, int posic) {
        AnimationSet animacion = new AnimationSet(true);

        int rs = ScaleAnimation.RELATIVE_TO_SELF;
        ScaleAnimation escala = new ScaleAnimation(1,2,2,5,rs,0.5f, rs, 0.5f);
        escala.setDuration(500);

        ScaleAnimation escala2 = new ScaleAnimation(2,1,2,1,rs,0.5f, rs, 0.5f);
        escala2.setDuration(500);
        escala2.setStartOffset(500);

        AlphaAnimation aparicion = new AlphaAnimation(0,1);
        aparicion.setDuration(1000);

        animacion.addAnimation(escala);
        animacion.addAnimation(escala2);
        animacion.addAnimation(aparicion);

        int recurso=0;
        if (miau.JugadorActual == 1) {
            recurso = R.drawable.x;
            if (posic==2 || posic==5 || posic==8) {
                recurso = R.drawable.x_;
            }
        }
        else {
            recurso = R.drawable.o;
            if (posic==2 || posic==5 || posic==8) {
                recurso = R.drawable.o_;
            }
        }

        btn.setImageResource(recurso);

        btn.startAnimation(animacion);

    }

    private void MostrarMensaje(String msj) {
        Dialog dialogo = null;
        Builder builder = new Builder(this);

        builder.setTitle(msj);
        builder.setIcon(R.drawable.gato);
        builder.setPositiveButton("Volver a iniciar", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                miau = new Gato();
                miau.JugadorActual = 1;
                txtNombre.setText(Jugador1.Nombre + " - " + Jugador1.Simbolo);
                VaciarTablero();
            }
        });
        builder.setNegativeButton("Salir", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                finish();
            }
        });
        dialogo = builder.create();
        dialogo.show();
    }
    
    private void VaciarTablero() {
        ((ImageView)findViewById(R.id.imageView1)).setImageResource(R.drawable.blancoc);
        ((ImageView)findViewById(R.id.imageView2)).setImageResource(R.drawable.blanco);
        ((ImageView)findViewById(R.id.imageView3)).setImageResource(R.drawable.blancoc);
        ((ImageView)findViewById(R.id.imageView4)).setImageResource(R.drawable.blancoc);
        ((ImageView)findViewById(R.id.imageView5)).setImageResource(R.drawable.blanco);
        ((ImageView)findViewById(R.id.imageView6)).setImageResource(R.drawable.blancoc);
        ((ImageView)findViewById(R.id.imageView7)).setImageResource(R.drawable.blancoc);
        ((ImageView)findViewById(R.id.imageView8)).setImageResource(R.drawable.blanco);
        ((ImageView)findViewById(R.id.imageView9)).setImageResource(R.drawable.blancoc);
    }


IMPORTANTE:
Las lineas horizontales del tablero del gato fueron agregadas fácilmente con:

    
    

pero las lineas verticales, la verdad no fue algo a lo que encontré una solución rápida en su momento, por lo cual opte por generar una imagen que tuviera lados con linea, para que hicieran el efecto de linea vertical, tal como este:
lo cual hizo necesario también, la modificación de O y X para que si lanzaban a la posición correspondiente 2, 5 o 7 se mostrará la variante con linea jejeje, si alguien logra hacerlo sin dicho truco por favor compartan.


El código completo estará disponible más adelante...

PASO 4. La publicación

Para publicar aplicaciones es necesario registrarse como desarrollador Android Developer http://developer.android.com/intl/es/index.html e ingresar a la consola del desarrollador, pero para publicar es necesario realizar un pago de aprox. 25 dólares a la fecha de hoy. Los detalles de como publicar espero en algún momento poder subirlos, más no es el objetivo de esta entrada.

El resultado final esta publicada en el play store
https://play.google.com/store/apps/details?id=martinc.elgato

O puedes buscarla mediante las palabras clave:

martinc.elgato

Esto de esperar a que pasen las horas de salida del autobús, no dejan nada bueno....
Saludos Ing PAGA