6.4 GRIDLAYOUT

 

Bueno pues finalizamos este bloque dedicado a los layouts viendo el  layout GridLayout  va a ser un post intenso porque lo vamos a ver sobre una práctica, será la creación de una calculadora. Va a ser una calculadora sencilla con los números del 0 al 9 y las operaciones básicas: suma, resta, división, multiplicación… Así que vamos a ello

Para ello nos creamos una clase a la que voy a llamar Calculadora con el método principal main, a continuación crearemos otra clase con el título y el tamaño de la ventana:

package lay;

 

import javax.swing.JFrame;

 

public class Calculadora {

 

       public static void main(String[] args) {

           

 

       }

 

}

class MarcoCalculadora extends JFrame {

     

       public MarcoCalculadora() {

           

             setTitle("Calculadora");

           

             setBounds(500, 300, 450, 300);

           

           

       }

}

Después dentro del método main nos vamos a crear una instancia de la clase MarcoCalculadora, mediante el método setDefaultCloseOperation le vamos a indicar que al cerrar la ventana finalice la ejecución y que la ventana sea visible:

       public static void main(String[] args) {

         

           MarcoCalculadora mimarco = new MarcoCalculadora();

          

           mimarco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

         

           mimarco.setVisible(true);

 

       }

Nos creamos una lámina que va a contener el display, el resultado de las operaciones, en lugar de ser un campo de texto va a ser un botón y va a estar colocado en la parte superior de la ventana:

class LaminaCalculadora extends JPanel {

   

    public LaminaCalculadora() {

        

          setLayout(new BorderLayout());

         

          JButton display =new JButton("0");

        

          add(display, BorderLayout.NORTH);

        

    }

}

Dentro del constructor de la clase MarcoCalculadora vamos a instanciar esta clase para que nos muestre el botón en la ventana:

             LaminaCalculadora milamina = new LaminaCalculadora();

            

             add(milamina);

Probamos:

 


Para que el botón nos aparezca más parecido a un campo de texto lo deshabilitamos con el método setEnabled en false:

class LaminaCalculadora extends JPanel {

   

    public LaminaCalculadora() {

        

      setLayout(new BorderLayout());

       

        JButton display =new JButton("0");

      

        display.setEnabled(false);

      

        add(display, BorderLayout.NORTH);

 

    }

}

Creamos una nueva lámina para añadir los botones dentro del constructor de la clase LaminaCalculadora:

        JPanel milamina2 = new JPanel();

       

        milamina2.setLayout(new GridLayout(4, 4));

Va a ser una disposición de 4x4, es decir, 4 filas y 4 columnas.

A continuación, agregamos los botones, hay dos formas de añadirlos, de esta forma:

        JButton boton1=new JButton("1");

       

        add(boton1);

Así con todos los botones que tenemos que añadir y después hay que añadir la lámina:

add(lamina2, BorderLayout.CENTER);

Sería un código largo, no quedaría del todo bien… otra forma de añadir los botones sería crearnos un método después de la llave de cierre del constructor de la LaminaCalculadora:

private void agregarBotones (String tit) {

   

    JButton boton = new JButton(tit);

  

    milamina2.add(boton);

}

 

private JPanel milamina2;

}

Instanciamos un objeto de tipo botón, al método y declaramos la variable milamina2 ya que al estar declarada en el constructor de la clase LaminaCalculadora no la podemos utilizar fuera, de forma, que una vez hecho esto en el constructor no es necesario declararla, sino, iniciarla:

milamina2 = new JPanel();

Añadimos los botones dentro del constructor de la LaminaCalculadora y añadimos la segunda lámina:

agregarBotones("7");

       

        agregarBotones("8");

      

        agregarBotones("9");

      

        agregarBotones("/");

      

        agregarBotones("4");

      

        agregarBotones("5");

      

        agregarBotones("6");

      

        agregarBotones("*");

      

        agregarBotones("1");

      

        agregarBotones("2");

      

        agregarBotones("3");

      

        agregarBotones("-");

      

        agregarBotones("0");

      

        agregarBotones(".");

       

        agregarBotones("+");

      

        agregarBotones("=");

      

        add(milamina2, BorderLayout.CENTER);

Probamos:

 


 

Tendríamos la primera parte terminada, ahora nos falta desarrollar el código para que la calculadora realice las operaciones básicas, el código completo:

package lay;

 

import java.awt.BorderLayout;

import java.awt.GridLayout;

 

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

 

public class Calculadora {

 

       public static void main(String[] args) {

           

           MarcoCalculadora mimarco = new MarcoCalculadora();

          

           mimarco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

         

           mimarco.setVisible(true);

 

 

       }

 

}

class MarcoCalculadora extends JFrame {

     

       public MarcoCalculadora() {

           

             setTitle("Calculadora");

           

             setBounds(500, 300, 450, 300);

            

             LaminaCalculadora milamina = new LaminaCalculadora();

            

             add(milamina);

 

           

           

       }

}

 

class LaminaCalculadora extends JPanel {

   

    public LaminaCalculadora() {

        

          setLayout(new BorderLayout());

         

          JButton display =new JButton("0");

         

          display.setEnabled(false);

        

          add(display, BorderLayout.NORTH);

         

          milamina2 = new JPanel();

         

          milamina2.setLayout(new GridLayout(4, 4));

         

          agregarBotones("7");

         

          agregarBotones("8");

        

          agregarBotones("9");

        

          agregarBotones("/");

        

          agregarBotones("4");

        

          agregarBotones("5");

        

          agregarBotones("6");

        

          agregarBotones("*");

        

          agregarBotones("1");

        

          agregarBotones("2");

        

          agregarBotones("3");

        

          agregarBotones("-");

        

          agregarBotones("0");

        

          agregarBotones(".");

         

          agregarBotones("+");

        

          agregarBotones("=");

         

          add(milamina2, BorderLayout.CENTER);

 

        

    }

   

    private void agregarBotones (String tit) {

       

        JButton boton = new JButton(tit);

      

        milamina2.add(boton);

    }

 

    private JPanel milamina2;

    }

 

Hay una forma para darle tamaño por defecto y es utilizando el método pack(), este método reemplaza al método setBoundssetSize… Si lo utilizamos:

class MarcoCalculadora extends JFrame {

     

       public MarcoCalculadora() {

           

             setTitle("Calculadora");

           

             //setBounds(500, 300, 450, 300);

            

             LaminaCalculadora milamina = new LaminaCalculadora();

            

             add(milamina);

 

             pack();

           

       }

}

Probamos:



Todos los elementos se adaptan al tamaño por defecto.

Bien, dicho esto vamos a empezar a darle funcionalidad a la calculadora. Vamos a empezar haciendo que al pulsar cualquiera de los botones de los números aparezca en el display. Para ello creamos una nueva clase que va a implementar la interfaz ActionListener y poner los botones a la escucha.

public void agregarBotones (String tit) {

     

        JButton boton = new JButton(tit);

       

        milamina2.add(boton);

    }

 

private class insertaNumero implements ActionListener {

 

      @Override

      public void actionPerformed(ActionEvent e) {

           

            String entrada = e.getActionCommand();

           

      }

 

}

 

    

    private JPanel milamina2;

    }


Con la interfaz ActionListener debemos crear el método actionPerformed, dentro de él nos creamos una variable de tipo String que va a almacenar el valor del botón que hayamos pulsado. Seguidamente tenemos que hacer que en el display aparezca el botón que hemos pulsado:

private class insertaNumero implements ActionListener {

 

      @Override

      public void actionPerformed(ActionEvent e) {

           

            String entrada = e.getActionCommand();

           

            display.setText(entrada);

           }

      }

    private JPanel milamina2;

   

    private JButton display;

 

}

Utilizamos el método setText para establecer, mostrar el valor o el número del botón en el display. Como el objeto display ya está declarado en el constructor de la LaminaCalculadora nos va a dar un error para solucionarlo tenemos que declarar la variable display de tipo JButton. Y en el constructor no hace falta declararla, sino, iniciarla:

display =new JButton("0");

Para poner los botones en escucha vamos a utilizar el método agregarBotones para que no solo nos añada los botones, sino, también que nos lo ponga en escucha, como segundo parámetro a este método le vamos a pasar un argumento de tipo ActionListener al que vamos a llamar oyente y poner el botón al a escucha:

    private void agregarBotones (String tit, ActionListener oyente) {

       

        JButton boton = new JButton(tit);

       

        boton.addActionListener(oyente);

      

        milamina2.add(boton);

    }

Si nos fijamos, nos da error el método agregarBotones porque le hemos de pasar un segundo argumento, solo se lo vamos a pasar a los botones que tienen valores, y av a ser el nombre de la instancia. Los que tienen el signo de las operaciones de momento los vamos a comentar, y antes de eso hemos de instanciar la clase insertaNumero:

ActionListener insertar = new insertaNumero();

         

          agregarBotones("7", insertar);

         

          agregarBotones("8", insertar);

        

          agregarBotones("9", insertar);

        

          //agregarBotones("/");

        

          agregarBotones("4", insertar);

        

          agregarBotones("5", insertar);

        

          agregarBotones("6", insertar);

        

          //agregarBotones("*");

        

          agregarBotones("1", insertar);

        

          agregarBotones("2", insertar);

        

          agregarBotones("3", insertar);

        

          //agregarBotones("-");

        

          agregarBotones("0", insertar);

        

          //agregarBotones(".");

         

          //agregarBotones("+");

        

          //agregarBotones("=");

         

          add(milamina2, BorderLayout.CENTER);

Si probamos la aplicación vemos que si pulsamos un botón se visualiza en el display, si pulsamos otro también se visualiza, sin embargo, no se añaden. Por ejemplo, si pulsamos el botón del número 1, en el display aparece el 1, si pulsamos el botón 5 se elimina automáticamente el 1 del display y aparece el número 5… sin embargo, las calculadoras no funcionan de esta manera, se pulsa el 1 y luego el 5, tienen que aparecer 15 en el display, y eso es lo que vamos a programar ahora. Para ello hemos de modificar el método setText de la clase insertaNumero:

display.setText(entrada);

Le hemos de indicar que nos ha de mostrar lo que hay en la pantalla más lo que introduzcamos después:

display.setText(display.getText()+entrada);

Probamos:



Vemos que se añaden los botones, no obstante el 0 sigue apareciendo, para eliminar el 0 inicial hacemos lo siguiente, nos creamos una variable de tipo boolean:

private boolean principio;

Y en la clase insertaNumero dentro del método actionPerformed crear un condicional if:

private class insertaNumero implements ActionListener {

 

      @Override

      public void actionPerformed(ActionEvent e) {

           

            String entrada = e.getActionCommand();

           

        if(principio) {

           

            display.setText(" ");

          

            principio=false;

     }

 

           

            display.setText(display.getText()+entrada);

           

      }

Le estamos indicando que si la variable principio es true que nos borre la pantalla y luego poner la variable a false. Sin embargo, todavía no funciona ya que al declarar la variable booleana si no la iniciamos por defecto es false, por lo que nunca va a entrar en el condicional if, así que hay que indicarle de alguna manera que esta variable booleana sea true, dentro de la LaminaCalculadora declaramos esta variable como true.

class LaminaCalculadora extends JPanel {

       public LaminaCalculadora() {

             principio=true;

Si probamos ahora la aplicación vemos que al pulsar cualquier botón de forma automática el 0 desaparece del display.

Ahora ya nos quedaría que la calculadora realizará las operaciones básicas.

Lo primero que tenemos que hacer es quitar las barras de comentario de los botones que tienen el signo de las operaciones. La clase insertaNumero sí que nos servía para añadir los botones numéricos, sin embargo, no nos sirve para las operaciones matemáticas por lo que nos creamos una nueva clase que gestione los eventos de las operaciones matemáticas.

    private class clOperaciones implements ActionListener{

 

            @Override

            public void actionPerformed(ActionEvent e) {

                 

                  principio=true;

                 

            }

     

     

    }

Utilizamos la variable booleana principio y la inicializamos en true. Instanciamos esta clase para pasar por parámetro al método agregarBotones y en los métodos agregarBotones de los símbolos de las operaciones como segundo parámetro hay que pasarle operación:

ActionListener operacion = new clOperaciones();

        

          agregarBotones("/", operacion);

        

          agregarBotones("*", operacion);

                 

          agregarBotones("-", operacion);

                 

          agregarBotones(".", operacion);

         

          agregarBotones("+", operacion);

        

          agregarBotones("=", operacion);

Tal y como tenemos la aplicación, si pulsamos los botones: 1, 2 y 3:



Al pulsar en un operador, por ejemplo, suma y pulsamos el botón 2 y 5:



Lo que hace es resetear el display, es decir, quita los números 123 y añade los números de los botones que hemos pulsado, esto es así gracias a la variable principio que la hemos inicializado que es la que resetea el display.

Tenemos que crearnos una variable que almacene las operaciones que vayamos realizando:

private double resultado;

Dentro del método actionPerformed de la clase clOperaciones antes de la variable booleana vamos a llamar a un método que vamos a llamar calcular que todavía no hemos creado y le vamos a pasar como parámetro lo que hay en el display. Pero como el display no es un campo de texto, es un botón hay que pasarle el valor numérico que haya dentro del display a String:

    private class clOperaciones implements ActionListener{

 

            @Override

            public void actionPerformed(ActionEvent e) {

                 

                  calcular(Double.parseDouble(display.getText()));

                 

                  principio=true;

                 

            }

     

     

    }

Creamos el método calcular después del método actionPerformed y le hemos de pasar por parámetro un doublé:

            public void calcular(double x) {

           

           

        }

Este método va a ser el encargado de realizar todas las operaciones.

Creamos una variable de tipo String dentro del método actionPerformed:

public void actionPerformed(ActionEvent e) {

                 

                  String operador=e.getActionCommand();

                 

                  calcular(Double.parseDouble(display.getText()));

                 

                  principio=true;

                 

            }

Con esto conseguimos almacenar un String en la variable operador que corresponde al texto del botón.

Creamos otra variable de tipo String:

private String ultimaAccion;

Que la utilizaremos para cuando el usuario pulse el botón del igual (=). Y está variable la igualamos a la variable operador:

            public void actionPerformed(ActionEvent e) {

                 

                  String operador=e.getActionCommand();

                 

                  calcular(Double.parseDouble(display.getText()));

                 

                  ultimaAccion=operador;

                 

                  principio=true;

                 

            }

Lo que hacemos con esto es que en la variable ultimaAccion se almacene todas las operaciones que se han realizado, además tenemos que inicializarla en el constructor de la lámina:

ultimaAccion = "+";

Con esto ya podemos realizar las operaciones, dentro del método calcular:

            public void calcular(double x) {

           

                  if(ultimaAccion.equals("+")) {

               

                resultado+=x;

         }

 

        }  

Lo que hacemos aquí es almacenar en la variable resultado lo que le hemos pasado por parámetro. Seguidamente con un else if realizamos lo mismo con las demás operaciones:

public void calcular(double x) {

           

            if(ultimaAccion.equals("+")) {

               

                resultado+=x;

         }else if(ultimaAccion.equals("-")) {

              

                resultado-=x;

         }else if(ultimaAccion.equals("*")) {

              

                resultado*=x;

         }else if(ultimaAccion.equals("/")) {

              

               resultado/=x;

         }

       

 

        }        

Tenemos que indicarle lo que tenemos acumulado, es decir, cuando pulsemos el botón igual:

      public void calcular(double x) {

           

            if(ultimaAccion.equals("+")) {

               

                resultado+=x;

         }else if(ultimaAccion.equals("-")) {

              

                resultado-=x;

         }else if(ultimaAccion.equals("*")) {

              

                resultado*=x;

         }else if(ultimaAccion.equals("/")) {

              

               resultado/=x;

              

              

         }

       

            display.setText(" "+resultado);

        }

Si le pasamos al método setText la variable resultado va a dar un error ya que es de tipo double, para solucionarlo lo concatenamos con una cadena vacía. El código completo de esta práctica es el siguiente:

package lay;

 

import java.awt.BorderLayout;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

 

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

 

public class Calculadora {

 

       public static void main(String[] args) {

           

           MarcoCalculadora mimarco = new MarcoCalculadora();

          

           mimarco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

         

           mimarco.setVisible(true);

 

 

       }

 

}

class MarcoCalculadora extends JFrame {

     

       public MarcoCalculadora() {

           

             setTitle("Calculadora");

           

             setBounds(500, 300, 450, 300);

            

             LaminaCalculadora milamina = new LaminaCalculadora();

            

             add(milamina);

            

             //pack();

 

           

           

       }

}

 

class LaminaCalculadora extends JPanel {

   

    public LaminaCalculadora() {

     

      principio=true;

     

      ultimaAccion = "+";

        

          setLayout(new BorderLayout());

         

          display =new JButton("0");

         

          display.setEnabled(false);

        

          add(display, BorderLayout.NORTH);

         

          milamina2 = new JPanel();

         

          milamina2.setLayout(new GridLayout(4, 4));

         

          ActionListener insertar = new insertaNumero();

         

          ActionListener operacion = new clOperaciones();

         

          agregarBotones("7", insertar);

         

          agregarBotones("8", insertar);

        

          agregarBotones("9", insertar);

        

          agregarBotones("/", operacion);

        

          agregarBotones("4", insertar);

        

          agregarBotones("5", insertar);

        

          agregarBotones("6", insertar);

        

          agregarBotones("*", operacion);

        

          agregarBotones("1", insertar);

        

          agregarBotones("2", insertar);

        

          agregarBotones("3", insertar);

        

          agregarBotones("-", operacion);

        

          agregarBotones("0", insertar);

        

          agregarBotones(".", operacion);

         

          agregarBotones("+", operacion);

        

          agregarBotones("=", operacion);

         

          add(milamina2, BorderLayout.CENTER);

 

        

    }

   

    private void agregarBotones (String tit, ActionListener oyente) {

       

        JButton boton = new JButton(tit);

       

        boton.addActionListener(oyente);

      

        milamina2.add(boton);

    }

   

    private class insertaNumero implements ActionListener {

 

            @Override

            public void actionPerformed(ActionEvent e) {

                 

                  String entrada = e.getActionCommand();

                 

              if(principio) {

                 

                  display.setText(" ");

                

                  principio=false;

           }

 

                 

                  display.setText(display.getText()+entrada);

                 

            }

     

     

    }

    private class clOperaciones implements ActionListener{

 

            @Override

            public void actionPerformed(ActionEvent e) {

                 

                  String operador=e.getActionCommand();

                 

                  calcular(Double.parseDouble(display.getText()));

                 

                  ultimaAccion=operador;

                 

                  principio=true;

                 

            }

            public void calcular(double x) {

           

            if(ultimaAccion.equals("+")) {

               

                resultado+=x;

         }else if(ultimaAccion.equals("-")) {

              

                resultado-=x;

         }else if(ultimaAccion.equals("*")) {

              

                resultado*=x;

         }else if(ultimaAccion.equals("/")) {

              

               resultado/=x;

              

              

         }

       

            display.setText(" "+resultado);

        }  

     

    }

 

    private JPanel milamina2;

   

    private JButton display;

   

    private boolean principio;

   

    private double resultado;

   

    private String ultimaAccion;

    }

Os espero en el próximo bloque dedicado a los Componentes Swings, si tenéis dudas, sugerencias o alternativas de hacer las prácticas con otro código podéis hacerlo a través de los comentarios del blog. Hasta pronto!

6.3 BORDERLAYOUT << >> 7.1CUADROS DE TEXTO



No hay comentarios:

Publicar un comentario