Instalacion de Apache Tomcat 7 en Windows

Mini tutorial (con imágenes) sobre la instalación de Apache tomcat 7 en Windows. Dado que he decido volver a retomar la programación en Java quiero dejar constancia con estas breves notas sobre la instalación de Apache Tomcat. Sobre la terminología y conceptos no daré muchos detalles específicos sino solo a grandes rasgos, daré por hecho que si tu también quieres instalarlo es porque ya tienes nociones de programación en Java o al menos sabes algo sobre el tema.

Como dijo Jack El Destripador, vayamos por partes…

¿Que es Apache Tomcat?

Es un Software de código abierto para la implementación (vaya, programación) de Servlets y tecnologías JavaServer Pages (JSP) los cuales derivan de Java. En sí Apache Tomcat actúa como un contenedor web para ejecutar Servlets/JSP.

Descargar el instalador de Tomcat

Para descargar tomcat hay que visitar la dirección http://tomcat.apache.org/ y en el panel derecho (sección Download) elegir una versión de Apache Tomcat:

A la fecha de hoy la versión más reciente de Tomcat es la version 7.0.37, pero ¿Cual versión que debes bajarte? Si observas esa misma pregunta está en la página de tomcat (en esta página) en la sección de descargas. Como ellos mismos explican, la versión depende de la especificación de Servlets y JSP’s que vayas a usar a la hora de estar programando.

En mi caso como voy a usar Tomcat para pruebas y además quiero aprender lo más reciente sobre servlets y jsp entonces me bajare la versión más reciente de Apache Tomcat, es decir, la versión que mencione anteriormente, da click en la versión elegida y podrás ver una pantalla similar a la siguiente:

Aquí debes el servidor espejo y el formato en el que deseas descargar el instalador de Apache Tomcat (formato zip, tar, instalador .exe, etc). En mi caso me bajare la versión: 32-bit/64-bit Windows Service Installer. Esta versión es una versión para windows el cual permite instalar Tomcat con un asistente de instalación, además, permite ejecutar apache de forma automática al encender la pc con un servicio de Windows.

De preferencia descárgalo en el escritorio para fácil ubicación y borrado (después de instalarlo):

Ahora que ya lo tienes en el escritorio hay que darle doble click para ejecutarlo e iniciar el asistente de instalación:

Instalacion de Apache Tomcat

Ahora procederemos a instalar Apache Tomcat. Al dar doble click sobre el icono del escritorio, se abre el asistente de instalación.

Paso 1: Bienvenida

En este paso se te da la bienvenida al asistente y se te indica que cierres todos los programas aplicativos antes de iniciar dicha instalación:

En realidad eso de cerrar las aplicaciones no es tan necesario (aplicaba para versiones anteriores de Windows) pues hoy en día yo desde que tenía windows Xp he instalado muchos programas en Windows que también indican que cierres y se instalan y funcionan sin problemas. Pero por si las dudas si gustas tú puedes cerrarlas. Da click en el botón Next (siguiente) para pasar al siguiente paso de instalación.

Paso 2: Aceptar el acuerdo de licencia

Esta pantalla del asistente te muestra el acuerdo de licencia, léelo; en resumen te indica los términos y condiciones a los que te sometes si usas el programa. Apache Tomcat es un Software libre de código abierto que se distribuye bajo la licencia de Apache. Así que no creo que tengas mucho de qué preocuparte al usar este Software. No digo que no lo hagas, si es tu deseo, hazlo:

Si estas de acuerdo, da click en el botón I Agree (Si Acepto) para aceptar el acuerdo de licencia y pasar al siguiente paso.

Paso 3: Elegir los componentes a instalar

Este paso te permite indicar los componentes de Apache Tomcat que deseas instalar, algunos son opcionales, te recomiendo que dejes los que están marcados por defecto pues creo que si tienen utilidad, por ejemplo la opción ‘Start Menu Items’ te crea unos accesos directos en el Menú inicio para que desde ahí puedes abrir Tomcat en caso de que no los programes con ejecución automática (cada vez que se enciende la computadora).

La opción Documentation. Te copia la documentación de Tomcat en la carpeta de instalación (mas adelante indicaremos donde se instalara). Por cierto, la documentación te recomiendo que la instales y que la leas pues es muuy buena. Muchas veces instalamos un programa y nos ponemos a buscar tutoriales y videos, etc. acerca del uso del programa sin revisar la documentación de los creadores del programa (la oficial), no hay nada mejor que la doc. oficial de un programa para aprender a usarlo. Así que deja de buscar por otros lados tutoriales, manuales y primero que nada revisa esta documentación que aunque esta en inglés es muy útil.
La opción Manager: Instala una aplicacion Web para administrar Tomcat.
La opción Examples: Instala ejemplos de Servlets y JSPs.

Selecciona los componentes que desees y da click al botón Next para ir al siguiente paso del asistente.

Paso 4: Nombre del servicio y login del administrador


En este paso puedes configurar varias cosas, te recomiendo dejarlas como están, te explico algunas opciones:
Windows Service Name. El instalador automáticamente te crea un servicio para que al encender la PC te arranque Apache tomcat. Esta opción te permite especificar el nombre de dicho servicio de Windows. En la imagen se observa que a este servicio le asigne el nombre contenedor_tomcat7. Más adelante explicare como configurar este servicio para que no arranque Tomcat de forma automática.

En la sección Tomcat Administrator Login (optional):
User name: Aquí puedes especificar el nombre de usuario del administrador de tomcat y en la caja de texto password especificas la contraseña de dicho usuario.
Roles: Te permite especificar el rol del usuario, te recomiendo dejar el que esta por defecto (manager-gui) ya que ese te permite accesar a la aplicación web para administrar Tomcat. Da click en el boton Next para avanzar al siguiente paso.

Paso 5: Eleccion del Java Runtime Environment (JRE)


Como decía al inicio, Tomcat te permite la ejecución de tecnologías Servlets y JSPs, por lo tanto necesita de una Máquina Virtual de Java (JVM), en este paso debes elegir la ruta de instalación de una JVM. El instalador de Apache Tomcat por defecto ya trae un JRE que usa para ejecutar el servicio de Windows, pero el también usa el registro de Windows para determinar la ruta base de Java o JRE que pudiéramos tener preinstalados.

A menos que sepas donde esta una versión mas reciente, te recomiendo que dejes la ruta tal y como esta des click en el botón Next para ir al siguiente paso.

Paso 6: Ruta de instalacion de Apache Tomcat


En este paso debemos elegir una carpeta donde se instalara Apache Tomcat. Cabe mencionar que constantemente en tutoriales, manuales, libros, etc. encuentres muchas referencias la palabra $CATALINA_HOME. Ésta representa la carpeta de instalación de tomcat, independientemente si es Linux o Windows.

A menos que tengas poco espacio en disco o quieras instalarlo en otro lugar especifico, te recomiendo que dejes la ruta predeterminada y des click al botón install para iniciar la copia de los archivos del instalador al disco duro.

Copia de los archivos de Apache Tomcat

Despues de dar click al boton install veras una pantalla similar a la siguiente; en la cual se observa el progreso de la copia de archivos, creacion del servicio, etc.

Una vez que el instalador ha terminado de copiar los archivos te muestra la siguiente pantalla en la cual se te indica que ha sido completado el asistente de instalación de Apache Tomcat:

Además, te da la opción de arrancar Apache Tomcat (inicia el servicio de windows) y/o leer el archivo léame que contiene información sobre la versión instalada. Si eliges iniciar Tomcat te mostrara una barra de progreso

y si no hay ningún problema mostrara un nuevo icono en la bandeja del sistema de Windows (en mi caso Windows 7):

Desde este icono podrás configurar el inicio del servicio de Windows (Opción Configure…, ficha General, Opción Statup type).

Una vez que ya tenemos instalado e iniciado el servicio, podemos abrir el navegador y escribir la dirección http://localhost:8080/ para verificar la instalación:

Si al hacerlo, te muestra la pantalla anterior; la instalación fue exitosa y ya puedes empezar a escribir tus WebApps (Aplicaciones web), sino, que es muy poco probable vuelve realizar los pasos o déjame un comentario con una descripción del problema y en cuanto vea tu mensaje y tenga tiempo te contesto.

Desinstalacion de Apache Tomcat (Windows)

Si por alguna razon extraña ya no deseas tener instalado Apache Tomcat en tu computadora, para desinstalarlo;

  • En el Panel de control->Programas y características buscas Apache Tomcat y los desinstalas.
  • Asegúrate de que no tengas iniciado el servicio de Apache Tomcat (con el boton de la bandeja del sistema) y borra la carpeta de instalación de Tomcat (paso 6).
  • Listo, quedo desinstalado.

Despedida

Eso es todo sobre la instalación de Apache Tomcat, mas adelante explicare como crear tu primera aplicación web y ejecutarla en Apache Tomcat. Espero que te haya gustado y sobre todo que te sirva. Te invito a que me dejes un comentario si te gusto el tutorial.

Hasta pronto, saludos

Como enviar un email en Java con la API JavaMail

Como enviar un correo electronico con Java usando la API JavaMail. Desde hace tiempo estaba pensado en exponer algo respecto a este tema y por fin me decidi a hacerlo. El ejemplo en si es muy sencillo pero util si lo necesitas usar inmediatamente.

Herramientas que necesitas

Necesitas principalmente dos cosas:

  • Libreria JavaMail.
  • libreria JAF ( JavaBeans Activation Framework ).

Como observas, te e puesto un link a la pagina de descarga de cada libreria, esa es la que he utilizado y que a la fecha me ha funcionado. Lo que debes hacer es bajarte los .zip, poner todos los archivos .jar juntos y agregarlos a la variable de entorno CLASSPATH de tu sistema operativo. Si no te quieres molestar en entrar a la pagina a continuacion yo ya los he bajado y a continuacion te dejo el link de descarga directa de la libreria JavaMail que contiene los JAR: dns.jar, imap.jar, mail.jar, mailapi.jar, pop3.jar, smtp.jar, la libreria JAF contiene un unico jar activation.jar.

Sigamos con lo interesante…

El codigo fuente

A continuacion pego el codigo fuente para el envio de el correo electronico que por cierto es muy corto. Sino fuera por la sencilla GUI que e creado….

/*
	Descripcion: Sencillo ejemplo de como enviar un Email con la libreria JavaMail
			a travez de una interfaz grafica.
	Author: Gonzalo Silverio    gonzasilve@gmail.com
	Archivo:  FrmVentanaMail.java
	Fuente:		https://gonzasilve.wordpress.com/
 **/
 
import javax.swing.*;
import java.awt.*;

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

import java.util.Properties;

//Para manejo de JavaMail
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class FrmVentanaMail extends JFrame {

	//Para el cuadro de dialogo de Opciones
	JPanel pnlServidor;
	JPanel pnlBotones;
	JPanel pnlRemitente;
	JPanel pnlPasswordRemitente;
	JPanel pnlDestino;
	JPanel pnlAsunto;
	JPanel pnlMensaje;
	
	JLabel lblServidor; 	JTextField jtfServidor;
	
	JLabel lblRemitente; 	JTextField jtfRemitente;	JPasswordField jpfPasswordRemitente;
	JLabel lblDestino; 	JTextField jtfDestino;
	JLabel lblAsunto; 	JTextField jtfAsunto;
	JLabel lblMensaje; 	JTextArea jtaMensaje;
	
	JButton btnEnviar;
	JButton btnCancelar;
	
	public FrmVentanaMail(String strTitulo, int i_ancho, int i_alto ) {
		this.setTitle(strTitulo);
    this.setSize(i_ancho,i_alto);    
    this.setLocationRelativeTo(null);

		this.setResizable(false);
		
		Box boxPrincipal = Box.createVerticalBox();
		crearCamposVentana();
		crearBotones();
		boxPrincipal.add(Box.createVerticalStrut(15));
		boxPrincipal.add(pnlServidor);
		boxPrincipal.add(Box.createVerticalStrut(15));
		boxPrincipal.add(pnlRemitente);
		boxPrincipal.add(Box.createVerticalStrut(15));
		boxPrincipal.add(pnlDestino);
		boxPrincipal.add(Box.createVerticalStrut(15));
		boxPrincipal.add(pnlAsunto);
		boxPrincipal.add(Box.createVerticalStrut(15));
		boxPrincipal.add(pnlMensaje);
		boxPrincipal.add(Box.createVerticalStrut(15));
		boxPrincipal.add(pnlBotones);
		
		add(boxPrincipal);
		
		btnCancelar.addActionListener( new ActionListener() {			
				public void actionPerformed(ActionEvent evt) {
					//dispose();
					System.exit(0);
				}
			}
		);
		
		btnEnviar.addActionListener( new ActionListener() {			
				public void actionPerformed(ActionEvent e) {
					if(enviarEmail() ) {
						JOptionPane.showMessageDialog(null,"Mensaje enviado!");
						jtaMensaje.requestFocus(true);
					} else {
						JOptionPane.showMessageDialog(null,"Por el momento NO SE PUDO ENVIAR el mensaje.");
					}
					
				}			
			}			
		);
		
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);	
	}
	
	private void crearCamposVentana() {
		Box boxServidor =  Box.createHorizontalBox();
		lblServidor = new JLabel("Servidor");
		jtfServidor = new JTextField("smtp.gmail.com",15);		
		boxServidor.add(Box.createHorizontalStrut(15));
		boxServidor.add(lblServidor);
		boxServidor.add(Box.createHorizontalStrut(20));
		boxServidor.add(jtfServidor);
		pnlServidor = new JPanel(new FlowLayout(FlowLayout.LEFT));
		pnlServidor.add(boxServidor);
		
		//Remitente
		Box boxRemitente =  Box.createHorizontalBox();
		lblRemitente = new JLabel("<html><font color='#0000FF'>Remitente</font></html>");
		jtfRemitente = new JTextField("gonzasilve@gmail.com",15);
		jpfPasswordRemitente =  new JPasswordField(15);
		jpfPasswordRemitente.setToolTipText("Escriba el password de este remitente");
		boxRemitente.add(Box.createHorizontalStrut(15));
		boxRemitente.add(lblRemitente);
		boxRemitente.add(Box.createHorizontalStrut(20));
		boxRemitente.add(jtfRemitente);
		boxRemitente.add(Box.createHorizontalStrut(5));
		boxRemitente.add(jpfPasswordRemitente);
		pnlRemitente = new JPanel(new FlowLayout(FlowLayout.LEFT));
		pnlRemitente.add(boxRemitente);
	
		//Destino
		Box boxDestino =  Box.createHorizontalBox();
		lblDestino = new JLabel("<html><font color='#0000FF'>Destino</font></html>");
		jtfDestino = new JTextField("gonzasilve@hotmail.com",15);
		jtfDestino.setToolTipText("Puede escribir varios destinatarios separados con coma");
		boxDestino.add(Box.createHorizontalStrut(15));
		boxDestino.add(lblDestino);
		boxDestino.add(Box.createHorizontalStrut(20));
		boxDestino.add(jtfDestino);
		pnlDestino = new JPanel(new FlowLayout(FlowLayout.LEFT));
		pnlDestino.add(boxDestino);			
			
		//Asunto
		Box boxAsunto =  Box.createHorizontalBox();
		lblAsunto = new JLabel("<html><font color='#0000FF'>Asunto</font></html>");
		jtfAsunto = new JTextField("Test JavaMail",15);		
		boxAsunto.add(Box.createHorizontalStrut(15));
		boxAsunto.add(lblAsunto);
		boxAsunto.add(Box.createHorizontalStrut(20));
		boxAsunto.add(jtfAsunto);
		pnlAsunto = new JPanel(new FlowLayout(FlowLayout.LEFT));
		pnlAsunto.add(boxAsunto);		
			
		//Mensaje
		Box boxMensaje =  Box.createHorizontalBox();
		lblMensaje = new JLabel("<html><font color='#0000FF'>Mensaje</font></html>");
		jtaMensaje = new JTextArea("Mensaje desde JavaMail",5,30);
		jtaMensaje.setLineWrap(true);
		JScrollPane jspScrollMsg = new JScrollPane(jtaMensaje);

		jtaMensaje.setAutoscrolls(true);
		boxMensaje.add(Box.createHorizontalStrut(15));
		boxMensaje.add(lblMensaje);
		boxMensaje.add(Box.createHorizontalStrut(20));
		boxMensaje.add(jspScrollMsg);
		pnlMensaje = new JPanel(new FlowLayout(FlowLayout.LEFT));
		pnlMensaje.add(boxMensaje);
	}
	
	private void crearBotones() {
		btnEnviar = new JButton("Enviar email");
		btnCancelar = new JButton("Cancelar");
		Box boxBotones = Box.createHorizontalBox();
		boxBotones.add(btnEnviar);
		boxBotones.add(Box.createHorizontalStrut(25));
		boxBotones.add(btnCancelar);
		boxBotones.add(Box.createHorizontalStrut(25));
		pnlBotones = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		pnlBotones.add(boxBotones);
				
	}
	
	private void mostrar() {
		setVisible(true);
	}
	
	//Devuelve true en caso de que se envie el email de manera correcta, o
	//devuelve false si no se pudo enviar el email
	private boolean enviarEmail() {
    try
    {
        // Propiedades de la conexión
        Properties props = new Properties();
        props.setProperty("mail.smtp.host",  "smtp.gmail.com");
        props.setProperty("mail.smtp.starttls.enable", "true");
        props.setProperty("mail.smtp.port", "587");
        props.setProperty("mail.smtp.auth", "true");

        // Preparamos la sesion
        Session session = Session.getDefaultInstance(props);
				
	//Recoger los datos
	String str_De 		= jtfRemitente.getText();
	String str_PwRemitente 		= jpfPasswordRemitente.getText();				
	String str_Para 	= jtfDestino.getText();
	String str_Asunto = jtfAsunto.getText();
	String str_Mensaje = jtaMensaje.getText();
	//Obtenemos los destinatarios
	String destinos[] = str_Para.split(",");
				
        // Construimos el mensaje
        MimeMessage message = new MimeMessage(session);
        
        message.setFrom(new InternetAddress( str_De ));

	//Otra forma de especificar las direcciones de email 
	//a quienes se enviar el correo electronico
	//Forma 1
        //Address [] receptores = new Address []{
	//      new InternetAddress ("fuerenio@gmail.com"),
	//      new InternetAddress ("gonzasilve@gmail.com")
	//  };
	//Forma 2
	//  Address [] receptores = new Address []{
	//      new InternetAddress ( str_De )
	// };
	//Forma 3
        Address [] receptores = new Address [ destinos.length ];
        int j = 0;
	while(j<destinos.length){					
		receptores[j] = new InternetAddress ( destinos[j] ) ;					
		j++;				
	}

        
        //receptores.
        message.addRecipients(Message.RecipientType.TO, receptores);        
        message.setSubject( str_Asunto );        
        message.setText( str_Mensaje );
            
        // Lo enviamos.
        Transport t = session.getTransport("smtp");
        t.connect(str_De, str_PwRemitente);
        t.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
				
        // Cierre de la conexion.
        t.close();
        return true;
    }
    catch (Exception e)
    {
        e.printStackTrace();
        return false;
    }		
	}
	
	public static void main(String gonzi[]) {
		FrmVentanaMail prueba1 = new FrmVentanaMail("Envio de email con JavaMail", 500, 400);
		prueba1.mostrar();
	}
	
}

En si no hay mucho que explicar, el metodo mas importante de la clase anterior es enviarEmail() pues es el que toma los datos de las cajas de texto y los configura como parametros para JavaMail y envia el mensaje escrito, usando el email remitente a los emails destino. Si observas éste devuelve un valor booleano para poder determinar el mensaje que se le muestra al usuario despues de que pulsa el boton Enviar email.

Pantallas del ejemplo

A continuación la pantalla que se dibuja al ejecutar el código anterior (e rellenado algunos campos):
GUI para enviar email con JavaMail

Si el email se envió correctamente aparece el siguiente mensaje:
Envio exitoso con JavaMail

El email que le llega al email destino es el siguiente:
Email recibido, fue enviado desde JavaMail

En caso de dudas, ó si te gusto el ejemplo te invito a que me dejes un comentario (me motivas a escribir mas). Si gustas tener el codigo por fa, dejame un comentario y te lo envio a la brevedad.

Hasta pronto.

Determinar si un año es Bisiesto

En esta ocasion y a peticion de un visitante del blog les dejo el codigo para determinar si un Año es bisiesto.

//              Instituto Tecnologico de Zacatepec
//      Descripcion:  Validacion de si un anio es bisiesto
//      Author: Gonzalo Silverio   gonzasilve@gmail.com
//      Archivo: AnioBisiesto.java

import java.util.GregorianCalendar;

public class AnioBisiesto {

   public static void main(String[] args) {

      String res = new String();
      for(int i=2000; i<=2012; i++)
      {
         res = esBisiesto(i) ? "Anio bisiesto" : "Anio NO bisiesto";
         System.out.println(i+" "+res);
         System.out.println("Comprobando con clase java GregorianCalendar...");
         res = esBisiestoJava(i) ? "Anio bisiesto" : "Anio NO bisiesto";
         System.out.println(i+" "+res+"\n----------");
      }
   }
   
   private static boolean esBisiesto(int anio)
   {
      int elanio = anio;

      if ((elanio % 4 == 0) && ((elanio % 100 != 0) || (elanio % 400 == 0)))
         return true;
      else
         return false;
   }
   
   private static boolean esBisiestoJava(int anio)
   {
      int elanio = anio;
      GregorianCalendar calendar = new GregorianCalendar();
      return calendar.isLeapYear(elanio);
   }

}

Parte de la salida de ejecucion en Netbeans:

Salida en Netbeans

Salida en Netbeans

Quien este interesado en el codigo solo basta con dejar su correo. Gracias x visitar. Hasta pronto.

Clase java para recorrer y buscar registros de tabla (de Sql Server, Mysql o Postgres) con botones primero, anterior, siguiente y ultimo.

Clase java para recorrer y buscar registros de tabla de base de datos con botones primero, anterior, siguiente y ultimo. El objetivo de esta entrada de blog es mostrar una clase diseñada por mi para facilitar la navegacion por los registros de una tabla. Se me ocurrio esto debido a que en muchas ocasiones en los programas necesitamos recorrer los registros de una tabla con los tipicos botones:
Primero Permite ir al primer registro de la tabla.
Anterior Permite ir al anterior registro.
Siguiente Permite ir al siguiente registro.
Ultimo Permite ir al ultimo registro.

La siguiente imagen muestra un ejemplo clasico donde se requieren estos botones (los botones con flechas verdes):

Ventana con botones de navegacion de registros.
Ventana con botones de navegacion de registros.

Como se puede imaginar con ayuda de estos botones nos podemos colocar en cualquier registro de la tabla y una vez posicionados en el registro deseado se pueden usar otros botones para modificar o eliminar el registro. Bueno sin mas preambulos muestro el codigo de la clase:

GonzaBD.java
El truco de esta clase es almacenar en un array todos los campos llave de la tabla que se desee manipular (por cada tabla se debe crear un nuevo objeto de esta clase). Al llamar al metodo primero() con ayuda de una variable se accede al primer elemento del arreglo de llaves primarias. Al llamar al metodo ultimo() con ayuda de una variable se accede al ultimo elemento del arreglo de llaves primarias. Al llamar al metodo siguiente() con ayuda de una variable; si por ejemplo estamos en la fila 5, se accede al elemento 5 +1, del arreglo de llaves primarias. Despues se realiza un Select hacia la tabla y los datos quedan en un Objeto Resultset (llamado rs) que es local a esta clase, bueno a continuacion muestro el codigo:

/*
 *   Instituto Tecnologico de Zacatepec
 * Descripcion:  Clase que contiene metodos para recorrer los registros de una tabla 
 *						hacia el primer, anterior, siguiente o ultimo registro
 * Archivo: GonzaBD.java
 * author Gonzalo Silverio       gonzasilve@hotmail.com
 * fuente:  https://gonzasilve.wordpress.com
 */
import java.sql.*;


public class GonzaBD 
{
	String strSentenciaSQL = "";
	String strCadenaConexion = "";
	String strOrdenarPor = "";
	String strCampoLLave = "";
	String strTabla = "";
	String strArrayCamposLlave[];
	int intArrayCamposLlave[];
	
	//Los posibles tipos del campo llave son cadena y entero
	//Por defecto el campo llave es de tipo cadena
	String strTipoCampoLlave = "cadena";
	
	int intTotalRegistros = 0,intFilaActual = 0;	
	
	String strDriverMySQL 		="com.mysql.jdbc.Driver";
	String strDriverPostgres 	="org.postgresql.Driver";
	String strDriverSqlServer 	="net.sourceforge.jtds.jdbc.Driver";	
	
	String strManejador 		= "mysql";
	String strBaseDatos 		= "BD";
	String strServidor 		= "localhost";
	String strUsuario 		= "usuario";
	String strPassword		= "password";
	String strControlador 	= strDriverMySQL;
	String strPuerto			= "3306";
	
	private static Connection con = null;
	Statement st;
	ResultSet rs;
	
    public GonzaBD()
    {
    	
    }
    
    //se mueve a la primera fila y devuelve true si se pudo, false sino se pudo ir a la primera fila
    public  boolean  primero()
    {
      try
		{
			intFilaActual = 0;
			if( strTipoCampoLlave.equals("cadena") )
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"='"+strArrayCamposLlave[intFilaActual]+"'");
			else
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"="+intArrayCamposLlave[intFilaActual]);
				
			if( rs.next() )
				return true;
			
			return false;
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }
    
    //se mueve a la anterior fila y devuelve true si se pudo, false sino se pudo ir a la anterior fila
    public  boolean  anterior()
    {
      try
		{
			intFilaActual--;
			if(intFilaActual<0)
				intFilaActual=0;
				
			if( strTipoCampoLlave.equals("cadena") )
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"='"+strArrayCamposLlave[intFilaActual]+"'");
			else
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"="+intArrayCamposLlave[intFilaActual]);
				
			if( rs.next() )
				return true;
			
			return false;
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }
    
    //se mueve a la siguiente fila y devuelve true si se pudo, false sino se pudo ir a la siguiente fila
    public  boolean  siguiente()
    {
      try
		{
			intFilaActual++;
			if(intFilaActual>intTotalRegistros-1)
				intFilaActual=intTotalRegistros-1;

			if( strTipoCampoLlave.equals("cadena") )
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"='"+strArrayCamposLlave[intFilaActual]+"'");
			else
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"="+intArrayCamposLlave[intFilaActual]);
				
			if( rs.next() )
				return true;
			
			return false;
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }
    
    //se mueve a la ultima fila y devuelve true si se pudo, false sino se pudo ir a la ultima fila
    public  boolean  ultimo()
    {
      try
		{
			intFilaActual = intTotalRegistros-1;

			if( strTipoCampoLlave.equals("cadena") )
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"='"+strArrayCamposLlave[intFilaActual]+"'");
			else
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"="+intArrayCamposLlave[intFilaActual]);
				
			if( rs.next() )
				return true;
			
			return false;
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }
	 
	//Obtiene el controlador del manejador mysql o postgres
    public  String obtenerDriverManejador(String manejador)
    {
		if(manejador.equals("sqlserver"))							//Si el manejador es sql server
			return strDriverSqlServer;
		else if(manejador.equals("mysql"))							//Si el manejador es mysql
			return strDriverMySQL;
		else if(manejador.equals("postgres"))							//Si el manejador es postgres
			return strDriverPostgres;

			//en caso d k no sea ninguno devuelve el de MySQL			
			return strDriverMySQL;
    }
  	
	//Conecta a la BD con los datos por default
    public boolean conectarBD() throws SQLException
    {    
      try
		{
			return conectarServidor(strManejador,strServidor,strUsuario,strPassword,strBaseDatos,strControlador);
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }
    

	//Conecta a la BD con los datos del usuario, bd y password especificados, para los demas toma los k estan por default
    public boolean conectarBD(String usuario, String password, String BD )// throws SQLException
    {
    	boolean ress;
      try
		{
			strUsuario 		= usuario;
			strPassword 	= password;
			strBaseDatos 	= BD;
			ress = conectarServidor(strManejador,strServidor,usuario,password,BD,strControlador);
			return ress;
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }
    
    //permite especificar el campo por el que se van a ordenar los registros
    public  void ordenarPor(String campo)
    {
    	strOrdenarPor = campo;
    }
    
	//Conecta a la BD con los datos especificados, para los demas toma los k estan por default
    public boolean conectarBD(String usuario, String password, String BD, String manejador) //throws SQLException
    {
    	boolean ress;
      try
		{
			strControlador = obtenerDriverManejador(manejador);			
			strUsuario 		= usuario;
			strPassword 	= password;
			strBaseDatos 	= BD;
			strManejador 	= manejador;
			ress = conectarServidor(manejador,strServidor,usuario,password,BD,strControlador);
			return ress;
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }
    
	//Realiza una conexion a sqlserver, mysql o postgres con los datos especificados
    public boolean conectarServidor(String manejador,String servidor,String usuario,String pw,String bd, String driver) throws SQLException
    {
		if(manejador.equals("sqlserver"))							//Si el manejador es sql server
		{
		    try
		    {
		        Class.forName(driver);
		        strCadenaConexion = "jdbc:jtds:sqlserver://"+servidor+"/"+bd+";instance=SQLSERVEREXPRESS;";
		        con = DriverManager.getConnection(strCadenaConexion,usuario,pw);
		        if (con == null )
		    			return false;
		        return true;
		    }
		    catch(SQLException sqlex)
		    {
		    		sqlex.printStackTrace();
		        	return false;
		    }
		    catch(Exception e)
		    {
		    		e.printStackTrace();
		        	return false;
		    }
		}            
    	else if(manejador.equals("mysql"))									//Si el manejador es mysql
    	{
           try
           {
		          Class.forName(driver);
		          strCadenaConexion = "jdbc:mysql://"+servidor+"/"+bd;
		          con = DriverManager.getConnection(strCadenaConexion,usuario,pw);
		          if (con == null )		          	
		          	return false;
		          
		          return true;
            }
            catch(SQLException sqlex)
            {
            	sqlex.printStackTrace();
                return false;
            }
            catch(Exception e)
            {
            	e.printStackTrace();
            	return false;
            }
    	}
    	else if(manejador.equals("postgres"))							//Si el manejador es postgress
      {
          try
          {
              Class.forName(driver);
              strCadenaConexion = "jdbc:postgresql://"+servidor+":5432/"+bd;
              con = DriverManager.getConnection(strCadenaConexion,usuario,pw);
              if (con == null )
          			return false;

              return true;
          }
          catch(SQLException sqlex)
          {

          		sqlex.printStackTrace();
              	return false;
          }
          catch(Exception e)
          {
          	e.printStackTrace();
              return false;
          }
      }

	    	return false;
    }
    
	//Ejecuta un SELECT y devuelve el Resultset con los resultados
	public ResultSet ejecutarConsulta(String cadSQ) throws SQLException
	{
		rs = null;
		if( ! strOrdenarPor.equals("") )
			cadSQ += " ORDER BY " +strOrdenarPor;
			
		try
		{
			rs = st.executeQuery(cadSQ);
			return rs;
       }
       catch(SQLException sqlex)
       {
       		sqlex.printStackTrace();
       		return rs;
       }

	}

	public  void obtenerCamposLlave()
	{
		obtenerCamposLlave(strTabla);
	}
	

	//Si el campo llave es de tipo entero guarda las llaves primarias en un arreglo de enteros
	//Si el campo llave es de tipo cadena guarda las llaves primarias en un arreglo de Strings
	public  void obtenerCamposLlave(String tabla)
	{
		int c=0;
		try
		{
			rs = ejecutarConsulta("SELECT * FROM " + tabla);
			while(rs.next())
				c++;
			intTotalRegistros = c;
			strArrayCamposLlave = new String[intTotalRegistros];
			intArrayCamposLlave = new int[intTotalRegistros];
			
			cerrar(rs);		//Cerrar consulta anterior
			//Ejecutar nuevamente la consulta
			rs = ejecutarConsulta("SELECT * FROM " + tabla);
			rs.next();		//Moverse al primer registro
			
			c=0;
			do
			{			//determina el tipo del campo llave y en base a eso guarda en el array correspondiente
				if( strTipoCampoLlave.equals("cadena") )				
					strArrayCamposLlave[c] = rs.getString(strCampoLLave);
				else
					intArrayCamposLlave[c] = rs.getInt(strCampoLLave);
					
				c++;
			}while( rs.next() );
			
		}
		catch(SQLException sqlex)
		{
       	sqlex.printStackTrace();
		}
		
	}

	
	// Cierra un objeto Resultset
	public static void cerrar(ResultSet rs)
	{	
		try
		{
			rs.close();
		} 
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	// cierra un objeto Statemet
	public static void cerrar(Statement st)
	{
		try
		{
			st.close();
		} 
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}

	// Cierra un objeto Connection
	public static void cerrar(Connection con)
	{	
		try
		{
			con.close();
		} 
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	//Permite especificar cual es el campo llave de la tabla
	public  void setCampoLlave(String campo)
	{
		strCampoLLave = campo;
	}
	
	//Permite especificar cual es el campo llave y su tipo, de la tabla
	public  void setCampoLlave(String campo, String tipo)
	{
		strCampoLLave = campo;
		strTipoCampoLlave = tipo;
	}
	
	public void setTipoCampoLlave(String tipo)
	{
		strTipoCampoLlave = tipo;
	}
	
	//Especifica la tabla sobre la k se va a trabajar
	public  void setTabla(String tabla)
	{
		try
		{
			strTabla = tabla;
			st=con.createStatement();
		}
		catch(SQLException ex)
		{
			ex.printStackTrace();
		}

	}	
}	//Fin de la clase

Lo interesante de esta clase es que esta preparada para recorrrer los registros de tablas que esten creadas en cualquera de los manejadores SQL Server, MySQL o de Postgres, obviamente que los .jar de los JConnector de dichos DBMS deben estar copiados en C:\Program Files\Java\jdk1.6.0_23\jre\lib\ext, Lo que esta en negrita lo e resaltado debido a que la version del JVM puede cambiar segun la que tengas instalada. Los JConnector que e usado para probar esta clase son los siguientes (puedes dar click en el enlace para descargarlo sino lo tienes).
JConnector de SQL Server: jtds-1.2.5.jar
JConnector de Postgres: postgresql-9.1-901.jdbc4.jar
JConnector de MySQL: mysql-connector-java-5.1.18-bin.jar

Para ejemplificar el uso de la clase anterior e usado una tabla que esta en SQL Server. Los parametros de conexion son:
Manejador de Base de datos (DBMS): SQL Server 2005 Express
Base de datos: prueba
Tabla: tbl_alumnos
Usuario: sa
Password: 123456
El Script para crear la tabla alumnos en SQL Server es el siguiente (generado con el Microsoft SQL Server Management Studio):

USE [prueba]
GO
/****** Object:  Table [dbo].[tbl_alumnos]    Script Date: 12/28/2011 17:59:51 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[tbl_alumnos](
	[matricula] [int] NOT NULL,
	[nombre] [varchar](50) NULL,
	[apellidos] [varchar](100) NULL,
	[edad] [int] NULL,
	[peso] [decimal](10, 2) NULL,
	[sexo] [char](1) NULL,
 CONSTRAINT [PK__tbl_alumnos__6FBF826D] PRIMARY KEY CLUSTERED
(
	[matricula] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF

La imagen de la tabla ya creada en SQL Server se ve asi:

Tabla Alumnos en SQL Server

DIAGRAMA UML DE LA CLASE gonzaBD

Diagrama UML de la clase gonzaBD

Diagrama UML de la clase gonzaBD

BREVE EXPLICACION DE LOS ATRIBUTOS DE LA CLASE gonzaBD:

Atributo Descripcion
intfilaActual Contiene un número que se usa como índice para acceder a una llave primaria dentro del arreglo strArrayCamposLlave o el arreglo strArrayCamposLlave (dependiendo de si la llave primaria es de tipo cadena o tipo entero, respectivamente). Este atributo contiene el número actual de fila-1.
strArrayCamposLlave[] Arreglo que contiene las llaves primarias de la tabla en caso de que el tipo de dato del campo llave sea Cadena.
intArrayCamposLlave[] Arreglo que contiene las llaves primarias de la tabla en caso de que el tipo de dato del campo llave sea Entero.
rs Contiene los datos de la fila actual mostrandose. Cada vez que se manda a llamar al método primero(), anterior(), siguiente() o ultimo() se realiza una consulta y este atributo (tipo Resultset) se actualiza con los campos de la nueva fila.

COMO SE USA LA CLASE gonzaBD
A continuacion voi a poner un fragmento de codigo con la intencion mostrar los pasos a realizar para usar correctamente la clase.

//Crear un objeto de esta clase
GonzaBD a = new GonzaBD();
//AHORA SE DEBE REALIZAR LO SIGUIENTE EN EL MISMO ORDEN…
//Primeramente se debe indicar especificar cual es la llave primaria de la tabla y su tipo
a.setCampoLlave("matricula","entero");
//Se de desea se puede indicar que si se desean ordenar los registros de la tabla por un campo, //este paso es opcional en todo caso sino se realiza, no se ordenan por ningún campo
a.ordenarPor("nombre");
//A continuación usamos un metodo sobrecargado para conectarse al DBMS, aquí es donde //indicamos a que manejador se debe accesar
a.conectarBD("sa","12345","pruebas","sqlserver");
//Una vez que ya estamos conectados se debe especificar la tabla que se va a manipular
a.setTabla("tbl_alumnos");
//Ahora se manda a llamar al método que rellena el arreglo de llaves primarias dentro de la clase; //dependiendo del tipo de dato del campo llave se rellena el arreglo de Strings o el arreglo de //enteros.
a.obtenerCamposLlave();
//Ahora ya se puede llamar a cualquiera de los métodos primero(), anterior(), siguiente() o ultimo()...

Despues de realizar lo anterior, para que el objeto rs se rellene con los datos de la primera fila se invoca al metodo:
a.primero();
Después de que se invoco ese metodo, el atributo rs de la clase gonzaBD se quedara con los datos de la fila 1. Supongamos que la tabla “alumnos”contiene las siguientes filas, rs apuntara a la fila:

El atributo rs esta en la posicion de la primera fila.

El atributo rs esta en la posicion de la primera fila.

Si inmediatamente despues se llama al método siguiente()
a.siguiente();
El atributo rs apuntara al siguiente registro despues del primero, es decir rs apuntara a la fila:

El atributo rs apunta a los datos de la segunda fila

El atributo rs apunta a los datos de la segunda fila

Y asi sucesivamente, una observación: si te fijas en el codigo de los metodos (siguiente() y anterior()) cuando se ha llegado a la ultima fila, es decir, si rs apunta al registro 4 y se ejecuta una llamada al método siguiente() (se intenta accesar una fila después de la ultima); dicho método contiene un ‘candado’ para detectar eso y siempre dejara a rs apuntando al ultimo registro. El método anterior() igualmente tiene esa precaucion y siempre que se intente accesar a un registro antes del primero automáticamente moverá a rs para que apunte a la primera fila. De esta manera no es posible sobrepasar los limites (inferior ni superior) de filas de la tabla que se este manipulando.

Finalmente Para ilustrar el uso de la clase gonzaBD anterior he creado una ventana muy basica.

JfrPrincipal.java
Esta clase crea una ventana de formulario con 6 campos y los 4 botones; primero, anterior, siguiente y ultimo en la parte inferior de dicha ventana. Es la misma clase que utilice para ilustrar como usar ventanas de formulario en Java, pero la he modificado con algunos campos mas. Bueno ahora muestro el codigo:

/*
 *   Instituto Tecnologico de Zacatepec
 * Descripcion:  Clase que crea una GUI para ilustrar el uso de la clase GonzaBD
 * Archivo: JfrPrincipal.java
 * author: Gonzalo Silverio       gonzasilve@hotmail.com
 * fuente:  https://gonzasilve.wordpress.com
 */

import javax.swing.*;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

//Se usara para cambiar los Margenes de los botones
import java.awt.Insets;

//Para Manejo de BD
import java.sql.*;

public class JfrPrincipal extends JFrame
{
	//Campos de texto y sus etiquetas 
	JLabel jlbMatricula;    JTextField  jtfMatricula;
	JLabel jlbNombre;       JTextField  jtfNombre;
	JLabel jlbApellidos;    JTextField  jtfApellidos;
	JLabel jlbEdad;         JTextField  jtfEdad;
	JLabel jlbPeso;         JTextField  jtfPeso;
	JLabel jlbSexo;         JComboBox   jcbSexo;
	
	//Botones de navegacion de los registros
	JButton btnPrimero;
	JButton btnAnterior;
	JButton btnSiguiente;
	JButton btnUltimo;
	
	Box boxVCamposVentana;   //Contiene todo los campos de texto (con su respectiva etiqueta)
	JPanel panBotones;      //Contiene los botones Guardar y Cancelar
	
	//Objeto de la clase que nos ayuda a navegar por los registros de la tabla
	GonzaBD bd = new GonzaBD();
	
	JfrPrincipal(String strTitulo, int intAncho, int intAlto)
	{
		super(strTitulo);
		this.setSize(intAncho, intAlto);
		this.setResizable(false);		//Ventana no redimensionable
		this.setLocationRelativeTo(null);       //Centrar ventana en pantalla
		
		//Box vertical por que los botones van a estar abajo
		Box boxVContenidoVerticalVentana = Box.createVerticalBox();
		crearCamposVentana();
		crearBotones();
		//Espacio del borde superior de la ventana al primer Campo
		boxVContenidoVerticalVentana.add(Box.createVerticalStrut(30));
		boxVContenidoVerticalVentana.add(boxVCamposVentana);
		//Espacio entre el ultimo campo (sexo) y los botones Guardar y Cancelar
		boxVContenidoVerticalVentana.add(Box.createVerticalStrut(20));
		boxVContenidoVerticalVentana.add(panBotones);
		
		this.add(boxVContenidoVerticalVentana);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	  
	  //Conecta la Base de datos
		conectarBD();
		bd.primero();		//Posicionarse en el primer registro
		rellenarCampos();		//Rellenar los campos con los datos del primer registro
		
		//ASIGNAR UN ESCUCHADOR PARA CADA BOTON DE NAVEGACION
		//Boton Primero
		btnPrimero.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent evt) 
			{
				bd.primero();
				rellenarCampos();
			}
		});
		//Boton Anterior
		btnAnterior.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent evt) 
			{
				bd.anterior();
				rellenarCampos();
			}
		});
		//Boton Siguiente
		btnSiguiente.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent evt) 
			{
				bd.siguiente();
				rellenarCampos();
			}
		});
		//Boton Ultimo
		btnUltimo.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent evt) 
			{
				bd.ultimo();
				rellenarCampos();
			}
		});
		  	
        	
	}		//Fin del constructor

	//Crea los campos de la ventana (cada caja tiene su correspondiente etiqueta)
    private void crearCamposVentana()
    {
        Box boxHMatricula =  Box.createHorizontalBox();        
        jlbMatricula = new JLabel("Matricula ");   jtfMatricula = new JTextField(15);
        boxHMatricula.add(Box.createHorizontalStrut(20));
        boxHMatricula.add(jlbMatricula);
        boxHMatricula.add(Box.createHorizontalStrut(14));
        boxHMatricula.add(jtfMatricula);
        JPanel panMatricula =  new JPanel(new FlowLayout(FlowLayout.LEFT) );
        panMatricula.add(boxHMatricula);

        Box boxHNombre =  Box.createHorizontalBox();
        jlbNombre = new JLabel("Nombre ");   jtfNombre = new JTextField(15);
        boxHNombre.add(Box.createHorizontalStrut(20));
        boxHNombre.add(jlbNombre);
        boxHNombre.add(Box.createHorizontalStrut(20));
        boxHNombre.add(jtfNombre);
        JPanel panNombre =  new JPanel(new FlowLayout(FlowLayout.LEFT) );
        panNombre.add(boxHNombre);

        Box boxHApellidos =  Box.createHorizontalBox();
        jlbApellidos = new JLabel("Apellidos ");   jtfApellidos = new JTextField(15);
        boxHApellidos.add(Box.createHorizontalStrut(20));
        boxHApellidos.add(jlbApellidos);
        boxHApellidos.add(Box.createHorizontalStrut(11));
        boxHApellidos.add(jtfApellidos);
        JPanel panApellidos =  new JPanel(new FlowLayout(FlowLayout.LEFT) );
        panApellidos.add(boxHApellidos);

        Box boxHEdad =  Box.createHorizontalBox();
        jlbEdad = new JLabel("Edad ");   jtfEdad = new JTextField(15);
        boxHEdad.add(Box.createHorizontalStrut(20));
        boxHEdad.add(jlbEdad);
        boxHEdad.add(Box.createHorizontalStrut(40));
        boxHEdad.add(jtfEdad);
        JPanel panEdad =  new JPanel(new FlowLayout(FlowLayout.LEFT) );
        panEdad.add(boxHEdad);
        
        Box boxHPeso =  Box.createHorizontalBox();
        jlbPeso = new JLabel("Peso ");   jtfPeso = new JTextField(15);
        boxHPeso.add(Box.createHorizontalStrut(20));
        boxHPeso.add(jlbPeso);
        boxHPeso.add(Box.createHorizontalStrut(40));
        boxHPeso.add(jtfPeso);
        JPanel panPeso =  new JPanel(new FlowLayout(FlowLayout.LEFT) );
        panPeso.add(boxHPeso);

        Box boxHSexo =  Box.createHorizontalBox();
        jlbSexo = new JLabel("Sexo ");   jcbSexo = new JComboBox();
        jcbSexo.addItem("Masculino");
        jcbSexo.addItem("Femenino");
        boxHSexo.add(Box.createHorizontalStrut(20));
        boxHSexo.add(jlbSexo);
        boxHSexo.add(Box.createHorizontalStrut(40));
        boxHSexo.add(jcbSexo);
        JPanel panSexo =  new JPanel(new FlowLayout(FlowLayout.LEFT) );
        panSexo.add(boxHSexo);

        boxVCamposVentana = Box.createVerticalBox();
        boxVCamposVentana.add(panMatricula);
        boxVCamposVentana.add(Box.createVerticalStrut(10));
        boxVCamposVentana.add(panNombre);
        boxVCamposVentana.add(Box.createVerticalStrut(10));
        boxVCamposVentana.add(panApellidos);
        boxVCamposVentana.add(Box.createVerticalStrut(10));
        boxVCamposVentana.add(panEdad);
        boxVCamposVentana.add(Box.createVerticalStrut(10));
        boxVCamposVentana.add(panPeso);
        boxVCamposVentana.add(Box.createVerticalStrut(10));
        boxVCamposVentana.add(panSexo);
    }

    private void crearBotones()
    {
        Box boxHBotones = Box.createHorizontalBox();
        
        btnPrimero = new JButton("|< Primero");
        btnAnterior = new JButton("< Anterior");
        btnSiguiente = new JButton("Siguiente >");
        btnUltimo = new JButton("Ultimo >|");
        //Cambiar los margenes de los botones
        			//Insets(margen_sup, margen_izq, margen_inf, margen_der)
        btnPrimero.setMargin(new Insets(0, 2, 0, 2));
        btnAnterior.setMargin(new Insets(0, 2, 0, 2));
        btnSiguiente.setMargin(new Insets(0, 2, 0, 2));
        btnUltimo.setMargin(new Insets(0, 2, 0, 2));
        
        boxHBotones.add(btnPrimero);
        boxHBotones.add(Box.createHorizontalStrut(20));
        boxHBotones.add(btnAnterior);
        boxHBotones.add(Box.createHorizontalStrut(20));
        boxHBotones.add(btnSiguiente);
        boxHBotones.add(Box.createHorizontalStrut(20));
        boxHBotones.add(btnUltimo);
        
        panBotones =  new JPanel(new FlowLayout(FlowLayout.CENTER) );
        panBotones.add(boxHBotones);
    }
	//Conecta con la BD y devuelve true si se conecto correctamente
	//false en cualquiero otro caso
	public boolean conectarBD()
	{
		// Especificar cual es la llave primaria de la tabla y su tipo
		bd.setCampoLlave("matricula","entero");
    	bd.ordenarPor("nombre");	//Ordena los registros de la tabla por este campo
		
		//Conecta con el usuario, pass, BD y dbms (manejador) especificados
		bd.conectarBD("sa","12345","pruebas","sqlserver");
		
    	//especifica la tabla sobre la que se va a manipular
    	bd.setTabla("tbl_alumnos");
    	//Dentro del objeto bd rellena un arreglo con las llaves 
    	//primarias de la tabla que se esta manipulando
		bd.obtenerCamposLlave();
		
		return true;
	}
	
	//Rellena los campos de texto con los datos del registro actual
    public void rellenarCampos()
    {
		try
		{
    		jtfMatricula.setText(aCadena(bd.rs.getInt("matricula")));
    		jtfNombre.setText(bd.rs.getString("nombre").trim ());
    		jtfApellidos.setText(bd.rs.getString("apellidos").trim ());
    		jtfEdad.setText(aCadena(bd.rs.getInt("edad")));
    		jtfPeso.setText(aCadena(bd.rs.getFloat("peso")));
    		jcbSexo.setSelectedItem( bd.rs.getString("sexo").equals("f") ? "Femenino" : "Masculino" );
    		
    		this.setTitle("Alumno "+(bd.intFilaActual+1)+" de "+bd.intTotalRegistros);
		}
		catch( SQLException ex )
		{
			ex.printStackTrace();
		}
    }
    
    //Recibe un numero entero y lo devuelve como Cadena (String)
    private String aCadena(int num)
    {
    	return String.valueOf(num);
    }
    
    //Recibe un numero decimal y lo devuelve como Cadena (String)
    private String aCadena(float num)
    {
    	return String.valueOf(num);
    }
    
    private void mostrar()
    {
        this.setVisible(true);
    }

    public static void main(String args[])
    {
        JfrPrincipal prueba1 = new JfrPrincipal("Recorrer registros de SQL Server en Java",400,400);
        prueba1.mostrar();
    }
}

Y aqui una imagen de la ejecucion:

Ejecucion del ejemplo: Mostrando la tabla alumnos

Ejecucion del ejemplo: Mostrando la tabla alumnos

A diferencia de la otra entrada de blog anterior a esta, ahora se pueden realizar busquedas e igualmente se pueden recorrer los resultados con ayuda de la misma clase. La busqueda se puede realizar por matricula, nombre o por genero (sexo). Por ejemplo en caso de que decidamos buscar en los nombres de los alumnos la cadena ‘ar’, debemos marcar el radio nombre, escribir en la cajita ‘ar’ y dar clic en el boton Buscar en este caso se encontraron 4 resultados, como se muestra en la siguiente imagen:

Buscando por nombre a un alumno

Buscando por nombre a un alumno

Observa como automaticamente se desactivan los controles de busqueda y se muestran los resultados; los cuales tambien se pueden recorrer con los mismos botones de Primero, Anterior, Siguiente y Ultimo. Ademas el texto del boton Buscar cambia y ahora ese boton permite terminar la Busqueda. Al dar click en el boton Fin Busqueda se muestran nuevamente todos los alumnos de la tabla y se despliega el que estaba mostrandose antes de hacer la busqueda. Por ultimo muestro otro pantallazo de una busqueda por Sexo:

Buscando alumnos por sexo

Buscando alumnos por sexo

Como decia anteriormente lo interesante es que si ahora deseamos que la tabla alumnos este creada en MySQL o Postgres, entonces la creamos en dicho manejador (con ayuda del script que puse mas arriba; estan los nombres de los campos y su tipo) y en la linea 402 de la clase JfrPrincipal.java, cambiamos los parametros de Conexion (usuario,pass,bd, manejador) de dicho manejador, la clase automaticamente usara el Driver adecuado y se conectara a dicho DBMS sin problemas.

Sin querer se hizo un poco largo este ejemplo, pero no era para mas, espero haber sido lo suficiente explicito y no haber dejado muchas dudas, los ya avanzados en Java supongo que mi codigo lo habran digerido sin problemas y los que empiezan de todas maneras pregunten sin compromiso, les aseguro que yo tambien soy un novato y seguro hay alguna manera mas fina y elegante de hacer esto del recorrido de registros, solo es una idea. . Y es que a la clase GonzaBD.java la simplifique y le quite mucho codigo para que quedara simple y sencilla de entender ya que mi version original tiene muchos mas metodos para realizar las cuatro Operaciones SQL de manera mas simple (INSERT, DELETE, UPDATE, SELECT), pero me reservo el codigo y posiblemente mas adelante lo libere en este mismo blog, por ahora creo que seria demasiado y requeria mas tiempo para explicarlo y estoy muy ocupado estod dias.

Bueno no me queda mas que decir hasta pronto y si a alguien le interesan los fuentes basta con pedirlos y se los envio, hasta pronto y gracias x visitar.

Encriptar Passwords en MD5 en Java

Encriptar Passwords en MD5 en Java. En vista de que e visto muchos comentarios a la entrada de blog Autentificar usuarios en Java, voi a ampliar un poco ese tema con algo extra. Digo esto porque pienso utilizar estos mismos fundamentos para almacenar los passwords encriptados (en MD5) de los usuarios en la BD. Googleando por la red me encontre (al igual que muchos otros) muchas maneras muy similares de encriptar en MD5, algunas un poco equivocadas, algunas con mas cosas que otras, pero la que mas me gusto es la que voi a mostrar a continuacion.

Antes que todo muestro la configuracion de la computadora en la que hice esta prueba:

Tipo de Computadora: Laptop, Toshiba
S.O.: Linux, distribucion Ubuntu 10.10 [Maverick]
version del Kernel: 2.6.35-27
Version de la JVM: 1.6.0_26

La clase siguiente contiene un metodo muy sencillo que recibe una cadena (String) y regresa otra pero encriptada en MD5. Por si no lo sabias, hasta este momento creo que java no cuenta con algun metodo para encriptar en MD5, asi que tenemos que ingeniarnosla de alguna manera para encriptar en este formato. Bueno el codigo es el siguiente para hacer la encriptacion es:
TestEncriptarMD5.java

/**
 *      Instituto Tecnologico de Zacatepec
 * Descripcion:   Encriptacion de paswords en MD5
 * @author Gonzalo Silverio
 * Fecha: 03-12-2011
 * Archivo:  TestEncriptarMD5.java
 */

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class TestEncriptarMD5
{
	private static final char[] CONSTS_HEX = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
  	public static String encriptaEnMD5(String stringAEncriptar)
	{
		try
		{
		   MessageDigest msgd = MessageDigest.getInstance("MD5");
		   byte[] bytes = msgd.digest(stringAEncriptar.getBytes());
		   StringBuilder strbCadenaMD5 = new StringBuilder(2 * bytes.length);
		   for (int i = 0; i < bytes.length; i++)
		   {
		       int bajo = (int)(bytes[i] & 0x0f);
		       int alto = (int)((bytes[i] & 0xf0) >> 4);
		       strbCadenaMD5.append(CONSTS_HEX[alto]);
		       strbCadenaMD5.append(CONSTS_HEX[bajo]);
		   }
		   return strbCadenaMD5.toString();
		} catch (NoSuchAlgorithmException e) {
		   return null;
		}
	}

	public static void main(String args[])
	{
		System.out.println("\n\nEncriptacion en MD5 de 123: '"+encriptaEnMD5("123")+"'");
		System.out.println("Encriptacion en MD5 de hola: '"+encriptaEnMD5("hola")+"'");
	}
}

Como se puede observar el metodo esta super corto y efectivamente se obtiene la cadena encriptada en MD5 y para probarlo a continuacion la compilacion y ejecucion de la clase anterior:

Ejemplo de encriptacion en MD5 en Java

Ejemplo de encriptacion en MD5 en Java

Bueno hasta pronto y ya sabes si gustan el codigo basta con dejar su email.  Suerte!!

Clase java para recorrer registros de tabla SQL Server con botones primero, anterior, siguiente y ultimo

Clase java para recorrer registros de tabla SQL Server con botones primero, anterior, siguiente y ultimo. El objetivo de esta entrada de blog es mostrar una clase diseñada por mi para facilitar la navegacion por los registros de una tabla. Se me ocurrio esto debido a que en muchas ocasiones en los programas necesitamos recorrer los registros de una tabla con los tipicos botones:
Primero Permite ir al primer registro de la tabla.
Anterior Permite ir al anterior registro.
Siguiente Permite ir al siguiente registro.
Ultimo Permite ir al ultimo registro.

La siguiente imagen muestra un ejemplo clasico donde se requieren estos botones (los botones con flechas verdes):

Ventana con botones de navegacion de registros.
Ventana con botones de navegacion de registros.

Como se puede imaginar con ayuda de estos botones nos podemos colocar en cualquier registro de la tabla y una vez posicionados en el registro deseado se pueden usar otros botones para modificar o eliminar el registro. Bueno sin mas preambulos muestro el codigo de la clase:

GonzaBD.java
El truco de esta clase es almacenar en un array todos los campos llave de la tabla que se desee manipular (por cada tabla se debe crear un nuevo objeto de esta clase). Al llamar al metodo primero() con ayuda de una variable se accede al primer elemento del arreglo de llaves primarias. Al llamar al metodo ultimo() con ayuda de una variable se accede al ultimo elemento del arreglo de llaves primarias. Al llamar al metodo siguiente() con ayuda de una variable; si por ejemplo estamos en la fila 5, se accede al elemento 5 +1, del arreglo de llaves primarias. Despues se realiza un Select hacia la tabla y los datos quedan en un Objeto Resultset (llamado rs) que es local a esta clase. Bueno a continuacion muestro el codigo:

/*
 *   Instituto Tecnologico de Zacatepec
 * Descripcion:  Clase que contiene metodos para recorrer los registros de una tabla
 *						hacia el primer, anterior, siguiente o ultimo registro
 * Archivo: GonzaBD.java
 * author Gonzalo Silverio       gonzasilve@hotmail.com
 * fuente:  https://gonzasilve.wordpress.com
 */
import java.sql.*;

public class GonzaBD
{
	String strSentenciaSQL = "";
	String strCadenaConexion = "";
	String strOrdenarPor = "";
	String strCampoLLave = "";
	String strTabla = "";
	String strArrayCamposLlave[];
	int intArrayCamposLlave[];

	//Los posibles tipos del campo llave son cadena y entero
	//Por defecto el campo llave es de tipo cadena
	String strTipoCampoLlave = "cadena";

	int intTotalRegistros = 0,intFilaActual = 0;

	String strDriverMySQL 		="com.mysql.jdbc.Driver";
	String strDriverPostgres 	="org.postgresql.Driver";
	String strDriverSqlServer 	="net.sourceforge.jtds.jdbc.Driver";

	String strManejador 		= "mysql";
	String strBaseDatos 		= "BD";
	String strServidor 		= "localhost";
	String strUsuario 		= "usuario";
	String strPassword		= "password";
	String strControlador 	= strDriverMySQL;
	String strPuerto			= "3306";

	private static Connection con = null;
	Statement st;
	ResultSet rs;

    public GonzaBD()
    {

    }

    //se mueve a la primera fila y devuelve true si se pudo, false sino se pudo ir a la primera fila
    public  boolean  primero()
    {
      try
		{
			intFilaActual = 0;
			if( strTipoCampoLlave.equals("cadena") )
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"='"+strArrayCamposLlave[intFilaActual]+"'");
			else
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"="+intArrayCamposLlave[intFilaActual]);

			if( rs.next() )
				return true;

			return false;
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }

    //se mueve a la anterior fila y devuelve true si se pudo, false sino se pudo ir a la anterior fila
    public  boolean  anterior()
    {
      try
		{
			intFilaActual--;
			if(intFilaActual<0)
				intFilaActual=0;

			if( strTipoCampoLlave.equals("cadena") )
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"='"+strArrayCamposLlave[intFilaActual]+"'");
			else
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"="+intArrayCamposLlave[intFilaActual]);

			if( rs.next() )
				return true;

			return false;
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }

    //se mueve a la siguiente fila y devuelve true si se pudo, false sino se pudo ir a la siguiente fila
    public  boolean  siguiente()
    {
      try
		{
			intFilaActual++;
			if(intFilaActual>intTotalRegistros-1)
				intFilaActual=intTotalRegistros-1;

			if( strTipoCampoLlave.equals("cadena") )
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"='"+strArrayCamposLlave[intFilaActual]+"'");
			else
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"="+intArrayCamposLlave[intFilaActual]);

			if( rs.next() )
				return true;

			return false;
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }

    //se mueve a la ultima fila y devuelve true si se pudo, false sino se pudo ir a la ultima fila
    public  boolean  ultimo()
    {
      try
		{
			intFilaActual = intTotalRegistros-1;

			if( strTipoCampoLlave.equals("cadena") )
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"='"+strArrayCamposLlave[intFilaActual]+"'");
			else
				rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"="+intArrayCamposLlave[intFilaActual]);

			if( rs.next() )
				return true;

			return false;
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }

	//Obtiene el controlador del manejador mysql o postgres
    public  String obtenerDriverManejador(String manejador)
    {
		if(manejador.equals("sqlserver"))							//Si el manejador es sql server
			return strDriverSqlServer;
		else if(manejador.equals("mysql"))							//Si el manejador es mysql
			return strDriverMySQL;
		else if(manejador.equals("postgres"))							//Si el manejador es postgres
			return strDriverPostgres;

			//en caso d k no sea ninguno devuelve el de MySQL
			return strDriverMySQL;
    }

	//Conecta a la BD con los datos por default
    public boolean conectarBD() throws SQLException
    {
      try
		{
			return conectarServidor(strManejador,strServidor,strUsuario,strPassword,strBaseDatos,strControlador);
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }

	//Conecta a la BD con los datos especificados
    public boolean conectarBD(String usuario, String password, String BD, String manejador) //throws SQLException
    {
    	boolean ress;
      try
		{
			strControlador = obtenerDriverManejador(manejador);
			strUsuario 		= usuario;
			strPassword 	= password;
			strBaseDatos 	= BD;
			strManejador 	= manejador;
			ress = conectarServidor(manejador,strServidor,usuario,password,BD,strControlador);
			return ress;
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }

	//Conecta a la BD con los datos del usuario, bd y password especificados, para los demas toma los k estan por default
    public boolean conectarBD(String usuario, String password, String BD )// throws SQLException
    {
    	boolean ress;
      try
		{
			strUsuario 		= usuario;
			strPassword 	= password;
			strBaseDatos 	= BD;
			ress = conectarServidor(strManejador,strServidor,usuario,password,BD,strControlador);
			return ress;
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
			return false;
		}
    }

    //permite especificar el campo por el que se van a ordenar los registros
    public  void ordenarPor(String campo)
    {
    	strOrdenarPor = campo;
    }

	//Realiza una conexion a sqlserver, mysql o postgres con los datos especificados
    public boolean conectarServidor(String manejador,String servidor,String usuario,String pw,String bd, String driver) throws SQLException
    {
		if(manejador.equals("sqlserver"))							//Si el manejador es sql server
		{
		    try
		    {
		        Class.forName(driver);
		        strCadenaConexion = "jdbc:jtds:sqlserver://"+servidor+"/"+bd+";instance=SQLSERVEREXPRESS;";
		        con = DriverManager.getConnection(strCadenaConexion,usuario,pw);
		        if (con == null )
		    			return false;
		        return true;
		    }
		    catch(SQLException sqlex)
		    {
		    		sqlex.printStackTrace();
		        	return false;
		    }
		    catch(Exception e)
		    {
		    		e.printStackTrace();
		        	return false;
		    }
		}
    	else if(manejador.equals("mysql"))									//Si el manejador es mysql
    	{
           try
           {
		          Class.forName(driver);
		          strCadenaConexion = "jdbc:mysql://"+servidor+"/"+bd;
		          con = DriverManager.getConnection(strCadenaConexion,usuario,pw);
		          if (con == null )
		          	return false;

		          return true;
            }
            catch(SQLException sqlex)
            {
            	sqlex.printStackTrace();
                return false;
            }
            catch(Exception e)
            {
            	e.printStackTrace();
            	return false;
            }
    	}
    	else if(manejador.equals("postgres"))							//Si el manejador es postgress
      {
          try
          {
              Class.forName(driver);
              strCadenaConexion = "jdbc:postgresql://"+servidor+":5432/"+bd;
              con = DriverManager.getConnection(strCadenaConexion,usuario,pw);
              if (con == null )
          			return false;

              return true;
          }
          catch(SQLException sqlex)
          {

          		sqlex.printStackTrace();
              	return false;
          }
          catch(Exception e)
          {
          	e.printStackTrace();
              return false;
          }
      }

	    	return false;
    }

	//Ejecuta un SELECT y devuelve el Resultset con los resultados
	public ResultSet ejecutarConsulta(String cadSQ) throws SQLException
	{
		rs = null;
		if( ! strOrdenarPor.equals("") )
			cadSQ += " ORDER BY " +strOrdenarPor;

		try
		{
			rs = st.executeQuery(cadSQ);
			return rs;
       }
       catch(SQLException sqlex)
       {
       		sqlex.printStackTrace();
       		return rs;
       }

	}

	public  void obtenerCamposLlave()
	{
		obtenerCamposLlave(strTabla);
	}

	//Si el campo llave es de tipo entero guarda los campos llave en un arreglo de enteros
	//Si el campo llave es de tipo cadena guarda los campos llave en un arreglo de Strings
	public  void obtenerCamposLlave(String tabla)
	{
		int c=0;
		try
		{
			rs = ejecutarConsulta("SELECT * FROM " + tabla);
			while(rs.next())
				c++;
			intTotalRegistros = c;
			strArrayCamposLlave = new String[intTotalRegistros];
			intArrayCamposLlave = new int[intTotalRegistros];

			cerrar(rs);		//Cerrar consulta anterior
			//Ejecutar nuevamente la consulta
			rs = ejecutarConsulta("SELECT * FROM " + tabla);
			rs.next();		//Moverse al primer registro

			c=0;
			do
			{			//determina el tipo del campo llave y en base a eso guarda en el array correspondiente
				if( strTipoCampoLlave.equals("cadena") )
					strArrayCamposLlave[c] = rs.getString(strCampoLLave);
				else
					intArrayCamposLlave[c] = rs.getInt(strCampoLLave);

				c++;
			}while( rs.next() );

		}
		catch(SQLException sqlex)
		{
       	sqlex.printStackTrace();
		}

	}

	// Cierra un objeto Resultset
	public static void cerrar(ResultSet rs)
	{
		try
		{
			rs.close();
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}

	// cierra un objeto Statemet
	public static void cerrar(Statement st)
	{
		try
		{
			st.close();
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}

	// Cierra un objeto Connection
	public static void cerrar(Connection con)
	{
		try
		{
			con.close();
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}

	//Permite especificar cual es el campo llave de la tabla
	public  void setCampoLlave(String campo)
	{
		strCampoLLave = campo;
	}

	//Permite especificar cual es el campo llave y su tipo, de la tabla
	public  void setCampoLlave(String campo, String tipo)
	{
		strCampoLLave = campo;
		strTipoCampoLlave = tipo;
	}

	public void setTipoCampoLlave(String tipo)
	{
		strTipoCampoLlave = tipo;
	}

	//Especifica la tabla sobre la k se va a trabajar
	public  void setTabla(String tabla)
	{
		try
		{
			strTabla = tabla;
			st=con.createStatement();
		}
		catch(SQLException ex)
		{
			ex.printStackTrace();
		}

	}
}	//Fin de la clase

Como se puede observar en la linea 229 de la clase GonzaBD.java estoy usando un nombre de instancia llamado SQLSERVEREXPRESS Esta clase se podria editar para recibir tambien como parametro el nombre de la instancia de SQL Server que se desee utilizar, se queda de tarea.

Lo interesante de esta clase es que esta preparada para recorrrer los registros de tablas que esten creadas en cualquera de los manejadores SQL Server, MySQL o de Postgres, obviamente que los .jar de los JConnector de dichos DBMS  deben estar copiados en C:\Program Files\Java\jdk1.6.0_23\jre\lib\ext, Lo que esta en negrita lo e resaltado debido a que la version del JVM puede cambiar segun la que tengas instalada. Los JConnector que e usado para probar esta clase son los siguientes (puedes dar click en el enlace para descargarlo sino lo tienes).
JConnector de SQL Server: jtds-1.2.5.jar
JConnector de Postgres: postgresql-9.1-901.jdbc4.jar
JConnector de MySQL: mysql-connector-java-5.1.18-bin.jar

Para ejemplificar el uso de la clase anterior e usado una tabla que esta en SQL Server. Los parametros de conexion son:
Manejador de Base de datos (DBMS): SQL Server 2005 Express
Base de datos: prueba
Tabla: alumnos
Usuario: sa
Password: root

El Script para crear la tabla alumnos en SQL Server es el siguiente:

create table alumnos(matricula int, nombre char(50), apellidos char(100), edad int, peso decimal(10,2),sexo char(1), PRIMARY KEY(matricula) );

La imagen de la tabla ya creada en SQL Server se ve asi:

Tabla alumnos en SQL Server

Tabla alumnos en SQL Server

DIAGRAMA UML DE LA CLASE gonzaBD

Diagrama UML de la clase gonzaBD

Diagrama UML de la clase gonzaBD

BREVE EXPLICACION DE LOS ATRIBUTOS DE LA CLASE gonzaBD:

Atributo Descripcion
intfilaActual Contiene un número que se usa como índice para acceder a una llave primaria dentro del arreglo strArrayCamposLlave o el arreglo strArrayCamposLlave (dependiendo de si la llave primaria es de tipo cadena o tipo entero, respectivamente). Este atributo contiene el número actual de fila-1.
strArrayCamposLlave[] Arreglo que contiene las llaves primarias de la tabla en caso de que el tipo de dato del campo llave sea Cadena.
intArrayCamposLlave[] Arreglo que contiene las llaves primarias de la tabla en caso de que el tipo de dato del campo llave sea Entero.
rs Contiene los datos de la fila actual mostrandose. Cada vez que se manda a llamar al método primero(), anterior(), siguiente() o ultimo() se realiza una consulta y este atributo (tipo Resultset) se actualiza con los campos de la nueva fila.

COMO SE USA LA CLASE gonzaBD
A continuacion voi a poner un fragmento de codigo con la intencion mostrar los pasos a realizar para usar correctamente la clase.

//Crear un objeto de esta clase
GonzaBD a = new GonzaBD();
//AHORA SE DEBE REALIZAR LO SIGUIENTE EN EL MISMO ORDEN…
//Primeramente se debe indicar especificar cual es la llave primaria de la tabla y su tipo
a.setCampoLlave("matricula","entero");
//Se de desea se puede indicar que si se desean ordenar los registros de la tabla por un campo, //este paso es opcional en todo caso sino se realiza, no se ordenan por ningún campo
a.ordenarPor("nombre");
//A continuación usamos un metodo sobrecargado para conectarse al DBMS, aquí es donde //indicamos a que manejador se debe accesar
a.conectarBD("sa","root","prueba","sqlserver");
//Una vez que ya estamos conectados se debe especificar la tabla que se va a manipular
a.setTabla("alumnos");
//Ahora se manda a llamar al método que rellena el arreglo de llaves primarias dentro de la clase; //dependiendo del tipo de dato del campo llave se rellena el arreglo de Strings o el arreglo de //enteros.
a.obtenerCamposLlave();
//Ahora ya se puede llamar a cualquiera de los métodos primero(), anterior(), siguiente() o ultimo()... 

Despues de realizar lo anterior, para que el objeto rs se rellene con los datos de la primera fila se invoca al metodo:
a.primero();
Después de que se invoco ese metodo, el atributo rs de la clase gonzaBD se quedara con los datos de la fila 1. Supongamos que la tabla “alumnos” contiene las siguientes filas, rs apuntara a la fila:

El atributo rs esta en la posicion de la primera fila.

El atributo rs esta en la posicion de la primera fila.

Si inmediatamente despues se llama al método siguiente()
a.siguiente();
El atributo rs apuntara al siguiente registro despues del primero, es decir rs apuntara a la fila:

El atributo rs apunta a los datos de la segunda fila

El atributo rs apunta a los datos de la segunda fila

Y asi sucesivamente, una observación: si te fijas en el codigo de los metodos (siguiente() y anterior()) cuando se ha llegado a la ultima fila, es decir, si rs apunta al registro 4 y se ejecuta una llamada al método siguiente() (se intenta accesar una fila después de la ultima); dicho método contiene un ‘candado’ para detectar eso y siempre dejara a rs apuntando al ultimo registro. El método anterior() igualmente tiene esa precaucion y siempre que se intente accesar a un registro antes del primero automáticamente moverá a rs para que apunte a la primera fila. De esta manera no es posible sobrepasar los limites (inferior ni superior) de filas de la tabla que se este manipulando.

Finalmente Para ilustrar el uso de la clase gonzaBD anterior he creado una ventana muy basica.

JfrPrincipal.java
Esta clase crea una ventana de formulario con 6 campos y los 4 botones; primero, anterior, siguiente y ultimo en la parte inferior de dicha ventana. Es la misma clase que utilice para ilustrar como usar ventanas de formulario en Java, pero la he modificado y adaptado para este ejemplo mas elaborado. Bueno ahora muestro el codigo:

/*
 *   Instituto Tecnologico de Zacatepec
 * Descripcion:  Clase que crea una GUI para ilustrar el uso de la clase EasyBD
 * Archivo: JfrPrincipal.java
 * author: Gonzalo Silverio       gonzasilve@hotmail.com
 * fuente:  https://gonzasilve.wordpress.com
 */

import javax.swing.*;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

//Se usara para cambiar los Margenes de los botones
import java.awt.Insets;

//Para Manejo de BD
import java.sql.*;

public class JfrPrincipal extends JFrame
{
	//Campos de texto y sus etiquetas 
	JLabel jlbMatricula;    JTextField  jtfMatricula;
	JLabel jlbNombre;       JTextField  jtfNombre;
	JLabel jlbApellidos;    JTextField  jtfApellidos;
	JLabel jlbEdad;         JTextField  jtfEdad;
	JLabel jlbPeso;         JTextField  jtfPeso;
	JLabel jlbSexo;         JComboBox   jcbSexo;
	
	//Botones de navegacion de los registros
	JButton btnPrimero;
	JButton btnAnterior;
	JButton btnSiguiente;
	JButton btnUltimo;
	
	Box boxVCamposVentana;   //Contiene todo los campos de texto (con su respectiva etiqueta)
	JPanel panBotones;      //Contiene los botones Guardary Cancelar
	
	//Objeto de la clase que nos ayuda a navegar por los registros de la tabla
	GonzaBD bd = new GonzaBD();
	
	JfrPrincipal(String strTitulo, int intAncho, int intAlto)
	{
		super(strTitulo);
		this.setSize(intAncho, intAlto);
		this.setResizable(false);		//Ventana no redimensionable
		this.setLocationRelativeTo(null);       //Centrar ventana en pantalla
		
		//Box vertical por que los botones van a estar abajo
		Box boxVContenidoVerticalVentana = Box.createVerticalBox();
		crearCamposVentana();
		crearBotones();
		//Espacio del borde superior de la ventana al primer Campo
		boxVContenidoVerticalVentana.add(Box.createVerticalStrut(30));
		boxVContenidoVerticalVentana.add(boxVCamposVentana);
		//Espacio entre el ultimo campo (sexo) y los botones Guardar y Cancelar
		boxVContenidoVerticalVentana.add(Box.createVerticalStrut(20));
		boxVContenidoVerticalVentana.add(panBotones);
		
		this.add(boxVContenidoVerticalVentana);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	  
	  //Conecta la Base de datos
		conectarBD();
		bd.primero();		//Posicionarse en el primer registro
		rellenarCampos();		//Rellenar los campos con los datos del primer registro
		
		//ASIGNAR UN ESCUCHADOR PARA CADA BOTON DE NAVEGACION
		//Boton Primero
		btnPrimero.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent evt) 
			{
				bd.primero();
				rellenarCampos();
			}
		});
		//Boton Anterior
		btnAnterior.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent evt) 
			{
				bd.anterior();
				rellenarCampos();
			}
		});
		//Boton Siguiente
		btnSiguiente.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent evt) 
			{
				bd.siguiente();
				rellenarCampos();
			}
		});
		//Boton Ultimo
		btnUltimo.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent evt) 
			{
				bd.ultimo();
				rellenarCampos();
			}
		});
		  	
        	
	}		//Fin del constructor

	//Crea los campos de la ventana (cada caja tiene su correspondiente etiqueta)
    private void crearCamposVentana()
    {
        Box boxHMatricula =  Box.createHorizontalBox();        
        jlbMatricula = new JLabel("Matricula ");   jtfMatricula = new JTextField(15);
        boxHMatricula.add(Box.createHorizontalStrut(20));
        boxHMatricula.add(jlbMatricula);
        boxHMatricula.add(Box.createHorizontalStrut(14));
        boxHMatricula.add(jtfMatricula);
        JPanel panMatricula =  new JPanel(new FlowLayout(FlowLayout.LEFT) );
        panMatricula.add(boxHMatricula);

        Box boxHNombre =  Box.createHorizontalBox();
        jlbNombre = new JLabel("Nombre ");   jtfNombre = new JTextField(15);
        boxHNombre.add(Box.createHorizontalStrut(20));
        boxHNombre.add(jlbNombre);
        boxHNombre.add(Box.createHorizontalStrut(20));
        boxHNombre.add(jtfNombre);
        JPanel panNombre =  new JPanel(new FlowLayout(FlowLayout.LEFT) );
        panNombre.add(boxHNombre);

        Box boxHApellidos =  Box.createHorizontalBox();
        jlbApellidos = new JLabel("Apellidos ");   jtfApellidos = new JTextField(15);
        boxHApellidos.add(Box.createHorizontalStrut(20));
        boxHApellidos.add(jlbApellidos);
        boxHApellidos.add(Box.createHorizontalStrut(11));
        boxHApellidos.add(jtfApellidos);
        JPanel panApellidos =  new JPanel(new FlowLayout(FlowLayout.LEFT) );
        panApellidos.add(boxHApellidos);

        Box boxHEdad =  Box.createHorizontalBox();
        jlbEdad = new JLabel("Edad ");   jtfEdad = new JTextField(15);
        boxHEdad.add(Box.createHorizontalStrut(20));
        boxHEdad.add(jlbEdad);
        boxHEdad.add(Box.createHorizontalStrut(40));
        boxHEdad.add(jtfEdad);
        JPanel panEdad =  new JPanel(new FlowLayout(FlowLayout.LEFT) );
        panEdad.add(boxHEdad);
        
        Box boxHPeso =  Box.createHorizontalBox();
        jlbPeso = new JLabel("Peso ");   jtfPeso = new JTextField(15);
        boxHPeso.add(Box.createHorizontalStrut(20));
        boxHPeso.add(jlbPeso);
        boxHPeso.add(Box.createHorizontalStrut(40));
        boxHPeso.add(jtfPeso);
        JPanel panPeso =  new JPanel(new FlowLayout(FlowLayout.LEFT) );
        panPeso.add(boxHPeso);

        Box boxHSexo =  Box.createHorizontalBox();
        jlbSexo = new JLabel("Sexo ");   jcbSexo = new JComboBox();
        jcbSexo.addItem("Masculino");
        jcbSexo.addItem("Femenino");
        boxHSexo.add(Box.createHorizontalStrut(20));
        boxHSexo.add(jlbSexo);
        boxHSexo.add(Box.createHorizontalStrut(40));
        boxHSexo.add(jcbSexo);
        JPanel panSexo =  new JPanel(new FlowLayout(FlowLayout.LEFT) );
        panSexo.add(boxHSexo);

        boxVCamposVentana = Box.createVerticalBox();
        boxVCamposVentana.add(panMatricula);
        boxVCamposVentana.add(Box.createVerticalStrut(10));
        boxVCamposVentana.add(panNombre);
        boxVCamposVentana.add(Box.createVerticalStrut(10));
        boxVCamposVentana.add(panApellidos);
        boxVCamposVentana.add(Box.createVerticalStrut(10));
        boxVCamposVentana.add(panEdad);
        boxVCamposVentana.add(Box.createVerticalStrut(10));
        boxVCamposVentana.add(panPeso);
        boxVCamposVentana.add(Box.createVerticalStrut(10));
        boxVCamposVentana.add(panSexo);
    }

    private void crearBotones()
    {
        Box boxHBotones = Box.createHorizontalBox();
        
        btnPrimero = new JButton("|< Primero");
        btnAnterior = new JButton("< Anterior");
        btnSiguiente = new JButton("Siguiente >");
        btnUltimo = new JButton("Ultimo >|");
        //Cambiar los margenes de los botones
        			//Insets(margen_sup, margen_izq, margen_inf, margen_der)
        btnPrimero.setMargin(new Insets(0, 2, 0, 2));
        btnAnterior.setMargin(new Insets(0, 2, 0, 2));
        btnSiguiente.setMargin(new Insets(0, 2, 0, 2));
        btnUltimo.setMargin(new Insets(0, 2, 0, 2));
        
        boxHBotones.add(btnPrimero);
        boxHBotones.add(Box.createHorizontalStrut(20));
        boxHBotones.add(btnAnterior);
        boxHBotones.add(Box.createHorizontalStrut(20));
        boxHBotones.add(btnSiguiente);
        boxHBotones.add(Box.createHorizontalStrut(20));
        boxHBotones.add(btnUltimo);
        
        panBotones =  new JPanel(new FlowLayout(FlowLayout.CENTER) );
        panBotones.add(boxHBotones);
    }
	//Conecta con la BD y devuelve true si se conecto correctamente
	//false en cualquiero otro caso
	public boolean conectarBD()
	{
		// Especificar cual es la llave primaria de la tabla y su tipo
		bd.setCampoLlave("matricula","entero");
    	bd.ordenarPor("nombre");	//Ordena los registros de la tabla por este campo
		
		//Conecta con el usuario, pass, BD y dbms (manejador) especificados
		bd.conectarBD("sa","root","prueba","sqlserver");
		
    	//especifica la tabla sobre la que se va a manipular
    	bd.setTabla("alumnos");
    	//Dentro del objeto bd rellena un arreglo con las llaves 
    	//primarias de la tabla que se esta manipulando
		bd.obtenerCamposLlave();
		
		return true;
	}
	
	//Rellena los campos de texto con los datos del registro actual
    public void rellenarCampos()
    {
		try
		{
    		jtfMatricula.setText(aCadena(bd.rs.getInt("matricula")));
    		jtfNombre.setText(bd.rs.getString("nombre").trim ());
    		jtfApellidos.setText(bd.rs.getString("apellidos").trim ());
    		jtfEdad.setText(aCadena(bd.rs.getInt("edad")));
    		jtfPeso.setText(aCadena(bd.rs.getFloat("peso")));
    		jcbSexo.setSelectedItem( bd.rs.getString("sexo").equals("f") ? "Femenino" : "Masculino" );
    		
    		this.setTitle("Alumno "+(bd.intFilaActual+1)+" de "+bd.intTotalRegistros);
		}
		catch( SQLException ex )
		{
			ex.printStackTrace();
		}
    }
    
    //Recibe un numero entero y lo devuelve como Cadena (String)
    private String aCadena(int num)
    {
    	return String.valueOf(num);
    }
    
    //Recibe un numero decimal y lo devuelve como Cadena (String)
    private String aCadena(float num)
    {
    	return String.valueOf(num);
    }
    
    private void mostrar()
    {
        this.setVisible(true);
    }

    public static void main(String args[])
    {
        JfrPrincipal prueba1 = new JfrPrincipal("Recorrer registros de SQL Server en Java",400,400);
        prueba1.mostrar();
    }
}

Y aqui una imagen de la ejecucion:

Ejecucion de la clase que recorre registros de tabla de SQL Server.

Ejecucion de la clase que recorre registros de tabla de SQL Server.

Como decia anteriormente lo interesante es que si ahora deseamos que la tabla alumnos este creada en MySQL o Postgres, entonces la creamos en dicho manejador (con ayuda del script que puse mas arriba) y en la linea 216 de la clase JfrPrincipal.java, cambiamos los parametros de Conexion (usuario,pass,bd, manejador) de dicho manejador, la clase automaticamente usara el Driver adecuado y se conectara a dicho DBMS sin problemas.

Sin querer se hizo un poco largo este ejemplo, pero no era para mas, espero haber sido lo suficiente explicito y no haber dejado muchas dudas, los ya avanzados en Java supongo que mi codigo lo habran digerido sin problemas y los que empiezan de todas maneras pregunten sin compromiso, les aseguro que yo tambien soy un novato y seguro hay alguna manera mas fina y elegante de hacer esto del recorrido de registros, solo es una idea. . Y es que a la clase GonzaBD.java la simplifique y le quite mucho codigo para que quedara simple y sencilla de entender ya que mi version original tiene muchos mas metodos para realizar las cuatro Operaciones SQL de manera mas simple (INSERT, DELETE, UPDATE, SELECT), pero me reservo el codigo y posiblemente mas adelante lo libere en este mismo blog, por ahora creo que seria demasiado y requeria mas tiempo para explicarlo y estoy en el fin de mi ultimo semestre de la carrera!!! poryectos por aqui, proyectos por allaa.

Bueno no me queda mas que decir hasta pronto y si a alguien le interesan los fuentes basta con pedirlos y se los envio, hasta pronto y gracias x visitar.

Como generar un PDF con datos de una tabla MySQL con ayuda de iText

Ejemplo muy sencillo donde se ilustra como generar un documento PDF con datos provenientes de una tabla creada en MySQL con la libreria iText. Bueno creo que el titulo de la entrada lo dice todo asi que no quiero ser redundante en el objetivo de esta practica de programacion.

El ejemplo consta de 3 archivos: CrearConexion.java, GenerarPDFEmpleados.java JfrPrincipal.java (a decir verdad tambien se usa una imagen (logo de mysql), pero puedes cambiarla por otra que quieras). Como en casi todos mis ejemplos, no voi a dar mucha explicacion debido a que mi objetivo es tener disponible el ejemplo de codigo. Primero que nada te muestro un diagrama para que veas en forma grafica y rapida la estructura del ejemplo:

Diagrama que muestra en forma grafica el ejemplo

Diagrama que muestra en forma grafica el ejemplo

A continuacion se explican brevemente los tres archivos de codigo a grandes rasgos:

JfrPrincipal
Clase que crea una interfaz grafica de usuario muy sencilla; la cual es una ventana con 2 JLabels, un JTextField y un JButton. Desde esta clase se hace una instancia de la clase GenerarPDFEmpleados.java, la cual es la que realmente genera el PDF con ayuda de la libreria iText. En el codigo se muestran los comentarios correspondiente explicando casi todo…

/*
		Instituto Tecnologico de Zacatepec, Mor.
Descripcion:  Clase que crea una ventana con un boton que al darle clic
					genera el PDF de una tabla de MySQL.
Autor:  			Gonzalo Silverio   gonzasilve@gmail.com
Archivo: 		JfrPrincipal.java
*/

import javax.swing.*;
import java.awt.FlowLayout;
import java.awt.event.*;

public class JfrPrincipal extends JFrame
{
	String strTituloPDF = "INSTItuTO TEcnologico de zacatepec";
	String strNombrePDF = "pdf_tabla_Empleados.pdf";
	JTextField jtfNombrePDF;
	
	//Constructor
	JfrPrincipal(String titulo, int ancho, int alto)
	{
		//Establecer titulo, tamanio y posicion en la pantalla
		super(titulo);
		setSize(ancho,alto);
		setLocationRelativeTo(null);	//centrado
		//Rotulo principal de la ventana
		JLabel lblTitulo = new JLabel("Generar un PDF desde Java");
		JPanel panTitulo = new JPanel(new FlowLayout(FlowLayout.CENTER));
		panTitulo.add(lblTitulo);
		
		//Crea campo de texto para especificar el nombre del PDF
		JLabel lblNombrePDF = new JLabel("Nombre del documento PDF");
		jtfNombrePDF = new JTextField(30);
		jtfNombrePDF.setText(strNombrePDF);
		jtfNombrePDF.setHorizontalAlignment (JTextField.CENTER);
		JPanel panNombrePDF = new JPanel(new FlowLayout(FlowLayout.CENTER));
      panNombrePDF.add(Box.createHorizontalStrut(15));
		panNombrePDF.add(lblNombrePDF);
		panNombrePDF.add(jtfNombrePDF);
		
		//Crear el boton nuevo
		JButton btnGenerarPDF = new JButton("Generar PDF");
		JPanel panGenerarPDF = new JPanel(new FlowLayout(FlowLayout.CENTER));
		panGenerarPDF.add(btnGenerarPDF);

		//Todos los componentes estan en un Box Vertical
		//la clase Box se usa para alinear los controles
		Box boxVertical = Box.createVerticalBox();
		boxVertical.add(Box.createVerticalStrut(50));
		boxVertical.add(panTitulo);
		boxVertical.add(panNombrePDF);
		boxVertical.add(Box.createVerticalStrut(10));
		boxVertical.add(panGenerarPDF);

		//Agregar el Box a la ventana
		add(boxVertical);
		setResizable(false);	//No maximizar ni cambiar tamanio
		//Al dar en la X terminar todo el programa
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    	// ########### ESCUCHADOR BOTON NUEVO   ##########
    	ActionListener escuchadorGenerarPDF = new ActionListener()
    	{
        	public void actionPerformed(ActionEvent evt)
        	{
        		strNombrePDF = jtfNombrePDF.getText();
            GenerarPDFEmpleados ejemplo = new GenerarPDFEmpleados(strTituloPDF,strNombrePDF);
       		//Preguntar al usuario si desea abrir el documento PDF
       		int respuesta = JOptionPane.showConfirmDialog(null,"Se ha generado el documento "+strNombrePDF+", ¿Desea abrirlo?","Pregunta",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);
       		//Si la respuesta es SI, abrirlo
				if(respuesta == JOptionPane.YES_OPTION)
					ejemplo.abrirPDF ();
          
        	}
   	};
    	btnGenerarPDF.addActionListener(escuchadorGenerarPDF);

    	
	}	//Fin del constructor

	//hace visible la ventana	
	public void mostrar()
	{
		setVisible(true);
	}

	public static void main(String[] args) 
   {
		JfrPrincipal ejemplo = new JfrPrincipal("Ventana principal de Usuario",400,400);
		ejemplo.mostrar();
   }
}

Y a continuacion una imagen de la GUI que se genera:

GUI para el ejemplo

GUI para el ejemplo

El primer Jlabel es un rotulo para la ventana, el segundo Jlabel es una etiqueta para el JTextField con la cual se le indica al usuario que debe escribir el nombre del documento PDF (con extension), el JTextField es el campo donde el uuario debe escribir el nombre del PDF. El JButton al darle click; el usuario generara el documento PDF de una tabla llamada Empleados e inmediatamente se le preguntara si desea abrirlo, aca una imagen:

Pregunta al usuario si desea abrir el PDF

Pregunta al usuario si desea abrir el PDF


Si el usuario da click en el boton Si del mensaje llama al metodo abrirPDF() de un objeto de la clase GenerarPDFEmpleados.java el cual abrira en una nueva ventana el documento PDF dentro del cual se muestra el contenido de la tabla empleados, aca una imagen del PDF:
PDF generado con datos de tabla empleados creada en MySQL

PDF generado con datos de tabla empleados creada en MySQL

GenerarPDFEmpleados.java
En esta clase es donde se hace uso de la libreria iText para generar un documento PDF. El codigo de esta clase es el siguiente:


//		Instituto Tecnologico de Zacatepec
//  	Descripcion:  Programa que genera un archivo PDF con datos de una base de datos
//		en mySQL y con ayuda de la libreria iText
//  	Author: Gonzalo Silverio   gonzasilve@hotmail.com
//		Archivo: GenerarPDFEmpleados.java

import java.awt.Color;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;

import com.lowagie.text.Anchor;
import com.lowagie.text.BadElementException;
import com.lowagie.text.Cell;
import com.lowagie.text.Chapter;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Font;
import com.lowagie.text.List;
import com.lowagie.text.ListItem;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Section;
import com.lowagie.text.Table;
import com.lowagie.text.Element;
import com.lowagie.text.PageSize;

import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfPTable;

import com.lowagie.text.Image;

import java.sql.*;

public class GenerarPDFEmpleados
{
	private String strNombreDelPDF;

	private  Font fuenteNegra10 = new Font(Font.TIMES_ROMAN, 10, Font.BOLD, Color.BLACK);
	private  Font fuente8 = new Font(Font.TIMES_ROMAN, 8, Font.NORMAL, Color.BLACK);
	private  Font fuenteAzul25 = new Font(Font.TIMES_ROMAN, 25, Font.BOLD, Color.BLUE);

	Color grisClaro = new Color( 230,230,230);	
	Color azulClaro = new Color( 124,195,255 );

	//############# VARIABLES PARA MANEJO DE BASE DE DATOS ########################
	//Guarda la consulta operacion a realizar
	String strConsultaSQL;
	//Apuntador a la conexion
	Connection conn = null;	
	//Para ejecutar operaciones SQL
	Statement estSQL1;
	//Para guardar los resultados de una operacion SELECT
	ResultSet rs;
	Document document;
	PdfWriter writer;
	String strRotuloPDF;
	
	//Metodo principal del ejemplo
	public GenerarPDFEmpleados(String titulo, String nomPDF)
	{
		strRotuloPDF = titulo;
		strNombreDelPDF = nomPDF;
		try 
		{		//Hoja tamanio carta, rotarla (cambiar a horizontal)
			document = new Document( PageSize.LETTER.rotate() );
			
			writer = PdfWriter.getInstance(
			// that listens to the document
					document,
					// direccionar el PDF-stream a un archivo
					new FileOutputStream(strNombreDelPDF));
			document.open();

			agregarMetaDatos(document);
			agregarContenido(document);
			
			document.close();
			
			System.out.println("Se ha generado el PDF: "+ strNombreDelPDF);
				
		} catch (Exception e) 
		{
			e.printStackTrace();
		}
	}
	
	//agrega el contenido del documento; para este ejemplo agrega una tabla con datos y una imagen
	//Espera como entrada el documento donde agregara el contenido
	private void agregarContenido(Document document) throws DocumentException
	{
		Paragraph ParrafoHoja = new Paragraph();
				
		// Agregamos una linea en blanco al principio del documento
		agregarLineasEnBlanco(ParrafoHoja, 1);
		// Colocar un encabezado (en mayusculas)
		ParrafoHoja.add(new Paragraph(strRotuloPDF.toUpperCase (), fuenteAzul25) );
		agregarLineasEnBlanco(ParrafoHoja, 1);
		// 1.- AGREGAMOS LA TABLA
		agregarTabla(ParrafoHoja);
		//Agregar 2 lineas en blanco
		agregarLineasEnBlanco(ParrafoHoja, 2);
		// 2.- AGREGAMOS LA IMAGEN
		try
		{
			Image im = Image.getInstance("logo_mysql.gif");
			im.setAlignment(Image.ALIGN_CENTER | Image.TEXTWRAP );
			im.setWidthPercentage (50);
	      ParrafoHoja.add(im);
		}
		catch(Exception e)
		{
			e.printStackTrace ();
		}
		
		document.add(ParrafoHoja);

	}

	//Se conecta al DBMS MySQL , obtiene los datos de la tabla (SELECT) y los acomoda en una tabla JTable de iText.
	// Espera como entrada el parrafo donde agregara la tabla
	private void agregarTabla(Paragraph parrafo) throws BadElementException 
	{
		//Anchos de las columnas
		float anchosFilas[] = { 0.2f,1f,1f,0.5f,0.5f,0.3f,1f,1.5f,0.7f };
		PdfPTable tabla = new PdfPTable(anchosFilas);
		String rotulosColumnas[] = {"id","Nombre","Apellidos","Sexo","Telefono","Edad","Correo","Direccion","Fecha\nContratacion"};
		// Porcentaje que ocupa a lo ancho de la pagina del PDF
		tabla.setWidthPercentage(100);
		//Alineacion horizontal centrada
		tabla.setHorizontalAlignment(Element.ALIGN_CENTER);
		//agregar celda que ocupa las 9 columnas de los rotulos
		PdfPCell cell = new PdfPCell(new Paragraph("Tabla: Empleados"));
		cell.setColspan(9);
		//Centrar contenido de celda
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		//Color de fondo de la celda
		cell.setBackgroundColor (azulClaro);		
		tabla.addCell(cell);

    	try
    	{
			if ( ConectarBD() )
			{
				// Mostrar los rotulos de las columnas
				for(int i=0; i<rotulosColumnas.length; i++)
				{
					cell = new PdfPCell(new Paragraph(rotulosColumnas[i],fuenteNegra10));
					cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
					cell.setHorizontalAlignment(Element.ALIGN_CENTER);
					cell.setBackgroundColor (grisClaro);
					tabla.addCell(cell);
				}
				
				//Consultar la tabla empleados
				strConsultaSQL = "SELECT * FROM empleados";
				//ejecutar consulta
				rs = estSQL1.executeQuery(strConsultaSQL);

				//Iterar Mientras haya una fila siguiente
	   		while (rs.next())
	   		{			//Agregar 9 celdas
					cell = new PdfPCell(new Paragraph(String.valueOf(rs.getInt ("idEmpleado")),fuente8 ));
					tabla.addCell(cell);
					cell = new PdfPCell(new Paragraph(rs.getString("nombre"),fuente8));
					tabla.addCell(cell);
					cell = new PdfPCell(new Paragraph(rs.getString("apellidos"),fuente8));
					tabla.addCell(cell);
					cell = new PdfPCell(new Paragraph(rs.getString("sexo"),fuente8));
					tabla.addCell(cell);
					cell = new PdfPCell(new Paragraph(rs.getString("telefono"),fuente8));
					tabla.addCell(cell);
					cell = new PdfPCell(new Paragraph(String.valueOf(rs.getInt("edad")),fuente8) );
					tabla.addCell(cell);
					cell = new PdfPCell(new Paragraph(rs.getString("correo"),fuente8));
					tabla.addCell(cell);
					cell = new PdfPCell(new Paragraph(rs.getString("direccion"),fuente8));
					tabla.addCell(cell);
					cell = new PdfPCell(new Paragraph(rs.getDate("fechaContratacion").toString (),fuente8 ) );
					tabla.addCell(cell);
   			}
   			
	        	//Cerrar los objetos de manejo de BD
	        	CrearConexion.cerrar(rs);			//ResultSet
	        	CrearConexion.cerrar(estSQL1);	//Statement
	        	CrearConexion.cerrar(conn);		//Connection
			}		//Fin de if que comprueba si se pudo conectar
			
		}
		catch(Exception e) 
		{
	    	System.out.println("Excepcion al ejecutar CONSULTA!!!");
	    	//Mostrar la traza de la pila
	    	e.printStackTrace();
		}
		//Agregar la tabla con los datos al parrafo que nos llego como entrada
		parrafo.add(tabla);
	}  //Fin del metodo que crea la tabla

	//Agrega las lineas en blanco  especificadas a un parrafo especificado
	private static void agregarLineasEnBlanco(Paragraph parrafo, int nLineas) 
	{
		for (int i = 0; i < nLineas; i++) 
			parrafo.add(new Paragraph(" "));
	}
	
	//Agrega los metadatos del documento, los metadatos a asignar son
	//Titulo, Asunto, Palabras clave, Autor y el sw o org con el cual fue generado
	private static void agregarMetaDatos(Document document)
	{
		document.addTitle("Documento con datos de tabla MySQL");
		document.addSubject("Usando iText y MySQL");
		document.addKeywords("Java, PDF, iText");
		document.addAuthor("Gonzalo Silverio");
		document.addCreator("https://gonzasilve.wordpress.com");
	}

	//devuelve true en caso de que si se pudo conectar
	//devuelve false sino se logro conectar
	public boolean ConectarBD() throws Exception
	{
	    try
	    {		
	    		//Aqui se instancia a la otra clase --> CrearConexion.java	    		
	    		//y se le mandan en el constructor los datos de conexion
	     		CrearConexion con  = new CrearConexion("root","root","prueba");
	     		//Obtiene una referencia a la conexion abierta
	     		conn = con.getConnection();
	      	
	      	//Comprobar si hay una refencia valida
	      	if(conn!=null)
	      	{
					//Mostrar MSG al usuario de la conexion se ha establecido
					System.out.println("Conexion establecida");
	     			//Se prepara para ejecutar sentencias en la conexion recien abierta
	      		estSQL1 = conn.createStatement();
					return true;
	      	}
	      	else
	      		return false;
	      		
	  	 }
	    catch (SQLException e)
	    {
	    	
	      // the above drop statements will throw exceptions
	      // if the types and tables did not exist before. Just ingore it.
	      System.out.println("Error en la conexion!!!");
	      e.printStackTrace();
	      return false;
	    }
	    		
	}
	
	//Abre el documento PDF
	public void abrirPDF()
	{
  		/* Abrir el archivo PDF */
		try 
		{
			Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + strNombreDelPDF);
		}
		catch (IOException e) 
		{
			e.printStackTrace();
		}	
	}	
}

Como se observa en el metodo conectarBD() se hace una instancia de la clase CrearConexion.java y se le mandan en el constructor los datos con los que se conectara a MySQL.

Los datos que se usan para conectarse al DBMS son:
Usuario: root
Password: root
Base de datos: prueba
Tabla: empleados
Host: localhost

Y la estructura de la tabla empleados es:

Estructura de la tabla empleados usada en este ejemplo

Estructura de la tabla empleados usada en este ejemplo

CrearConexion.java
Este archivo tiene como funcion la apertura de una conexion al DBMS MySQL y devuelve la referencia a traves de su metodo getConnection(). En el constructor recibe los datos que seran usados por el JConnector, el codigo de este archivo es:

// 		Instituto Tecnologico de Zacatepec
 // Descripcion: Clase para manejo de base de datos de MySQL
 // Author Gonzalo Silverio    gonzasilve@hotmail.com
 // Archivo: CrearConexion.java


import java.sql.*;

public class CrearConexion 
{
	//Datos por default de la conexion
	static String strUsuario = "usr";
	static String strPassword = "pw";
	static String strBaseDatos ="bd";
	static String strHost = "localhost";
	
	//Constructor, le llegan los datos con los que se conectara al DBMS
	public CrearConexion(String usr,String pw, String bd)
	{
		strUsuario = usr;
		strPassword = pw;
		strBaseDatos =bd;
		try
		{
			Class.forName("com.mysql.jdbc.Driver");		
		} catch ( ClassNotFoundException e )
		{
			System.out.println("ERROR: Error al cargar la clase del Driver");		
		}
	}
	
	//Constructor, le llegan los datos con los que se conectara al DBMS
	// a dif. del otro constructor le llega tbn el host (servidor)
	public CrearConexion(String usr,String pw, String bd,String srvr)
	{
		strUsuario = usr;
		strPassword = pw;
		strBaseDatos =bd;
		strHost = srvr;
		try
		{
			//Cargar el driver
			Class.forName("com.mysql.jdbc.Driver");		
		} catch ( ClassNotFoundException e )
		{
			System.out.println("ERROR: Error al cargar la clase del Driver\n");
			e.printStackTrace();
		}
	}
	
	public static Connection getConnection() throws SQLException 
	{
		//a continuacion vamos a formar la cadena de conexion, pero...
		//OJO aca debes poner el nombre de la instancia de SQL Server que vas a usar
		String url = "jdbc:mysql://"+strHost+"/"+strBaseDatos;
		return DriverManager.getConnection(url,strUsuario,strPassword);
	}

	//Cierra objeto Resultset
	public static void cerrar(ResultSet rs)
	{	
		try
		{
			rs.close();
		} 
		catch(Exception ex)
		{}
	}
	
	//Cierra objeto Statement
	public static void cerrar(Statement st)
	{
		try
		{
			st.close();
		} 
		catch(Exception ex)
		{}
	}
	
	//Cierra objeto Connection
	public static void cerrar(Connection con)
	{	
		try
		{
			con.close();
		} 
		catch(Exception ex)
		{}
	}
}	//Fin de la clase

Como se puede ver esta clase es la misma que use en el ejemplo Acceso a Base de datos de SQL Server desde java (Jconnector).

Eso es todo, hasta pronto y espero comentarios al respecto. ya sabes si quieres los fuentes, basta con pedirlos dejando tu mail. Suerte, bye.

Uso de la clase StringTokenizer para realizar un analizador sintactico de SQL

Uso de la clase StringTokenizer para realizar una analizador sintactico de las operaciones SQL INSERT, DELETE, UPDATE o SELECT. Como he mostrado anteriormente el uso de la clase StringTokenizer es muy sencillo. Asi que ahora quisiera aportar una idea acerca de como se podria implementar el analizador sintactico para alguna de las 4 operaciones SQL. El ejemplo solamente es una clase y solamente da una idea de como iniciar el analisis de la sintaxis de la Operacion INSERT de SQL, SOLAMENTE ES UNA IDEA y es la siguiente:

/*
 *    Instituto Tecnologico de Zacatepec
 *	Descripcion Ejemplo2 de uso de la clase StringTokenizer
 * author Gonzalo Silverio    gonzasilve@hotmail.com
 * version 1.00 
 * Archivo: EjemploTokenizer2.java
 */

import java.util.StringTokenizer;

public class EjemploTokenizer2
{
	//Guarda las tablas validas donde se puede realizar el INSERT, DELETE, UPDATE o un SELECT
	// este arreglo se puede rellenar con info de alguna fuente exterior a este
	//programa; por ejemplo de una B.D.
	static String tablasValidas[] = {"alumnos","profesores","calificaciones","materias","etc"};
    
    //Analiza la sintaxis de la operacion INSERT de SQL
    public static void analizarOperacionInsert(String cadena)
    {
		StringTokenizer tok1 = new StringTokenizer(cadena);
		String finCadena = new String();
    	//Guardara el token actualmente leido
    	String tokenActual;
    	
    	//salta el INSERT (en el main ya se comprobo que si era la palabra INSERT)
		tok1.nextToken();
		//guarda SEGUNDO token (INTO)
		tokenActual = tok1.nextToken();
		
		//Comprueba si realmente es la palabra INTO
		if(! tokenActual.equals ("INTO") )
		{
			System.out.println ("Se esperaba la palabra clave INTO, no '"+tokenActual+"'");
			return;
		}
		
		//guarda SEGUNDO token (Nombre de la tabla donde se desea hacer el INSERT)
		tokenActual = tok1.nextToken();
		
		//Comprueba si es una tabla valida
		if( ! buscar_tabla(tokenActual) )
		{
			System.out.println ("La tabla '"+tokenActual+"' NO EXISTE o NO es una tabla valida.");
			return;
		}
		
		tokenActual = tok1.nextToken(); 	//guarda lo de values y todo lo demas
		
		StringTokenizer tok2 = new StringTokenizer(tokenActual,"(");
		String cadValues;
		cadValues = tok2.nextToken();
		
		//Comprueba si realmente es la palabra VALUES
		if(! cadValues.equals ("VALUES") )
		{
			System.out.println ("Se esperaba la palabra clave VALUES, no '"+cadValues+"'");
			return;
		}
		//Muestra los tokens que estan despues del parentesis
		System.out.println("\n\n"+tok2.nextToken());
		
		//Y asi sucesivamente se seguiria analizando la sintaxis de la Operacion INSERT de SQL
		//bla, bla, bla
		
    }  // Fin de metodo analizarOperacionDelete();
    
    //Analiza la sintaxis de la operacion DELETE de SQL
    public static void analizarOperacionDelete(String cadena)
    {
    	//Aqui se analizaria la sintaxis del DELETE
    }
    
    //Analiza la sintaxis de la operacion UPDATE de SQL
    public static void analizarOperacionUpdate(String cadena)
    {
    	//etc
    }
    
    //Analiza la sintaxis de la operacion SELECT de SQL
    public static void analizarOperacionSelect(String cadena)
    {
    	
    }
    
   //Devuelve true si la cadena que llega esta dentro de un arreglo de Strings,
   //devuelve  false en caso contrario; busca la tabla que llega dentro de las tablas validas
   public static boolean buscar_tabla(String nomTabla)
   {
      for(int i = 0;i< tablasValidas.length;i++)
      {
         if( tablasValidas[i].equals(nomTabla) )
				return true;
      }
      return false;
   }

    public static void main(String gonza[])
    {
    	//Cadena a ser analizada
    	String cadena = "INSERT INTO alumnos VALUES('s1','intel','cuerna',245)";
    	//String cadena = "Delete FROM alumnos where matricula='00547264'";
    	//String cadena = "UPDATE alumnos SET nombre='Fabian', apellidos='Granados P.' where matricula='00664326'";
    	
    	//Guardara el token actualmente leido
    	String tokenActual;

		StringTokenizer st = new StringTokenizer(cadena);
		
		//Guarda el primer token
		tokenActual = st.nextToken();
		
		//Convertimos toda la cadena a MAYUSCULAS para hacerla case insensitive
		// (NO sensible a las mayusculas/minusculas)
		tokenActual = tokenActual.toUpperCase();
		
		//EMPEZAMOS POR REVISAR EL PRIMER TOKEN, si es una de las 4 Operaciones SQL
		if( tokenActual.equals ("INSERT") || tokenActual.equals ("DELETE")  || tokenActual.equals ("UPDATE") || tokenActual.equals ("SELECT"))
		{
			if (tokenActual.equals ("INSERT"))
				analizarOperacionInsert(cadena);
			else if (tokenActual.equals ("DELETE"))
				analizarOperacionDelete(cadena);
			else	if (tokenActual.equals ("UPDATE"))
				analizarOperacionUpdate(cadena);
			else	if (tokenActual.equals ("SELECT"))
				analizarOperacionSelect(cadena);
		}
		else
			System.out.println("No es una operacion SQL valida, solo se permite INSERT,DELETE,UPDATE o SELECT");
		
		
    }  //Fin del metodo main()
    
    
}

Observa como en el metodo main() se especifica la operacion SQL a analizar (linea 101), obviamente esa cadena se debe obtener de alguna caja de texto donde escribio el usuario o dejar que la teclee el usuario por la consola, yo la he puesto en una variable directamente para fines didacticos y por que solmente quiero mostrar mi idea. Ahora una imagen de la ejecucion y compilacion del ejemplo (sin errores de sintaxis):

Ejecucion1 de ejemplo de analisis sintactico de INSERT de SQL

Ejecucion1 de ejemplo de analisis sintactico de INSERT de SQL

Ahora supongamos que en la cadena escribimos mal la palabra INTO y pusimos INTOO, asi;

String cadena = "INSERT INTOO alumnos VALUES('s1','intel','cuerna',245)";

(esto lo cambias en la linea 101) observa ahora la ejecucion, nos marca error de sintaxis!!!

Ejecucion2 de ejemplo de analisis sintactico de INSERT de SQL

Ejecucion2 de ejemplo de analisis sintactico de INSERT de SQL

Ahora supongamos que escribimos un nombre de tabla que no es ninguna de las tablas validas; escribimos la tabla salarios, asi;

 
String cadena = "INSERT INTO salarios VALUES('s1','intel','cuerna',245)";

(esto lo cambias en la linea 101) observa ahora la ejecucion, nos marca error de sintaxis!!!, la tabla no existe!!

Ejecucion3 de ejemplo de analisis sintactico de INSERT de SQL

Ejecucion3 de ejemplo de analisis sintactico de INSERT de SQL

Ahora supongamos que olvidamos escribir la palabra INTO, asi;

String cadena = "INSERT alumnos VALUES('s1','intel','cuerna',245)";

(esto lo cambias en la linea 101) observa ahora la ejecucion, nos marca error de sintaxis!!!.

Ejecucion4 de ejemplo de analisis sintactico de INSERT de SQL

Ejecucion4 de ejemplo de analisis sintactico de INSERT de SQL

Es todo, y si quieres el .java ya sabes, pidelo en un comentario y te lo envio. hasta pronto.

Uso de la clase StringTokenizer

Uso de los metodos basicos de la clase StringTokenizer; nextToken(),hasMoreTokens(),countTokens(). En esta ocasion voi a mostrar el uso de tres metodos de la clase StringTokenizer. Esta clase permite obtener por separado las palabras (tokens) que conforman una cadena, para obtener las palabras separadas se puede especificar el separador que hay entre estas, por defecto sino se indica Java asume que el separador es el espacio. Esta clase tiene varios constructores pero a mi principalmente me parecen interesantes dos:

El primero recibe como entrada una cadena, la cual es obviamente la cadena que contiene las palabras que se quieren obtener por separado. En este ejemplo voi a suponer que se desea obtener los tokens de una cadena la cual es una de las 4 operaciones SQL (INSERT, DELETE, UPDATE o SELECT). Ejemplos del uso de este constructor:

//La clase se encuentra en el paquete java.util
import java.util.StringTokenizer;
//Ejemplo del uso del contructor1, donde java asume el espacio como separador
StringTokenizer token1 = new StringTokenizer("SELECT nombre,apellidos,edad FROM alumnos");
StringTokenizer token2 = new StringTokenizer("EJEMPLO DE UNA CADENA PARA EFECTOS DE PRUEBA");
StringTokenizer token3 = new StringTokenizer("Instituto Tecnologico de Zacatepec");

Las cadenas anteriores tienen 4,8,4 tokens respectivamente.
El segundo constructor recibe como entrada una cadena y un caracter separador (en realidad puede ser otra cadena). Ejemplos:

//La clase se encuentra en el paquete java.util
import java.util.StringTokenizer;
//Ejemplo del uso del contructor2, donde se especifica explicitamente el separador de los tokens
StringTokenizer token1 = new StringTokenizer("04-04-2011","-");
StringTokenizer token2 = new StringTokenizer("gonzasilve:x:502:502:   Gonzalo Silverio:/home/gonzasilve:/bin/bash",":");

Ahora las cadenas anteriores tienen 3 y 7 tokens respectivamente. Ojo, observa que el espacio ya no es el separador en ninguna de las cadenas anteriores, por eso tienen ese numero de tokens.

Bueno ahora vamos con los metodos, los describo brevemente a continuacion:

nextToken()
Devuelve una subcadena (String) que es el siguiente token de la cadena. Imaginemos que cada vez que se llama a este metodo hay un apuntador y el cual se posiciona en el siguiente token. Observa la siguiente imagen

Uso del metodo nextToken() de la clase StringTokenizer

Uso del metodo nextToken() de la clase StringTokenizer

La primera vez que se llama a este metodo, el apuntador esta posicionado en la primera palabra por lo tanto el metodo devolveria el token «INGENIERIA» y el apuntador se mueve al siguiente token.
La segunda vez que se llama a este metodo, el apuntador esta posicionado en la segunda palabra por lo tanto el metodo devolveria el token «EN» y el apuntador se mueve al siguiente token.
La tercera vez que se llama a este metodo, el apuntador esta posicionado en la tercera palabra por lo tanto el metodo devolveria el token «SISTEMAS» y el apuntador se mueve al siguiente token.
La cuarta vez que se llama a este metodo, el apuntador esta posicionado en la cuarta palabra por lo tanto el metodo devolveria el token «COMPUTACIONALES» y el apuntador se mueve al siguiente token.

Ahora observa la siguiente imagen donde se observa la posicion donde quedo el apuntador despues de llamar por cuarta vez al metodo nextToken():

Uso del metodo nextToken() de la clase StringTokenizer

Uso del metodo nextToken() de la clase StringTokenizer


Si se llama por quinta vez al metodo nextToken() ocurrira una excepcion porque ya no hay un siguiente token.

hasMoreTokens()
Devuelve un valor de tipo boolean (true o false) que indica si hay (true) un siguiente token. Sino hay un siguiente token devuelve false.

countTokens()
Devuelve un entero (int) que es el numero de tokens de la cadena. Bueno a continuacion muestro un ejemplo mas elaborado que muestra el uso de estos tres metodos. No explico el codigo debido a que ya puse comentarios.

/*
 *    Instituto Tecnologico de Zacatepec
 *	Descripcion Ejemplo1 de uso de la clase StringTokenizer
 * author Gonzalo Silverio    gonzasilve@hotmail.com
 * version 1.00 
 * Archivo: EjemploTokenizer1.java
 */

import java.util.StringTokenizer;

public class EjemploTokenizer1
{
	StringTokenizer st;
	//Recine como entrada la cadena de la cual se quieren sacar su tokens
	public EjemploTokenizer1(String cadena)
	{
		st = new StringTokenizer(cadena);
	}
    
    //Muestra en la consola los tokens de la cadena
	public void mostrarTokens()
	{
		//Mientras haya mas tokens
		//hasMoreTokens() devuelve true si hay un siguiente token o  false si ya no hay
		while (st.hasMoreTokens())
		{
		    System.out.println(st.nextToken());
		}		
	}

    //Devuelve un String con el siguiente token
	public String siguienteToken()
	{
		//El metodo nextToken devuelve un string con el siguiente token
		return st.nextToken();
	}
	   
   //Devuelve el numero de tokens que tiene la cadena
	public int contarTokens()
	{
		return st.countTokens();
	}
	
	//hasMoreTokens() devuelve true si hay un siguiente token o  false si ya no hay
	public boolean hayOtroToken()
	{
		return st.hasMoreTokens();		
	}
	
    public static void main(String gonza[])
    {
    	//Reinicializar objeto con cadena SQL
    	EjemploTokenizer1 objeto1 = new EjemploTokenizer1("SELECT nombre,apellidos,edad FROM alumnos");
    	System.out.println("tokens en esta cadena: "+ objeto1.contarTokens () );
    	System.out.println(objeto1.siguienteToken() );	//Muestra SELECT
    	System.out.println(objeto1.siguienteToken() ); 	//Muestra los campos seleccionados
    	System.out.println(objeto1.siguienteToken() );	//Muestra FROM
    	System.out.println(objeto1.siguienteToken() );	//Muestra el nombre de la tabla
    	System.out.println("hay otro token: "+ objeto1.hayOtroToken () );	//Muestra si hay otro token
    	
    	//Se reinicializa el objeto con otra cadena SQL
    	objeto1 = new EjemploTokenizer1("INSERT  INTO S VALUES('s1','intel','cuerna',245)");
    	System.out.println("\ntokens en esta cadena: "+ objeto1.contarTokens () );
    	objeto1.mostrarTokens();
    	
    	
    }
    
}

Ahora una imagen de la compilacion y ejecucion de este ejemplo:

Compilacion  y ejecucion del ejemplo StringTokenizer

Compilacion y ejecucion del ejemplo StringTokenizer

Bueno, eso es todo y ya sabes si quieres el .java basta con pedirlo. Hasta pronto y gracias por tu visita.