viernes, 7 de marzo de 2014

Práctica de cuentas bancarias. 3ª parte. GUI.

Pues al fin vamos a crear nuestro primer "programa visual", que es casi seguro lo que todos esperan crear cuando empiezan con esto de la programación ^^. Hoy seguiremos con nuestra práctica de cuentas bancarias de la otra vez (si no la hiciste, puedes descargarte los códigos, no te preocupes ;) ). Se desea desarrollar una aplicación gráfica que permita manipular una cuenta bancaria. La aplicación tendrá tres posibles vistas, las cuales implementarán todas la misma interfaz:
(Nota: en orden, las tres imagenes son  PanelCuenta1, PanelCuenta2 y PanelCuenta3)





import java.awt.event.*;
public interface VistaCuenta {
  String INGRESO = "INGRESO";
  String GASTO = "GASTO";
  String SALDO = "SALDO";
  /** Obtenemos la cantidad a ingresar
  * @return double con la cantidad a ingresar
  */
  double obtenerCantidad();
  /** Establecemos el saldo de la cuenta.
  * @param saldo double con el saldo de la cuenta.
  */
  void saldo(double saldo);
  /** Mostramos un mensaje de información.
  * @param msg String con el mensaje a mostrar.
  */
  void mensaje(String msg);
  /** Pasamos el controlador.
  */
  void controlador(ActionListener ctr);
  }

Aquí teneis el enunciado en pdf.
Las clases que implementan los diferentes paneles gráficos serán PanelCuentas1, PanelCuentas2 y PanelCuentas3, respectivamente.
Las tres deben implementar la interfaz VistaCuenta.
Para controlar los botones de ingresar, extraer y saldo implementar la clase CtrCuenta.
La clase CuentaDemo será la clase principal de la aplicación.

Debemos poder poner o quitar comentarios al panel que queremos utilizar y el resto debe funcionar.
      VistaCuenta vistaCuenta = new PanelCuenta1();
   // VistaCuenta vistaCuenta = new PanelCuenta2();
    //VistaCuenta vistaCuenta = new PanelCuenta3();

Observa que la segunda y la tercera versión no proporcionan un botón para consultar el saldo. En la tercera versión, el campo de texto en el que introducir la cantidad será no editable, forzando a que la cantidad se introduzca utilizando la botonera. Esta botonera será controlada desde el propio panel. Es decir, el panel implementará la interfaz ActionListener.
Aquí os pongo la demo:
import java.awt.event.ActionListener;
import javax.swing.*;


public class CuentaDemo {
 public static void main(String []args) {
  //creamos la vista
  //VistaCuenta vistaCuenta  = new PanelCuenta1();
  //VistaCuenta vistaCuenta  = new PanelCuenta2();
  VistaCuenta vistaCuenta  = new PanelCuenta3();
  
  // Creamos el modelo
  Cuenta cuenta = new Cuenta(0);
  //creamos el controlador pasandole la vista y el modelo
  ActionListener ctrCuenta = new ctrCuenta(vistaCuenta, cuenta);
  //Le decimos a la vista el nombre del controlador
  vistaCuenta.controlador(ctrCuenta);
  //Creamos el contenido superior
  JFrame ventana = new JFrame("Control de cuentas");
  
  ventana.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  ventana.setContentPane((JPanel)vistaCuenta);
  ventana.pack();
  ventana.setVisible(true);
  }
}


Bueno pues aquí os pongo los códigos fuente:

Primero el del controlador ctrCuenta:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

//Controlador
public class ctrCuenta implements ActionListener{
 
 //referencia al modelo
 private Cuenta cuenta;
 //referencia a la vista
 private VistaCuenta vistacuenta;
 //constructor que recibe a la vista y al modelo
 public ctrCuenta(VistaCuenta vc, Cuenta c) {
  cuenta = c;
  vistacuenta = vc;
 }
 
 
 public void actionPerformed(ActionEvent evento) {
  
  String command = evento.getActionCommand();
  
  if (command.equals(VistaCuenta.INGRESO)) {
   double cantidad = vistacuenta.obtenerCantidad();
   cuenta.ingresa(cantidad); 
   vistacuenta.saldo(cuenta.saldo());
   vistacuenta.mensaje("Ingreso de "+ cantidad + "€"+" realizado con éxito.");
   
  } else if(command.equals(VistaCuenta.GASTO)) {
   double cantidad = vistacuenta.obtenerCantidad();
   cuenta.extrae(cantidad);
   vistacuenta.saldo(cuenta.saldo());
   vistacuenta.mensaje("Pago de "+ cantidad + "€"+" realizado con éxito.");
   
  } else if(command.equals(VistaCuenta.SALDO)) {
   vistacuenta.mensaje("Su saldo es de "+ cuenta.saldo() + "€");
   
  }
 }
 
}

Ahora el de PanelCuenta1
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import javax.swing.*;


public class PanelCuenta1 extends JPanel implements VistaCuenta{
 private static final long serialVersionUID = 1L;

 private JButton saldoJB;
 private JButton extraerJB;
 private JButton ingresarJB;
 private JTextField cantidadJTF;
 private JLabel mensajeJL;
 private JLabel saldoJL;
 
 
 public PanelCuenta1() {
  //Creacion de los componentes
  saldoJB  = new JButton("SALDO");
  extraerJB  = new JButton("EXTRAER");
  ingresarJB  = new JButton("INGRESAR");
  cantidadJTF = new JTextField(10);
  mensajeJL  = new JLabel(" ");
  saldoJL  = new JLabel(" ");
  
  //Creacion del panel este.
  JPanel panelD = new JPanel();
  panelD.setLayout(new GridLayout(3,1)); //3 filas y 1 columna
  panelD.add(ingresarJB);
  panelD.add(extraerJB);
  panelD.add(saldoJB);
  
  //creo el panel central 
  JPanel panelC = new JPanel();
  panelC.setLayout(new GridLayout(2,2));
  panelC.add(new JLabel("Cantidad"));
  panelC.add(cantidadJTF);
  panelC.add(new JLabel("Saldo: "));
  panelC.add(saldoJL);
  
  //Montar el panel principal  
  setLayout(new BorderLayout());
  add(panelD, BorderLayout.EAST);
  add(panelC, BorderLayout.CENTER);
  add(mensajeJL, BorderLayout.SOUTH);
 }
  
 
 @Override
 public double obtenerCantidad() {
  
  return Double.parseDouble(cantidadJTF.getText());
 }

 @Override
 public void saldo(double saldo) {
  
  saldoJL.setText(String.format("%12.2f", saldo));
 }

 @Override
 public void mensaje(String msg) {
  
  mensajeJL.setText(msg);
 }

 @Override
 public void controlador(ActionListener ctr) {
  
  ingresarJB.addActionListener(ctr);
  ingresarJB.setActionCommand(INGRESO);
  saldoJB.addActionListener(ctr);
  saldoJB.setActionCommand(SALDO);
  extraerJB.addActionListener(ctr);
  extraerJB.setActionCommand(GASTO);
 }

 
 
 
 
 

}

El de PanelCuenta2:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;

import javax.swing.*;


public class PanelCuenta2 extends JPanel implements VistaCuenta{
 private static final long serialVersionUID = 1L;
 
 private JButton extraerJB;
 private JButton ingresarJB;
 private JTextField cantidadJTF;
 private JLabel saldoJL;
 private JLabel mensajeJL;
 
 public PanelCuenta2() {
  extraerJB  = new JButton("EXTRAER");
  ingresarJB  = new JButton("INGRESAR");
  cantidadJTF = new JTextField(10);
  saldoJL  = new JLabel(" ");
  mensajeJL = new JLabel(" ");
  
  //Panel Este
  JPanel panelEste = new JPanel();   // Creamos el panel
  panelEste.setLayout(new GridLayout(3, 1)); //2 filas, 1 columna
  panelEste.add(new JLabel("Saldo: "));
  panelEste.add(saldoJL);
  panelEste.add(mensajeJL);
  //Panel de Botones
  JPanel botonPanel = new JPanel();
  botonPanel.setLayout(new GridLayout(1, 2));
  botonPanel.add(ingresarJB);
  botonPanel.add(extraerJB);
  
  
  //Panel Oeste
  JPanel panelOeste = new JPanel();
  panelOeste.setLayout(new GridLayout(2, 1));
  panelOeste.add(cantidadJTF);
  panelOeste.add(botonPanel, BorderLayout.SOUTH);
  
  //Panel total
  setLayout(new GridLayout(1, 2));
  add(panelOeste, BorderLayout.WEST);
  add(panelEste, BorderLayout.EAST);
  
 }
 
 
 
 @Override
 public double obtenerCantidad() {
  
  return Double.parseDouble(cantidadJTF.getText());
 }
 @Override
 public void saldo(double saldo) {
  
  saldoJL.setText(String.format("%12.2f", saldo));
 }
 @Override
 public void mensaje(String msg) {
  
  mensajeJL.setText(msg);
 }
 @Override
 public void controlador(ActionListener ctr) {
  
  ingresarJB.addActionListener(ctr);
  ingresarJB.setActionCommand(INGRESO);
  extraerJB.addActionListener(ctr);
  extraerJB.setActionCommand(GASTO);
 }
 

}

Y el de PanelCuenta3:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;


public class PanelCuenta3 extends JPanel implements ActionListener, VistaCuenta{
 private static final long serialVersionUID = 1L;
 
 private JButton b1JB;
 private JButton b2JB;
 private JButton b3JB;
 private JButton b4JB;
 private JButton b5JB;
 private JButton b6JB;
 private JButton b7JB;
 private JButton b8JB;
 private JButton b9JB;
 private JButton b0JB;
 private JButton ingresarJB;
 private JButton extraerJB;
 private JButton borrarJB;
 private JLabel saldoJL;
 private JTextField cantidadJTF;
 private JTextArea mensajesJTA;
 
 
 public PanelCuenta3() {
  b1JB = new JButton("1");
  b2JB = new JButton("2");
  b3JB = new JButton("3");
  b4JB = new JButton("4");
  b5JB = new JButton("5");
  b6JB = new JButton("6");
  b7JB = new JButton("7");
  b8JB = new JButton("8");
  b9JB = new JButton("9");
  b0JB = new JButton("0");
  ingresarJB = new JButton("INGRESAR");
  extraerJB = new JButton("EXTRAER");
  borrarJB = new JButton("Borrar");
  saldoJL = new JLabel(" ");
  cantidadJTF = new JTextField(" ");
  cantidadJTF.setEditable(false);
  mensajesJTA = new JTextArea(" ");
  
  b1JB.addActionListener(this);
  b2JB.addActionListener(this);
  b3JB.addActionListener(this);
  b4JB.addActionListener(this);
  b5JB.addActionListener(this); 
  b6JB.addActionListener(this);
  b7JB.addActionListener(this);
  b8JB.addActionListener(this);
  b9JB.addActionListener(this);
  b0JB.addActionListener(this);
  borrarJB.addActionListener(this);
  b1JB.setActionCommand("1");
  b2JB.setActionCommand("2"); 
  b3JB.setActionCommand("3");
  b4JB.setActionCommand("4"); 
  b5JB.setActionCommand("5"); 
  b6JB.setActionCommand("6");
  b7JB.setActionCommand("7");
  b8JB.setActionCommand("8");
  b9JB.setActionCommand("9");
  b0JB.setActionCommand("0");
  borrarJB.setActionCommand("BORRAR");
   
  //Panel números
  JPanel panelNum = new JPanel();
  panelNum.setLayout(new GridLayout(4,3));
  panelNum.add(b1JB);
  panelNum.add(b2JB);
  panelNum.add(b3JB);
  panelNum.add(b4JB);
  panelNum.add(b5JB);
  panelNum.add(b6JB);
  panelNum.add(b7JB);
  panelNum.add(b8JB);
  panelNum.add(b9JB);
  panelNum.add(b0JB);
  panelNum.add(new JLabel(" "));
  panelNum.add(borrarJB);
  
  //Panel de acciones
  JPanel panelAccion = new JPanel();
  panelAccion.setLayout(new GridLayout(2, 1));
  panelAccion.add(ingresarJB);
  panelAccion.add(extraerJB);
  
  //panel Central
  JPanel panelCentral = new JPanel();
  panelCentral.setLayout(new GridLayout(1, 2));
  panelCentral.add(panelNum);
  panelCentral.add(panelAccion);
  
  //Panel Saldo
  JPanel panelSaldo = new JPanel();
  panelSaldo.setLayout(new GridLayout(1, 2));
  panelSaldo.add(new JLabel("Saldo: "));
  panelSaldo.add(saldoJL);
  
  setLayout(new GridLayout(4, 1));
  add(cantidadJTF, BorderLayout.EAST);
  add(panelCentral, BorderLayout.EAST);
  add(panelSaldo, BorderLayout.EAST);
  add(mensajesJTA, BorderLayout.EAST);
  
 }
 
 
 @Override
 public double obtenerCantidad() {
  
  return Double.parseDouble(cantidadJTF.getText());
 }

 @Override
 public void saldo(double saldo) {
  
  saldoJL.setText(String.format("%12.2f", saldo));
 }

 @Override
 public void mensaje(String msg) {
  
  mensajesJTA.append(msg + "\n" + "\n");
 }

 @Override
 public void controlador(ActionListener ctr) {
  
  ingresarJB.addActionListener(ctr);
  ingresarJB.setActionCommand(INGRESO);
  extraerJB.addActionListener(ctr);
  extraerJB.setActionCommand(GASTO);
 }

 @Override
 public void actionPerformed(ActionEvent arg0) {
  String e = arg0.getActionCommand();
  
  if(e.equals("BORRAR")) {
   cantidadJTF.setText(" ");
  } else {
   int i = Integer.parseInt(e);
   cantidadJTF.setText(Integer.toString(
     i+10*Integer.parseInt( cantidadJTF.getText().equals(" ") ? "0" : cantidadJTF.getText())));
  }
  
 }
 

}

Espero que os haya gustado la práctica. Tampoco es muy complicado hacer una gui de estas. Es más cosa de diseñarla. Sin embargo la clase controladora (ctrCuenta) es muy similar a las que se usan en videojuegos para captar las acciones que hacemos.

Eso es todo gente. No dudeis en preguntar cualquier duda y hasta el Domingo.

Saludos ;)

1 comentario: