/**
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* $Id: InterfazCadenasAdn.java,v 1.15 2006/12/10 20:17:57 da-romer Exp $
* Universidad de los Andes (Bogotá - Colombia)
* Departamento de Ingeniería de Sistemas y Computación
* Licenciado bajo el esquema Academic Free License version 2.1
*
* Proyecto Cupi2 (http://cupi2.uniandes.edu.co)
* Ejercicio: n9_cadenasAdn
* Autor: Mario Sánchez - 26-may-2006
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
package uniandes.cupi2.cadenasAdn.interfaz;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.border.TitledBorder;
import uniandes.cupi2.cadenasAdn.mundo.CadenaIncorrectaExcepcion;
import uniandes.cupi2.cadenasAdn.mundo.BaseNitrogenada;
import uniandes.cupi2.cadenasAdn.mundo.Cadena;
import uniandes.cupi2.cadenasAdn.mundo.CadenaNoExisteExcepcion;
import uniandes.cupi2.cadenasAdn.mundo.CadenaRepetidaException;
import uniandes.cupi2.cadenasAdn.mundo.ProcesadorAdn;
/**
* Esta es la ventana principal de la aplicación.
*/
public class InterfazCadenasAdn extends JFrame
{
// -----------------------------------------------------------------
// Atributos
// -----------------------------------------------------------------
/**
* Clase principal del mundo
*/
private ProcesadorAdn procesadorAdn;
/**
* El último directorio de donde se cargó un archivo
*/
private File ultimoDirectorio;
/**
* Es una lista con las descripciones de las cadenas mostradas actualmente
*/
private ArrayList cadenasMostradas;
// -----------------------------------------------------------------
// Atributos de la interfaz
// -----------------------------------------------------------------
/**
* Es el panel donde se muestran las imágenes de las cadenas
*/
private PanelImagenCadenas panelImagenCadenas;
/**
* Es el panel donde se muestra la lista de cadenas disponibles
*/
private PanelListaCadenas panelLista;
/**
* Es el panel donde se muestran los botones que controlan la aplicación
*/
private PanelBotones panelBotones;
/**
* Panel con las extensiones
*/
private PanelExtension panelExtension;
/**
* Panel con una imagen decorativa
*/
private PanelImagen panelImagen;
// -----------------------------------------------------------------
// Constructores
// -----------------------------------------------------------------
/**
* Construye la ventana principal <br>
* <b>post: </b> Se construyó la ventana principal de la aplicación
*/
public InterfazCadenasAdn( )
{
// Crea la clase principal
procesadorAdn = new ProcesadorAdn( );
ultimoDirectorio = new File( "./data" );
// Construye la forma
setLayout( new BorderLayout( ) );
setSize( 730, 630 );
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
setTitle( "Cadenas de ADN" );
// Creación de los paneles
setLayout( new GridBagLayout( ) );
GridBagConstraints gbc = new GridBagConstraints( 0, 0, 2, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 5, 5, 5, 5 ), 0, 0 );
panelImagen = new PanelImagen( );
add( panelImagen, gbc );
gbc = new GridBagConstraints( 0, 1, 1, 1, 0.5, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 5, 5, 5, 5 ), 0, 0 );
panelImagenCadenas = new PanelImagenCadenas( );
add( panelImagenCadenas, gbc );
gbc = new GridBagConstraints( 1, 1, 1, 2, 0.4, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 5, 5, 5, 5 ), 0, 0 );
panelLista = new PanelListaCadenas( this );
JScrollPane scroll = new JScrollPane( );
scroll.getViewport( ).add( panelLista );
scroll.setBorder( new TitledBorder( "Cadenas" ) );
add( scroll, gbc );
gbc = new GridBagConstraints( 0, 2, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 5, 5, 5, 5 ), 0, 0 );
panelBotones = new PanelBotones( this );
getContentPane( ).add( panelBotones, gbc );
gbc = new GridBagConstraints( 0, 3, 2, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 5, 5, 5, 5 ), 0, 0 );
panelExtension = new PanelExtension( this );
add( panelExtension, gbc );
centrarVentana();
}
// -----------------------------------------------------------------
// Métodos
// -----------------------------------------------------------------
/**
* Centra la ventana en la pantalla
*/
private void centrarVentana( )
{
Dimension dPantalla = Toolkit.getDefaultToolkit( ).getScreenSize( );
Dimension dVentana = getSize( );
int xEsquina = ( dPantalla.width / 2 ) - ( dVentana.width / 2 );
int yEsquina = ( dPantalla.height / 2 ) - ( dVentana.height / 2 );
setLocation( xEsquina, yEsquina );
}
/**
* Actualiza las cadenas mostradas
*/
private void actualizarCadenasMostradas( )
{
ArrayList cadenas = new ArrayList( );
if (cadenasMostradas!=null)
{
for( int i = 0; i < cadenasMostradas.size( ); i++ )
{
String descripcion = ( String )cadenasMostradas.get( i );
Cadena c = procesadorAdn.darCadena( descripcion );
cadenas.add( c );
}
}
panelImagenCadenas.actualizarCadenasMostradas( cadenas );
}
/**
* Cambia las cadenas que son mostradas
* @param descripcionesCadenas Es una lista con las descripciones de las cadenas que se deben mostrar - descripcionesCadenas != null
*/
public void cambiarCadenasMostradas( ArrayList descripcionesCadenas )
{
cadenasMostradas = descripcionesCadenas;
ArrayList cadenas = new ArrayList( );
for( int i = 0; i < descripcionesCadenas.size( ); i++ )
{
String descripcion = ( String )descripcionesCadenas.get( i );
Cadena c = procesadorAdn.darCadena( descripcion );
cadenas.add( c );
}
panelImagenCadenas.actualizarCadenasMostradas( cadenas );
}
/**
* Actualiza la lista de las cadenas
*/
private void actualizarListaCadenas( )
{
ArrayList descripciones = procesadorAdn.darDescripcionesCadenas( );
panelLista.actualizarListaCadenas( descripciones );
validate( );
}
/**
* Este método se encarga de cargar una cadena a partir de un archivo que seleccione el usuario
*/
public void cargarCadena( )
{
JFileChooser fc = new JFileChooser( ultimoDirectorio );
fc.setDialogTitle( "Cargar Cadena ADN" );
int resultado = fc.showOpenDialog( this );
if( resultado == JFileChooser.APPROVE_OPTION )
{
File archivoCadena = fc.getSelectedFile( );
ultimoDirectorio = archivoCadena.getParentFile( );
try
{
procesadorAdn.cargarCadena( archivoCadena );
actualizarListaCadenas( );
}
catch( IOException e )
{
JOptionPane.showMessageDialog( this, "Hubo un error leyendo el archivo:\n" + e.getMessage( ), "Error", JOptionPane.ERROR_MESSAGE );
}
catch( CadenaRepetidaException e )
{
JOptionPane.showMessageDialog( this, "Error cargando el archivo:\n" + e.getMessage( ), "Error", JOptionPane.ERROR_MESSAGE );
}
catch( CadenaIncorrectaExcepcion e )
{
JOptionPane.showMessageDialog( this, "Error cargando el archivo:\n" + e.getMessage( ), "Error", JOptionPane.ERROR_MESSAGE );
}
}
}
/**
* Guarda una de las cadenas
*/
public void guardarCadena( )
{
Cadena cadena = seleccionarCadena( "Guardar Cadena" );
if( cadena != null )
{
JFileChooser fc = new JFileChooser( ultimoDirectorio );
fc.setDialogTitle( "Guardar Cadena ADN" );
int resultado = fc.showSaveDialog( this );
if( resultado == JFileChooser.APPROVE_OPTION )
{
File archivoCadena = fc.getSelectedFile( );
ultimoDirectorio = archivoCadena.getParentFile( );
try
{
procesadorAdn.guardarCadena( archivoCadena, cadena );
actualizarListaCadenas( );
}
catch( IOException e )
{
JOptionPane.showMessageDialog( this, "Hubo un error salvando el archivo:\n" + e.getMessage( ), "Error", JOptionPane.ERROR_MESSAGE );
}
}
}
}
/**
* Busca el fragmento común más largo entre dos cadenas
*/
public void buscarFragmentoComun( )
{
Cadena cadena1 = seleccionarCadena( "Cadena número 1" );
if( cadena1 != null )
{
Cadena cadena2 = seleccionarCadena( "Cadena número 2" );
if( cadena2 != null )
{
try
{
procesadorAdn.buscarSecuenciaComun( cadena1, cadena2 );
actualizarListaCadenas( );
}
catch( CadenaRepetidaException e )
{
JOptionPane.showMessageDialog( this, e.getMessage( ), "Error", JOptionPane.ERROR_MESSAGE );
}
}
}
}
/**
* Elimina un fragmento a una cadena
*/
public void eliminarFragmento( )
{
Cadena cadena1 = seleccionarCadena( "Eliminar Fragmento" );
if( cadena1 != null )
{
String fragmento = JOptionPane.showInputDialog( this, "Escriba la secuencia de bases que será eliminada.\nUse solamente los caracteres A, T, G o C." );
if( fragmento != null )
{
fragmento = fragmento.toUpperCase( ).trim( );
if( fragmento.matches( "[ATGC]*" ) && fragmento.length( ) > 0 )
{
BaseNitrogenada primera = null;
BaseNitrogenada ultima = null;
char[] letrasFragmento = fragmento.toCharArray( );
for( int i = 0; i < letrasFragmento.length; i++ )
{
char letra = letrasFragmento[ i ];
BaseNitrogenada nuevaBase = null;
if( letra == 'A' )
nuevaBase = new BaseNitrogenada( BaseNitrogenada.ADENINA );
else if( letra == 'G' )
nuevaBase = new BaseNitrogenada( BaseNitrogenada.GUANINA );
else if( letra == 'T' )
nuevaBase = new BaseNitrogenada( BaseNitrogenada.TIMINA );
else if( letra == 'C' )
nuevaBase = new BaseNitrogenada( BaseNitrogenada.CITOSINA );
if( primera == null )
{
primera = nuevaBase;
ultima = nuevaBase;
}
else
{
ultima.cambiarSiguiente( nuevaBase );
nuevaBase.cambiarAnterior( ultima );
ultima = nuevaBase;
}
}
try
{
procesadorAdn.eliminarFragmento( cadena1, primera );
actualizarCadenasMostradas( );
}
catch( CadenaNoExisteExcepcion e )
{
JOptionPane.showMessageDialog( this, e.getMessage( ), "Error", JOptionPane.ERROR_MESSAGE );
}
}
else
{
JOptionPane.showMessageDialog( this, "Solamente puede escribir A, T, G o C", "Error", JOptionPane.ERROR_MESSAGE );
}
}
}
}
/**
* Elimina una de las cadenas
*/
public void eliminarCadena( )
{
Cadena cadena = seleccionarCadena( "Eliminar Cadena" );
if( cadena != null )
{
try
{
procesadorAdn.eliminarCadena( cadena.darDescripcion( ) );
boolean encontre = false;
if(cadenasMostradas!=null)
for( int i = 0; i < cadenasMostradas.size( ) && !encontre; i++ )
{
String descripcionMostrada = ( String )cadenasMostradas.get( i );
if( descripcionMostrada.equals( cadena.darDescripcion( ) ) )
{
encontre = true;
cadenasMostradas.remove( descripcionMostrada );
}
}
}
catch( CadenaNoExisteExcepcion e )
{
JOptionPane.showMessageDialog( this, e.getMessage( ), "Error", JOptionPane.ERROR_MESSAGE );
}
}
actualizarListaCadenas( );
actualizarCadenasMostradas( );
}
/**
* Corrige una mutación en una cadena
*/
public void corregirMutacion( )
{
try
{
Cadena cadena1 = seleccionarCadena( "Cadena Mutada" );
if( cadena1 != null )
{
String cadenaMutacion = JOptionPane.showInputDialog( this, "Escriba la secuencia de bases que se sabe es una mutación.\nUse solamente los caracteres A, T, G o C." );
if( cadenaMutacion != null )
{
String cadenaCorreccion = JOptionPane.showInputDialog( this, "Escriba la secuencia de bases para corregir la mutación.\nUse solamente los caracteres A, T, G o C." );
if( cadenaCorreccion != null )
{
BaseNitrogenada fragmentoMutacion = construirCadenaBases( cadenaMutacion );
BaseNitrogenada fragmentoCorreccion = construirCadenaBases( cadenaCorreccion );
procesadorAdn.crearCadenaCorregida( cadena1, fragmentoMutacion, fragmentoCorreccion );
actualizarListaCadenas( );
}
}
}
}
catch( Exception e )
{
JOptionPane.showMessageDialog( this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE );
}
}
/**
* Construye una cadena de BasesNitrogenadas a partir de una cadena de caracteres
* @param cadenaCaracteres La cadena de caracteres que se quiere usar para construir la cadena de bases
* @return Retorna la cadena de bases nitrogenadas construida a partir de la cadena de caracteres
* @throws CadenaIncorrectaExcepcion Se lanza esta excepción si la cadena de caracteres tiene caracteres que no son válidos
*/
private BaseNitrogenada construirCadenaBases( String cadenaCaracteres ) throws CadenaIncorrectaExcepcion
{
cadenaCaracteres = cadenaCaracteres.toUpperCase( ).trim( );
if( cadenaCaracteres.matches( "[ATGC]*" ) && cadenaCaracteres.length( ) > 0 )
{
BaseNitrogenada primera = null;
BaseNitrogenada ultima = null;
char[] letrasFragmento = cadenaCaracteres.toCharArray( );
for( int i = 0; i < letrasFragmento.length; i++ )
{
char letra = letrasFragmento[ i ];
BaseNitrogenada nuevaBase = null;
if( letra == 'A' )
nuevaBase = new BaseNitrogenada( BaseNitrogenada.ADENINA );
else if( letra == 'G' )
nuevaBase = new BaseNitrogenada( BaseNitrogenada.GUANINA );
else if( letra == 'T' )
nuevaBase = new BaseNitrogenada( BaseNitrogenada.TIMINA );
else if( letra == 'C' )
nuevaBase = new BaseNitrogenada( BaseNitrogenada.CITOSINA );
if( primera == null )
{
primera = nuevaBase;
ultima = nuevaBase;
}
else
{
ultima.cambiarSiguiente( nuevaBase );
nuevaBase.cambiarAnterior( ultima );
ultima = nuevaBase;
}
}
return primera;
}
else
throw new CadenaIncorrectaExcepcion( "La cadena puede construirse únicamente con A, T, G o C" );
}
/**
* Agrega a una cadena, las bases de otra cadena
*/
public void agregarBases( )
{
Cadena c1 = seleccionarCadena( "Cadena que será extendida" );
if( c1 != null )
{
Cadena c2 = seleccionarCadena( "Cadena que será agregada" );
if( c2 != null )
{
if( !c1.equals( c2 ) )
{
try
{
procesadorAdn.agregarBasesACadena( c1, c2 );
actualizarCadenasMostradas( );
}
catch( CadenaNoExisteExcepcion e )
{
JOptionPane.showMessageDialog( this, e.getMessage( ), "Error", JOptionPane.ERROR_MESSAGE );
}
}
else
{
JOptionPane.showMessageDialog( this, "La cadena agregada no puede ser la misma cadena que será extendida", "Agregar bases", JOptionPane.INFORMATION_MESSAGE );
}
}
}
}
/**
* Mostrar un diálogo para seleccionar una cadena
* @param titulo El título que se mostrará en el diálogo - titulo != null
* @return Se retornó la cadena seleccionada por el usuario
*/
private Cadena seleccionarCadena( String titulo )
{
ArrayList descripciones = procesadorAdn.darDescripcionesCadenas( );
if( descripciones.size( ) > 0 )
{
String seleccion = ( String )JOptionPane.showInputDialog( this, "Seleccione la cadena", titulo, JOptionPane.QUESTION_MESSAGE, null, descripciones.toArray( ), descripciones.get( 0 ) );
if( seleccion != null )
{
Cadena cadena = procesadorAdn.darCadena( seleccion );
return cadena;
}
}
return null;
}
// -----------------------------------------------------------------
// Puntos de Extensión
// -----------------------------------------------------------------
/**
* Método para la extensión 1
*/
public void reqFuncOpcion1( )
{
String resultado = procesadorAdn.metodo1( );
JOptionPane.showMessageDialog( this, resultado, "Respuesta", JOptionPane.INFORMATION_MESSAGE );
}
/**
* Método para la extensión 2
*/
public void reqFuncOpcion2( )
{
String resultado = procesadorAdn.metodo2( );
JOptionPane.showMessageDialog( this, resultado, "Respuesta", JOptionPane.INFORMATION_MESSAGE );
}
// -----------------------------------------------------------------
// Main
// -----------------------------------------------------------------
/**
* Este método ejecuta la aplicación, creando una nueva interfaz
* @param args Argumento de ejecución. No deben usarse
*/
public static void main( String[] args )
{
InterfazCadenasAdn interfaz = new InterfazCadenasAdn( );
interfaz.setVisible( true );
}
}
|