lunes, 10 de marzo de 2014

Práctica de creación de Jarras (Parte 3) GUI

Buenas, hoy vamos a implementar una GUI para la aplicación de Jarras vista anteriormente. Vamos a intentar que se parezca lo más posible a esto:



La clase que implementa el panel gráfico será la clase PanelJarras, que debe implementar la interfaz  istaJarras, ControladorJarras será la clase controladora y AplicacionJarras la clase principal de la aplicación. El programa Jarras será el de las prácticas anteriores. La interfaz VistaJarras se proporciona a continuación:
import java.awt.event.ActionListener;

public interface VistaJarras { 
 public static final String INICIAR = "INICIAR"; 
 public static final String LLENAR_A = "LLENAR_A"; 
 public static final String LLENAR_B = "LLENAR_B"; 
 public static final String VACIAR_A = "VACIAR_A"; 
 public static final String VACIAR_B = "VACIAR_B"; 
 public static final String VOLCAR_A_EN_B = "VOLCAR_A_EN_B"; 
 public static final String VOLCAR_B_EN_A = "VOLCAR_B_EN_A"; 
 public static final String FINALIZAR = "FINALIZAR"; 
 /** 
  *  * * Pasamos el controlador.
  *   */ 
 public void controlador(ActionListener ctr); 
 /** 
  * * Obtenemos la capacidad inicial de la jarra A.
  * * @return int con la capacidad inicial de la jarra A.
  *  */ 
 public int capacidadInicialA(); 
 /** 
  * * Obtenemos la capacidad inicial de la jarra B
  * * @return int con la capacidad inicial de la jarra B.
  *  */

 public int capacidadInicialB();
 /**
  *
  *
  ** Mostramos un mensaje de error.
  ** @param mensaje
  * * String con el mensaje a mostrar.
  *
  *@return 
  * */
 public void error(String mensaje);

 /**
  * * Mostramos un mensaje de información.
  * * @param mensaje
  * String con el mensaje a mostrar. 
  */ 
 public void ok(String mensaje); 
 /** 
 *  Habilitamos o deshabilitamos el modo inicialización de jarras o trasvases
 *  @param b
 *  true para habilitar el modo inicialización; false para el modo trasvases 
  */ 
 public void habilitarInicio(boolean b); 
 /** 
* Establecemos la capacidad de la jarra A.
* @param c
 * int con la capacidad de la jarra A 
 */ 
public void capacidadA(int c); 
/** 
* Establecemos la capacidad de la jarra B.
* @param c
 * int con la capacidad de la jarra B. 
 */ 
public void capacidadB(int c); 
/** 
* Establecemos el contenido de la jarra A.
* @param c
 * int con el contenido de la jarra A. 
 */ 
public void contenidoA(int c); 
/** 
* Establecemos el contenido de la jarra B.
* @param c
 * int con el contenido de la jarra B. 
 */ 
public void contenidoB(int c); 
/** 
* Añadimos un mensaje al histórico.
* @param mensaje
 * String con el mensaje a añadir. 
 */ 
public void añadirAHistórico(String mensaje); 
/** 
* Limpiamos el histórico.
 */ 
public void limpiar(); 
}

NOTA 1: Cuando a un componente se le asigna un GridLayout es posible especificar en el constructor el margen que debe quedar entre el elemento a insertar y el borde de la cuadrícula. Así, si creamos un objeto con new GridLayout(4,2,5,5) además de crear la matriz de 4x2 para insertar componentes, cada componente se mostrará con un margen de 5 puntos por cada lado. Es decir, la separación entre componentes será de 10 puntos.

NOTA 2: Mientras las jarras no hayan sido correctamente inicializadas, no tiene sentido hacer trasvases sobre ellas. Por eso la aplicación tiene dos modos. Modo de inicialización de jarras en as que sólo es posible actuar sobre el botón de iniciar capacidades, y modo trasvase en las que ya es posible los trasvases pero no la inicialización. El botón finalizar nos lleva de nuevo al modo de inicialización de jarras.

La verdad es que no necesitais programa de test más que el que se usó para la otra práctica de jarras; pues la GUI se testea "toqueteandola". Aquí teneis los resultados:

Aquí el main
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class AplicacionJarras {
 public static void main(String[] args) {
  VistaJarras vj = new PanelJarras();
  //Jarras jarraA;
  //Jarras jarraB;
  
  ActionListener ctrJarras = new ControladorJarras(vj);
  vj.controlador(ctrJarras);
  JFrame ventana = new JFrame("Control de Jarras");
  
  ventana.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  ventana.setContentPane((JPanel)vj);
  ventana.pack();
  ventana.setVisible(true);
 }
}


Aquí el Controlador
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


public class ControladorJarras implements ActionListener{

 private Jarras jarraA, jarraB;
 private VistaJarras vistaJarra;
 
 public ControladorJarras(VistaJarras vj) {
  vistaJarra = vj;
  vistaJarra.habilitarInicio(true);
  vistaJarra.ok("Indique las capacidades iniciales");
 }
 
 @Override
 public void actionPerformed(ActionEvent e) {
  // TODO Auto-generated method stub
  
  String comando = e.getActionCommand();
  try{
   if(comando.equals(VistaJarras.INICIAR)) {
    
    vistaJarra.habilitarInicio(false);
    jarraA = new Jarras(vistaJarra.capacidadInicialA());
    jarraB = new Jarras(vistaJarra.capacidadInicialB());
    vistaJarra.capacidadA(jarraA.capacidad());
    vistaJarra.capacidadB(jarraB.capacidad());
    vistaJarra.ok("Jarras creadas con éxito");
   } else if(comando.equals(VistaJarras.LLENAR_A)) {
    
    jarraA.llena();
    vistaJarra.contenidoA(jarraA.cantidad());
    vistaJarra.añadirAHistórico("Llenamos la jarra A");
    vistaJarra.ok("Jarra A llena al completo");
   } else if(comando.equals(VistaJarras.LLENAR_B)) {
    
    jarraB.llena();
    vistaJarra.contenidoB(jarraB.cantidad());
    vistaJarra.añadirAHistórico("Llenamos la jarra B");
    vistaJarra.ok("Jarra B llena al completo");
   } else if (comando.equals(VistaJarras.VACIAR_A)){
    jarraA.vacia();
    vistaJarra.contenidoA(jarraA.cantidad());
    vistaJarra.añadirAHistórico("Vaciamos la jarra A");
    vistaJarra.ok("Jarra A vacía");
   } else if(comando.equals(VistaJarras.VACIAR_B)) {
    jarraB.vacia();
    vistaJarra.contenidoB(jarraB.cantidad());
    vistaJarra.añadirAHistórico("Vaciamos la jarra B");
    vistaJarra.ok("Jarra B vacía");
   } else if(comando.equals(VistaJarras.VOLCAR_A_EN_B)) {
    jarraB.llenaDesde(jarraA);
    vistaJarra.contenidoB(jarraB.cantidad());
    vistaJarra.contenidoA(jarraA.cantidad());
    vistaJarra.añadirAHistórico("Volcamos el contenido de la Jarra A en la Jarra B");
    vistaJarra.ok("Jarra A vaciada en Jarra B");
   } else if(comando.equals(VistaJarras.VOLCAR_B_EN_A)) {
    jarraA.llenaDesde(jarraB);
    vistaJarra.contenidoA(jarraA.cantidad());
    vistaJarra.contenidoB(jarraB.cantidad());
    vistaJarra.añadirAHistórico("Volcamos el contenido de la Jarra B en la Jarra A");
    vistaJarra.ok("Jarra B vaciada en Jarra A");
   } else if(comando.equals(VistaJarras.FINALIZAR)) {
    vistaJarra.limpiar();
    vistaJarra.habilitarInicio(true);
    vistaJarra.ok("Indique las capacidades iniciales");
    jarraA = null;
    jarraB = null;
    
   }
  } catch (NumberFormatException e1) {
   vistaJarra.error("No ha introducido un valor numérico");
  } catch (RuntimeException e2) {
   vistaJarra.error("Se ha producido un error");
  }
 }

}


Y aquí el panel
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionListener;

import javax.swing.*;


public class PanelJarras extends JPanel implements VistaJarras{
 private static final long serialVersionUID = 1L;
 private JButton botonIniciar, botonLlenarA, botonLlenarB, botonVaciarA, botonVaciarB, botonVolcarAenB, botonVolcarBenA, botonFinalizar;
 private JLabel etiquetaJarraA, etiquetaJarraB, etiquetaInformacion, etiquetaContenidoA, etiquetaContenidoB, etiquetaCapacidadA, etiquetaCapacidadB;
 private JTextArea textoCapacidadInicialA, textoCapacidadInicialB, textoAreaHistorico, textoCapacidadA, textoCapacidadB, textoContenidoA, 
   textoContenidoB;
 private ImageIcon der, izq;
 
 public PanelJarras() {
  der = new ImageIcon("next.jpg");
  izq = new ImageIcon("previous.jpg");
  
  botonIniciar = new JButton("Iniciar");
  botonLlenarA = new JButton("Llenar");
  botonLlenarB = new JButton("Llenar");
  botonVaciarA = new JButton("Vaciar");
  botonVaciarB = new JButton("Vaciar");
  botonVolcarAenB = new JButton(der);
  botonVolcarBenA = new JButton(izq);
  botonFinalizar = new JButton("Finalizar");
  
  etiquetaJarraA = new JLabel("Jarra A: ");
  etiquetaJarraB = new JLabel("Jarra B: ");
  etiquetaInformacion = new JLabel(" ");
  etiquetaContenidoA = new JLabel("Contenido");
  etiquetaCapacidadA = new JLabel("Capacidad");
  etiquetaContenidoB = new JLabel("Contenido");
  etiquetaCapacidadB = new JLabel("Capacidad");
  
  textoCapacidadInicialA = new JTextArea();
  textoCapacidadInicialB = new JTextArea();
  textoCapacidadA = new JTextArea();
  textoCapacidadB = new JTextArea();
  textoContenidoA = new JTextArea();
  textoContenidoB = new JTextArea();
  textoAreaHistorico = new JTextArea();
  textoContenidoA.append("0");
  textoContenidoB.append("0");
  textoContenidoA.setEditable(false);
 // textoContenidoB.setEditable(false);
  textoCapacidadA.setEditable(false);
  textoCapacidadB.setEditable(false);
  
  //Paneles previos a los de inicio
  JPanel panelInicA = new JPanel();
  panelInicA.setLayout(new GridLayout(1, 2));
  panelInicA.add(etiquetaJarraA);
  panelInicA.add(textoCapacidadInicialA);
  
  JPanel panelInicB = new JPanel();
  panelInicB.setLayout(new GridLayout(1, 2));
  panelInicB.add(etiquetaJarraB);
  panelInicB.add(textoCapacidadInicialB);
  
  
  //Panel de inicio
  JPanel panelInic = new JPanel();
  panelInic.setLayout(new GridLayout(1, 3));
  panelInic.add(panelInicA);
  panelInic.add(botonIniciar);
  panelInic.add(panelInicB);
  
  
  //Paneles previos a los de las Jarra
  JPanel panelContPrevA = new JPanel();
  panelContPrevA.setLayout(new GridLayout(1, 2));
  panelContPrevA.add(etiquetaContenidoA);
  panelContPrevA.add(textoContenidoA);
    
  JPanel panelContPrevB = new JPanel();
  panelContPrevB.setLayout(new GridLayout(1, 2));
  panelContPrevB.add(etiquetaContenidoB);
  panelContPrevB.add(textoContenidoB);
  
  JPanel panelCapPrevA = new JPanel();
  panelCapPrevA.setLayout(new GridLayout(1, 2));
  panelCapPrevA.add(etiquetaCapacidadA);
  panelCapPrevA.add(textoCapacidadA);
    
  JPanel panelCapPrevB = new JPanel();
  panelCapPrevB.setLayout(new GridLayout(1, 2));
  panelCapPrevB.add(etiquetaCapacidadB);
  panelCapPrevB.add(textoCapacidadB);
    
    
  //Panel de la Jarra A
  JPanel panelJarraA = new JPanel();
  panelJarraA.setLayout(new GridLayout(4, 1, 5, 5));
  panelJarraA.add(botonLlenarA);
  panelJarraA.add(panelContPrevA);
  panelJarraA.add(panelCapPrevA);
  panelJarraA.add(botonVaciarA);
  
  //Panel de la Jarra B
  JPanel panelJarraB = new JPanel();
  panelJarraB.setLayout(new GridLayout(4, 1, 5, 5));
  panelJarraB.add(botonLlenarB);
  panelJarraB.add(panelContPrevB);
  panelJarraB.add(panelCapPrevB);
  panelJarraB.add(botonVaciarB);
  
  //Panel central
  JPanel panelCentro = new JPanel();
  panelCentro.setLayout(new GridLayout(3, 1));
  panelCentro.add(botonVolcarAenB);
  panelCentro.add(botonVolcarBenA);
  panelCentro.add(botonFinalizar);
  
  //Panel de comandos
  JPanel panelComand = new JPanel();
  panelComand.setLayout(new GridLayout(1, 3));
  panelComand.add(panelJarraA);
  panelComand.add(panelCentro);
  panelComand.add(panelJarraB);
  
  //mitad de arriba
  JPanel panelArriba = new JPanel();
  panelArriba.setLayout(new GridLayout(2, 1));
  panelArriba.add(panelInic);
  panelArriba.add(panelComand);
  
  //mitad de Abajo
  JPanel panelAbajo = new JPanel();
  panelAbajo.setLayout(new GridLayout(2, 1));
  panelAbajo.add(textoAreaHistorico);
  panelAbajo.add(etiquetaInformacion);
  
  setLayout(new GridLayout(2, 1));
  add(panelArriba, BorderLayout.NORTH);
  add(panelAbajo, BorderLayout.SOUTH);
  
 }
 
 @Override
 public void controlador(ActionListener ctr) {
  // TODO Auto-generated method stub
  botonIniciar.addActionListener(ctr);
  botonLlenarA.addActionListener(ctr);
  botonLlenarB.addActionListener(ctr);
  botonVaciarA.addActionListener(ctr);
  botonVaciarB.addActionListener(ctr);
  botonVolcarAenB.addActionListener(ctr);
  botonVolcarBenA.addActionListener(ctr);
  botonFinalizar.addActionListener(ctr);
  
  botonIniciar.setActionCommand(VistaJarras.INICIAR);
  botonLlenarA.setActionCommand(VistaJarras.LLENAR_A);
  botonLlenarB.setActionCommand(VistaJarras.LLENAR_B);
  botonVaciarA.setActionCommand(VistaJarras.VACIAR_A);
  botonVaciarB.setActionCommand(VistaJarras.VACIAR_B);
  botonVolcarAenB.setActionCommand(VistaJarras.VOLCAR_A_EN_B);
  botonVolcarBenA.setActionCommand(VistaJarras.VOLCAR_B_EN_A);
  botonFinalizar.setActionCommand(VistaJarras.FINALIZAR);
  
 
  // ....................................................................................................
  
 }

 @Override
 public int capacidadInicialA() {
  return Integer.parseInt(textoCapacidadInicialA.getText());
 }

 @Override
 public int capacidadInicialB() {
  return Integer.parseInt(textoCapacidadInicialB.getText());
 }

 @Override
 public void error(String mensaje) {
  // TODO Auto-generated method stub
  etiquetaInformacion.setForeground(Color.RED);
  etiquetaInformacion.setText(mensaje);
  
 }

 @Override
 public void ok(String mensaje) {
  // TODO Auto-generated method stub
  etiquetaInformacion.setForeground(Color.BLUE);
  etiquetaInformacion.setText(mensaje);
  
 }

 @Override
 public void habilitarInicio(boolean b) {
  // TODO Auto-generated method stub
  etiquetaJarraA.setEnabled(b);
  etiquetaJarraB.setEnabled(b);
  botonIniciar.setEnabled(b);
  textoCapacidadInicialA.setEditable(b);
  textoCapacidadInicialB.setEditable(b);
  
  botonLlenarA.setEnabled(!b);
  botonLlenarB.setEnabled(!b);
  botonVaciarA.setEnabled(!b);
  botonVaciarB.setEnabled(!b);
  botonFinalizar.setEnabled(!b);
  botonVolcarAenB.setEnabled(!b);
  botonVolcarBenA.setEnabled(!b);
  etiquetaContenidoA.setEnabled(!b);
  etiquetaContenidoB.setEnabled(!b);
  etiquetaCapacidadA.setEnabled(!b);
  etiquetaCapacidadB.setEnabled(!b);
   
  
 }

 @Override
 public void capacidadA(int c) {
  // TODO Auto-generated method stub

  textoCapacidadA.setText(" " +c);
 }

 @Override
 public void capacidadB(int c) {
  // TODO Auto-generated method stub

  textoCapacidadB.setText(" " +c);
 }

 @Override
 public void contenidoA(int c) {
  // TODO Auto-generated method stub
  textoContenidoA.setText(" " +c);
  
 }

 @Override
 public void contenidoB(int c) {
  // TODO Auto-generated method stub
  textoContenidoB.setText(" " +c);
  
 }

 @Override
 public void añadirAHistórico(String mensaje) {
  // TODO Auto-generated method stub
  textoAreaHistorico.append(mensaje + "\n");
  
 }

 @Override
 public void limpiar() {
  // TODO Auto-generated method stub
  textoAreaHistorico.setText(" ");
  textoCapacidadA.setText(" ");
  textoCapacidadB.setText(" ");
  textoContenidoA.setText(" ");
  textoContenidoB.setText(" ");
  
 }

}


Espero que os esté pareciendo, cuanto menos, interesante este blog. A ver si puedo subir continuamente esta semanilla, pues me voy a un congreso en Gijón y voy a estar liadillo :p

Saludos y a seguir aprendiendo ;)

2 comentarios:

  1. Me ha servido de mucha ayuda porque no tenia la clase principal, y aunque crearla es fácil, no se como me las arreglé para que me diera un fallo.

    Yo lo tengo escrito de forma alternativa a ustedes y que controla más posibles fallos. Si la queréis os la envío.

    Un Saludo

    ResponderEliminar
    Respuestas
    1. Buenas. Si quieres, envíanos el code a aprendiendoaprogramarentretodo@gmail.com y hacemos los cambios que veamos oportunos (Nombrándote, claro está).

      De todos modos te explico que al ser unas prácticas tan básicas no hemos querido ofuscar mucho el código controlando cada posible excepción.

      Saludos ;)

      Eliminar