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 setBounds, setSize… 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