/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package practica1.ui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import practica1.actions.*;
import practica1.controller.Controller;
import practica1.controller.adapter.ControllerExperimentoAdapter;
import practica1.controller.adapter.ControllerPoblacionAdapter;
import practica1.controller.event.ControllerExperimentoEvent;
import practica1.controller.event.ControllerListenerEvent;
import practica1.controller.event.ControllerPoblacionEvent;
import practica1.controller.listener.ControllerListener;
import practica1.language.Language;
import practica1.language.LanguageEvent;
import practica1.language.LanguageListener;
import practica1.logic.LogicExperimento;
import practica1.logic.LogicPoblacion;
/**
* Componente que representa el panel donde se visualizan los experimentos
* y sus poblaciones en un JTree
* @author Miguel González - Ceura
*/
public class PanelExperimentos extends JPanel implements LanguageListener {
private JTree arbolExperimentos;
private DefaultTreeModel modeloArbol;
private DefaultMutableTreeNode padreArbol;
private JPopupMenu popupMenuExperimentos;
private JPopupMenu popupMenuExperimento;
private JPopupMenu popupMenuPoblacion;
private Controller controlador;
/**
* Constructor por defecto del panel
*/
public PanelExperimentos() {
controlador = Controller.getInstance();
controlador.addControllerListener(new EscuchadorControllador());
controlador.addControllerExperimentoListener(
new EscuchadorExperimentos());
controlador.addControllerPoblacionListener(
new EscuchadorPoblaciones());
Language.getI().addLanguageListener(this);
popupMenuExperimentos = new JPopupMenu();
popupMenuExperimentos.add(new ActionAbrir());
popupMenuExperimentos.add(new ActionNuevoExperimento());
popupMenuExperimentos.setOpaque(true);
popupMenuExperimento = new JPopupMenu();
popupMenuExperimento.add(new ActionNuevaPoblacion());
popupMenuExperimento.add(new ActionGuardar());
popupMenuExperimento.add(new ActionGuardarComo());
popupMenuExperimento.add(new ActionMainExperimento());
popupMenuExperimento.add(new ActionPropiedades());
popupMenuExperimento.add(new ActionCerrar());
popupMenuExperimento.setOpaque(true);
popupMenuPoblacion = new JPopupMenu();
popupMenuPoblacion.add(new ActionCerrarPoblacion());
popupMenuPoblacion.add(new ActionBorrarPoblacion());
popupMenuPoblacion.add(new ActionPropiedadesPoblacion());
popupMenuPoblacion.setOpaque(true);
padreArbol = new DefaultMutableTreeNode(
Language.getI().getP("EXPERIMENTOS"));
modeloArbol = new DefaultTreeModel(padreArbol);
arbolExperimentos = new JTree(modeloArbol);
arbolExperimentos.setCellRenderer(new TreeCellRendererComponent());
arbolExperimentos.setShowsRootHandles(true);
arbolExperimentos.getSelectionModel().setSelectionMode
(TreeSelectionModel.SINGLE_TREE_SELECTION);
//Listen for when the selection changes.
arbolExperimentos.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
//Obtenemos el nodo seleccionado
TreePath ramaNodoSeleccionado =
arbolExperimentos.getSelectionPath();
if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) {
//Comprobamos que tipo de nodo es
if(ramaNodoSeleccionado != null &&
ramaNodoSeleccionado.getPath().length == 2) {
//Es un experimento
String nombreExperimento = ramaNodoSeleccionado.toString();
} else if(ramaNodoSeleccionado != null &&
ramaNodoSeleccionado.getPath().length == 3) {
//Es una población
String nombrePoblacion = ramaNodoSeleccionado.toString();
String nombreExperimento = ramaNodoSeleccionado.
getPath()[1].toString();
LogicPoblacion poblacion = ((LogicPoblacion)
((DefaultMutableTreeNode)
ramaNodoSeleccionado.getPath()[2])
.getUserObject());
//Abrimos la población
controlador.abrirPoblacion(poblacion);
}
} else if(e.getClickCount() == 1 &&
e.getButton() == MouseEvent.BUTTON3) {
try {
//Con el botón derecho tenemos que seleccionar el nodo manualmente
int row = arbolExperimentos.getRowForLocation(
e.getX(), e.getY());
arbolExperimentos.addSelectionRow(row);
//Volvemos a pedir el nodo seleccionado
ramaNodoSeleccionado =
arbolExperimentos.getSelectionPath();
//Comprobamos que tipo de nodo es
if(ramaNodoSeleccionado.getPath().length == 1) {
//Si es la raíz experimentos
popupMenuExperimentos.show((JComponent)e.getSource(),
e.getX(), e.getY());
} else if(ramaNodoSeleccionado.getPath().length == 2) {
//Si es un experimento
controlador.setExperimentoSeleccionado((LogicExperimento)
((DefaultMutableTreeNode)
ramaNodoSeleccionado.getPath()[1])
.getUserObject());
popupMenuExperimento.show((JComponent)e.getSource(),
e.getX(), e.getY());
} else if(ramaNodoSeleccionado.getPath().length == 3) {
//Es una población
String nombrePoblacion = ramaNodoSeleccionado.toString();
String nombreExperimento = ramaNodoSeleccionado.
getPath()[1].toString();
LogicExperimento experimento = ((LogicExperimento)
((DefaultMutableTreeNode)
ramaNodoSeleccionado.getPath()[1])
.getUserObject());
LogicPoblacion poblacion = ((LogicPoblacion)
((DefaultMutableTreeNode)
ramaNodoSeleccionado.getPath()[2])
.getUserObject());
controlador.setExperimentoSeleccionado(experimento);
controlador.setPoblacionSeleccionada(poblacion);
popupMenuPoblacion.show((JComponent)e.getSource(),
e.getX(), e.getY());
}
} catch(Exception ex) {
//No hacemos nada, error dado porque no se ha pinchado
//en un nodo y falla el getRowForLocation
}
}
}
@Override public void mousePressed(MouseEvent e) {}
@Override public void mouseReleased(MouseEvent e) {}
@Override public void mouseEntered(MouseEvent e) {}
@Override public void mouseExited(MouseEvent e) {}
});
initComponents();
}
/**
* Inicializa los componentes Swing
*/
private void initComponents() {
setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
setLayout(new BorderLayout());
JScrollPane scrollPane = new JScrollPane(arbolExperimentos);
add(scrollPane, BorderLayout.CENTER);
for(LogicExperimento exp : controlador.getExperimentosAbiertos()) {
aniadirExperimento(exp);
}
}
/**
* Método que añade los experimentos y sus poblaciones al JTree
* @param exp LogicExperimento a añadir
*/
private void aniadirExperimento(LogicExperimento exp) {
DefaultMutableTreeNode nodoExperimento = new DefaultMutableTreeNode(exp);
ArrayList<LogicPoblacion> poblaciones = exp.getPoblaciones();
//Añadimos las poblaciones
for(LogicPoblacion poblacion : poblaciones) {
DefaultMutableTreeNode nodoPoblacion = new
DefaultMutableTreeNode(poblacion);
nodoExperimento.add(nodoPoblacion);
}
modeloArbol.insertNodeInto(nodoExperimento, padreArbol,
modeloArbol.getChildCount(padreArbol));
//Mostramos la nueva rama
arbolExperimentos.scrollPathToVisible(new TreePath(
nodoExperimento.getPath()));
}
/**
* Método que escucha cuando un experimento es modificado y repinta
* el JTree por si su nombre ha cambiado
*/
private class EscuchadorControllador implements ControllerListener {
@Override
public void experimentoPrincipalChange(ControllerListenerEvent event) {
arbolExperimentos.repaint();
}
}
/**
* Clase que escucha los cambios en los experimentos por el controlador
*/
private class EscuchadorExperimentos extends ControllerExperimentoAdapter {
/**
* Método que es llamado cuando se añade un nuevo experimento
* @param event ControllerExperimentoEvent
*/
@Override
public void addedExperimento(ControllerExperimentoEvent event) {
aniadirExperimento(event.getExperimento());
}
/**
* Método que es llamado cuando se quita un experimento
* @param event ControllerExperimentoEvent
*/
@Override
public void removedExperimento(ControllerExperimentoEvent event) {
boolean removed = false;
//Recorremos el árbol buscando el experimento a borrar
for(int i=0; i<arbolExperimentos.getRowCount() && !removed; i++) {
TreePath pathExp = arbolExperimentos.getPathForRow(i);
//Si el path es de dos niveles es un experimento
//Primer nivel es root
//Segundo nivel el path del experimento
if(pathExp.getPath().length == 2) {
LogicExperimento ex = (LogicExperimento)
((DefaultMutableTreeNode)pathExp.getPath()[1])
.getUserObject();
if(ex.equals(event.getExperimento())) {
padreArbol.remove(i - 1);
modeloArbol.reload();
removed = true;
}
}
}
}
}
/**
* Clase que escucha los cambios en las poblaciones
*/
private class EscuchadorPoblaciones extends ControllerPoblacionAdapter {
/**
* Método que es llamado al añadirse una población a un experimento
* @param event
*/
@Override
public void addedPoblacion(ControllerPoblacionEvent event) {
LogicPoblacion poblacion = event.getPoblacion();
//Actualizamos el jtree con la nueva población
DefaultMutableTreeNode nodoPoblacion = new DefaultMutableTreeNode(
poblacion);
//Buscamos el padre
boolean enc = false;
for(int i=0; i<modeloArbol.getChildCount(padreArbol) && !enc; i++) {
//Obtenemos el modelo de experimento de la rama actual del JTree
LogicExperimento experimento = ((LogicExperimento)
((DefaultMutableTreeNode)modeloArbol
.getChild(padreArbol, i)).getUserObject());
//Si el experimento de la población
if(experimento.equals(poblacion.getExperimentoPadre())) {
//Insertamos la población como hoja del experimento
modeloArbol.insertNodeInto
(nodoPoblacion, (DefaultMutableTreeNode)modeloArbol
.getChild(padreArbol, i),
modeloArbol.getChildCount(
(DefaultMutableTreeNode)modeloArbol
.getChild(padreArbol, i)));
enc = true;
}
}
//Mostramos la nueva rama
arbolExperimentos.setSelectionPath(new TreePath(
nodoPoblacion.getPath()));
arbolExperimentos.scrollPathToVisible(new TreePath(
nodoPoblacion.getPath()));
}
/**
* Método que es llamado al quitarse una población de un experimento
* @param event ControllerPoblacionEvent
*/
@Override
public void removedPoblacion(ControllerPoblacionEvent event) {
boolean removed = false;
//Recorremos el árbol buscando el experimento a borrar
for(int i=0; i<arbolExperimentos.getRowCount() && !removed; i++) {
TreePath pathExp = arbolExperimentos.getPathForRow(i);
//Si el path es de dos niveles es un experimento
//Primer nivel es root
//Segundo nivel el path del experimento
//Tercer nivel el path de poblacion
if(pathExp.getPath().length == 3) {
LogicPoblacion po = (LogicPoblacion)
((DefaultMutableTreeNode)pathExp.getPath()[2])
.getUserObject();
if(po.equals(event.getPoblacion())) {
((DefaultMutableTreeNode)pathExp.getPath()[1]).remove(
((DefaultMutableTreeNode)pathExp.getPath()[2]));
modeloArbol.reload();
removed = true;
}
}
}
}
/**
* Método que es llamado al modificarse una población, repintamos el
* JTree por si su nombre ha cambiado
* @param event
*/
@Override
public void modifiedPoblacion(ControllerPoblacionEvent event) {
arbolExperimentos.repaint();
}
}
/**
* Método que es llamado cuando el idioma cambia
* @param evt LanguageEvent
*/
@Override
public void idiomaChange(LanguageEvent evt) {
padreArbol.setUserObject(Language.getI().getP("EXPERIMENTOS"));
arbolExperimentos.repaint();
}
}