/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package es.miguelgonzalez.jgraficacomida;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.Serializable;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* Componente para editar la alimentación de una población a través de
* unos textbox o de una gráfica.
* @author Miguel González - Ceura
*/
public final class JGraficaComida extends JPanel implements
GraficaComidaChangeEventListener, Serializable {
public static final int IDIOMA_E = 1;
public static final int IDIOMA_I = 2;
//Modelo de datos de la poblacion
private JGraficaComidaModel modeloPoblacion;
//Objetos gráficos para pintar el componente
private JTextField txtAlimentoInicial;
private JTextField txtDiaMaximo;
private JTextField txtAlimentoMaximo;
private JTextField txtAlimentoFinal;
private JLabel lblAlimentoInicial;
private JLabel lblDiaAlimentoMaximo;
private JLabel lblAlimentoMaximo;
private JLabel lblAlimentoFinal;
private JGraficaComidaDibujo grafica;
/**
* Constructor por defecto del componente. Inicializa la población a
* valores por defecto: alimentoInicial = 150, diaMax = 15,
* alimentoMax = 150, alimentoFinal = 150
*/
public JGraficaComida() {
//Por defecto el modelo de la población es nulo
modeloPoblacion = null;
//Inicializamos el componente
initPoblacion();
}
/**
* Constructor del componente
* @param modeloPoblacion Recibe un modelo de la población
*/
public JGraficaComida(JGraficaComidaModel modeloPoblacion) {
//Establecemos el modelo recibido como parámetro como nuestro modelo
this.modeloPoblacion = modeloPoblacion;
//Inicializamos el componente
initPoblacion();
}
/**
* Establece el idioma del componente
* @param tipoIdioma IDIOMA_E o IDIOMA_I
*/
public void cambiarIdioma(int tipoIdioma) {
if(tipoIdioma == IDIOMA_E) {
lblAlimentoInicial.setText("Alimento inicial: ");
lblDiaAlimentoMaximo.setText("Día de alimento máximo: ");
lblAlimentoMaximo.setText("Alimento máximo: ");
lblAlimentoFinal.setText("Alimento final: ");
} else if(tipoIdioma == IDIOMA_I) {
lblAlimentoInicial.setText("Initial food: ");
lblDiaAlimentoMaximo.setText("Day of maximum feeding: ");
lblAlimentoMaximo.setText("Maximun feeding: ");
lblAlimentoFinal.setText("Final feeding: ");
}
}
/**
* Devuelve el modelo de la población del componente
* @return Modelo de la población
*/
public JGraficaComidaModel getModeloPoblacion() {
return modeloPoblacion;
}
/**
* Establece un nuevo modelo de la población en el componente
* @param modeloPoblacion Nuevo modelo de la población
*/
public void setModeloPoblacion(JGraficaComidaModel modeloPoblacion) {
this.modeloPoblacion = modeloPoblacion;
//Nos quitamos de la escucha del antiguo modelo
modeloPoblacion.removeChangeEventListener(this);
//Nos añadimos a la escucha del nuevo modelo
modeloPoblacion.addChangeEventListener(this);
grafica.setModelExperimento(modeloPoblacion);
}
/**
* Inicializa el componente
*/
private void initPoblacion() {
if(modeloPoblacion == null) {
//Si no recibe un modelo de la población lo creamos
modeloPoblacion = new JGraficaComidaModel();
}
//Nos añadimos a la escucha del modelo de datos
modeloPoblacion.addChangeEventListener(this);
//Inicializamos los componentes Swing
grafica = new JGraficaComidaDibujo(modeloPoblacion);
lblAlimentoInicial = new JLabel("Alimento inicial: ", JLabel.TRAILING);
txtAlimentoInicial = new JTextField(3);
lblAlimentoInicial.setLabelFor(txtAlimentoInicial);
lblDiaAlimentoMaximo = new JLabel("Día de alimento máximo: ",
JLabel.TRAILING);
txtDiaMaximo = new JTextField(5);
lblDiaAlimentoMaximo.setLabelFor(txtDiaMaximo);
lblAlimentoMaximo = new JLabel("Alimento máximo: ", JLabel.TRAILING);
txtAlimentoMaximo = new JTextField(5);
lblAlimentoMaximo.setLabelFor(txtAlimentoMaximo);
lblAlimentoFinal = new JLabel("Alimento final: ", JLabel.TRAILING);
txtAlimentoFinal = new JTextField(5);
lblAlimentoFinal.setLabelFor(txtAlimentoFinal);
//Inicializamos el panel
setLayout(new BorderLayout());
JPanel panelIzq = new JPanel();
panelIzq.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.ipadx = 10;
c.gridx = 0;
c.gridy = 0;
panelIzq.add(lblAlimentoInicial, c);
c.gridx = 1;
c.gridy = 0;
panelIzq.add(txtAlimentoInicial, c);
c.gridx = 0;
c.gridy = 1;
panelIzq.add(lblDiaAlimentoMaximo, c);
c.gridx = 1;
c.gridy = 1;
panelIzq.add(txtDiaMaximo, c);
c.gridx = 0;
c.gridy = 2;
panelIzq.add(lblAlimentoMaximo, c);
c.gridx = 1;
c.gridy = 2;
panelIzq.add(txtAlimentoMaximo, c);
c.gridx = 0;
c.gridy = 3;
panelIzq.add(lblAlimentoFinal, c);
c.gridx = 1;
c.gridy = 3;
panelIzq.add(txtAlimentoFinal, c);
//Inicializamos los textos
txtAlimentoInicial.setText(Integer.toString(
modeloPoblacion.getAlimentoInicial()));
txtDiaMaximo.setText(Integer.toString(
modeloPoblacion.getDiaMax()));
txtAlimentoMaximo.setText(Integer.toString(
modeloPoblacion.getAlimentoMax()));
txtAlimentoFinal.setText(Integer.toString(
modeloPoblacion.getAlimentoFinal()));
//Añadimos los paneles
add(panelIzq, BorderLayout.WEST);
JPanel panelGrafica = new JPanel();
panelGrafica.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
panelGrafica.setLayout(new BorderLayout());
panelGrafica.add(grafica, BorderLayout.CENTER);
add(panelGrafica, BorderLayout.CENTER);
initListeners();
}
/**
* Inicializa los listeners
*/
private void initListeners() {
txtAlimentoInicial.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
actualizarAlimentoInicial();
}
});
txtAlimentoInicial.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
actualizarAlimentoInicial();
}
});
txtDiaMaximo.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
actualizarDiaMaximo();
}
});
txtDiaMaximo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
actualizarDiaMaximo();
}
});
txtAlimentoMaximo.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {}
@Override
public void focusLost(FocusEvent e) {
actualizarAlimentoMaximo();
}
});
txtAlimentoMaximo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
actualizarAlimentoMaximo();
}
});
txtAlimentoFinal.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {}
@Override
public void focusLost(FocusEvent e) {
actualizarAlimentoFinal();
}
});
txtAlimentoFinal.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
actualizarAlimentoFinal();
}
});
}
/**
* Actualiza la alimentación inicial en el modelo
*/
private void actualizarAlimentoInicial() {
//Se resetea el color de fondo por si había un error
lblAlimentoInicial.setForeground(Color.BLACK);
//Si al perder el foco se detecta que se ha cambiado el alimento
if(Integer.parseInt(txtAlimentoInicial.getText())
!= modeloPoblacion.getAlimentoInicial()) {
try {
modeloPoblacion.setAlimentoInicial(Integer.parseInt(
txtAlimentoInicial.getText()));
} catch (GraficaComidaIncorrectValueException ex) {
//Se pone en rojo el textbox
lblAlimentoInicial.setForeground(Color.RED);
}
}
}
/**
* Actualiza el día máximo en el modelo
*/
private void actualizarDiaMaximo() {
//Se resetea el color de fondo por si había un error
lblDiaAlimentoMaximo.setForeground(Color.BLACK);
//Si al perder el foco se detecta que se ha cambiado el alimento
if(Integer.parseInt(txtDiaMaximo.getText())
!= modeloPoblacion.getDiaMax()) {
try {
modeloPoblacion.setDiaMax(Integer.parseInt(
txtDiaMaximo.getText()));
} catch (GraficaComidaIncorrectValueException ex) {
//Se pone en rojo el textbox
lblDiaAlimentoMaximo.setForeground(Color.RED);
}
}
}
/**
* Actualiza el alimento máximo en el modelo
*/
private void actualizarAlimentoMaximo() {
//Se resetea el color de fondo por si había un error
lblAlimentoMaximo.setForeground(Color.BLACK);
//Si al perder el foco se detecta que se ha cambiado el alimento
if(Integer.parseInt(txtAlimentoMaximo.getText())
!= modeloPoblacion.getAlimentoMax()) {
try {
modeloPoblacion.setAlimentoMax(Integer.parseInt(
txtAlimentoMaximo.getText()));
} catch (GraficaComidaIncorrectValueException ex) {
//Se pone en rojo el textbox
lblAlimentoMaximo.setForeground(Color.RED);
}
}
}
/**
* Actualiza el alimento final en el modelo
*/
private void actualizarAlimentoFinal() {
//Se resetea el color de fondo por si había un error
lblAlimentoFinal.setForeground(Color.BLACK);
//Si al perder el foco se detecta que se ha cambiado el alimento
if(Integer.parseInt(txtAlimentoFinal.getText())
!= modeloPoblacion.getAlimentoFinal()) {
try {
modeloPoblacion.setAlimentoFinal(Integer.parseInt(
txtAlimentoFinal.getText()));
} catch (GraficaComidaIncorrectValueException ex) {
//Se pone en rojo el textbox
lblAlimentoFinal.setForeground(Color.RED);
}
}
}
/**
* Método que dispara los cambios en el modelo a todos los listeners
* que se han suscrito a la escucha de los cambios
* @param ev Cambio producido
*/
@Override
public void fireChangeEvent(GraficaComidaChangeEvent ev) {
//Actualizamos los JTextFields según la propiedad que ha cambiado
if(ev.getPropertyName().equals(GraficaComidaChangeEvent.ALIMENTO_INICIAL)) {
lblAlimentoInicial.setForeground(Color.BLACK);
txtAlimentoInicial.setText(Integer.toString(ev.getNewValue()));
} else if(ev.getPropertyName().equals(GraficaComidaChangeEvent.DIA_MAX)) {
lblDiaAlimentoMaximo.setForeground(Color.BLACK);
txtDiaMaximo.setText(Integer.toString(ev.getNewValue()));
} else if(ev.getPropertyName().equals(GraficaComidaChangeEvent.ALIMENTO_MAX)) {
lblAlimentoMaximo.setForeground(Color.BLACK);
txtAlimentoMaximo.setText(Integer.toString(ev.getNewValue()));
} else if(ev.getPropertyName().equals(GraficaComidaChangeEvent.ALIMENTO_FINAL)) {
lblAlimentoFinal.setForeground(Color.BLACK);
txtAlimentoFinal.setText(Integer.toString(ev.getNewValue()));
}
}
}