domingo, noviembre 14, 2010

Java - Google Web Toolkit con Java - GWT con Java


"Si usa algún código del siguiente tutorial, den el icono de ME GUSTA del Facebook que se encuentra en su mano derecha, para que se vuelva Seguidor del Blog y también comentenos que tal les pareció el tutorial"


1. Entorno


  • JDK 6 Update 21
  • Eclipse Helios
  • GWT para Eclipse Helios (Google Update Site for Eclipse 3.6 - http://dl.google.com/eclipse/plugin/3.6)

2. Introducción


Actualmente, la creación de aplicaciones web resulta un proceso pesado y propenso a errores. Los desarrolladores pueden pasar el 90% de su tiempo estudiando las peculiaridades de los navegadores. Por otra parte, la creación, la reutilización y el mantenimiento de una gran cantidad de componentes AJAX y bases de código JavaScript pueden ser tareas complejas y delicadas.
GWT permite crear aplicaciones AJAX en el lenguaje de programación Java que son compiladas posteriormente por GWT en código JavaScript ejecutable optimizado que funciona automáticamente en los principales navegadores.

3. Desarrollo


Lo que se piensa desarrollar es un ejemplo de tablas dinámicas y combo anidados que siempre usamos en nuestras aplicaciones sin necesidad de tener que refrescar toda la pagina. No vamos a usar a Base de Datos para el ejemplo, solo lo vamos a manejar con array de forma temporal la información.

3.1. Crear proyecto en Eclipse Helios

Debemos de crear un proyecto del tipo Aplicación Web para GWT. Para eso se debe de primero tener instalado GWT en Eclipse.


















Como nombre al proyecto le vamos a poner "GWTConEclipse" y dejamos activados los checkbox para usar GWT y GOOGLE APP ENGINE, aunque este ultimo no lo utilizaremos, pero en ciertas aplicaciones GWT se necesita el Google App.



















Y nos crea una estructura de proyecto como la que se mostrara en la siguiente figura. La clase "GWTConEclipse.java"  es el Servlet encargado de controlar las peticiones desde la parte Web del GWT. Es justo en este archivo donde vamos a desarrollar nuestro ejemplo



















El formulario que deseamos desarrollar es el que se mostrara a continuación. El ejemplo trata de hacer un pantalla para el Mantenimiento(Registro, Actualización, Eliminación y Búsqueda) de los datos de un Alumno. El combo de la Escuela se carga en función de la Facultad que ustedes seleccionan, estamos desarrollando un combo anidado usando GWT.














3.2. Crear clase Alumno

Primero debemos de crear (agregar) una clase Alumno que va  a tener toda la información del alumno que vamos a registrar dentro del paquete "com.hwongu.client"

package com.hwongu.client;

public class Alumno {

 private int codigo;
 private String nombre;
 private String apellido;
 private String facultad;
 private String escuela;
 private String categoria;
 private double monto;
    
 public Alumno(){
    this.codigo=0;
    this.nombre="";
    this.apellido="";
    this.facultad="";
    this.escuela="";
    this.categoria="";
    this.monto=0;
 }
    
 public Alumno(int codigo, 
    String nombre, 
    String apellido, 
    String facultad, 
    String escuela, 
    String categoria, 
    double monto) {
    this.codigo=codigo;
    this.nombre = nombre;
    this.apellido = apellido;
    this.facultad = facultad;
    this.escuela = escuela;
    this.categoria = categoria;
    this.monto = monto;
 }
 public String toString(){
      return apellido + ", "+ nombre; 
 }
 public int getCodigo(){
    return codigo;
 }
 public void setCodigo(int codigo){
    this.codigo=codigo;
 }
 public String getNombre() {
    return nombre;
 }
 public void setNombre(String nombre) {
    this.nombre = nombre;
 }
 public String getApellido() {
    return apellido;
 }
 public void setApellido(String apellido) {
    this.apellido = apellido;
 }
 public String getFacultad() {
    return facultad;
 }
 public void setFacultad(String facultad) {
    this.facultad = facultad;
 }
 public String getEscuela() {
    return escuela;
 }
 public void setEscuela(String escuela) {
    this.escuela = escuela;
 }
 public String getCategoria() {
     return categoria;
 }
 public void setCategoria(String categoria) {
    this.categoria = categoria;
 }
 public double getMonto() {
    return monto;
 }
 public void setMonto(double monto) {
     this.monto = monto;
 }
}

3.3. Agregando los componentes para el diseño

Lo primero que se debe de hacer es comenzar a declarar los componentes (variables) que tendra el formulario en la clase "GWTConEclipse.java", los componentes que vamos a utilizar son las siguientes:

private VerticalPanel principal = new VerticalPanel();
private Label lblNombre = new Label("Nombre: ");
private TextBox txtNombre = new TextBox();
private Label lblApellido = new Label("Apellido: ");
private TextBox txtApellido = new TextBox();
private Label lblFacultad = new Label("Facultad: ");
private ListBox cboFacultad = new ListBox();
private Label lblEscuela = new Label("Escuela: ");
private ListBox cboEscuela = new ListBox();
private Label lblCategoria = new Label("Categoria: ");
private RadioButton rbtA = new RadioButton("categoria", "Categoria A");
private RadioButton rbtB = new RadioButton("categoria", "Categoria B");
private RadioButton rbtC = new RadioButton("categoria", "Categoria C");
private Button btnAgregar = new Button("Agregar");
private Label lblTiempo = new Label();
// Componente tipo tabla que nos permite agregar componentes
// le decimos el numero de filas y de columnas que va a tener
private Grid gridPrincipal = new Grid(6, 2);
// Tabla principal
private FlexTable tablaAlumnos = new FlexTable();
// Array con datos
private ArrayList<Alumno> listaAlumnos = new ArrayList<Alumno>();
//Indice para saber si se esta editando
private int indiceEditar = -1;
//Codigo del alumno que registro
private int codigo=1;

El codigo anterior lo ponemos justamente después de la declaración de la clase. Despues debemos de crear un metodo para llenar las Facultades de la escuela.

// Llena el combo de facultades
private void llenarFacultades() {
  this.cboFacultad.addItem("Ingenieria");
  this.cboFacultad.addItem("Ciencias Agrarias");
  this.cboFacultad.addItem("Arquitectura Urbanismo y Artes");
  this.cboFacultad.addItem("Ciencias de la Comunicacion");
  this.cboFacultad.addItem("Educacion y Humanidades");
  this.cboFacultad.addItem("Derecho y Ciencias Politicas");
  this.cboFacultad.addItem("Medicina Humana");
  this.cboFacultad.addItem("Ciencia de la Salud");
  this.cboFacultad.addItem("Ciencias Economicas");
}

Creamos un método para que llenen el combo de Escuela en función a  la Facultad que hemos seleccionado

// Llena el combo de Escuelas en funcion de la Facultad
private void llenarEscuelas() {
  //Limpiamos el combo de la escuela
  this.cboEscuela.clear();
  switch (cboFacultad.getSelectedIndex()) {
  case 0:
    this.cboEscuela.addItem("Ingenieria de Computacion y Sistemas");
    this.cboEscuela.addItem("Ingenieria de Software");
    this.cboEscuela.addItem("Ingenieria de Telecomunicaciones y Redes");
    this.cboEscuela.addItem("Ingenieria Civil");
    this.cboEscuela.addItem("Ingenieria Electronica");
    break;
  case 1:
    this.cboEscuela.addItem("Ingenieria Agronoma");
    this.cboEscuela.addItem("Veterinaria");
    this.cboEscuela.addItem("Industrias Alimentarias");
    break;
  case 2:
    this.cboEscuela.addItem("Arquitectura");
    break;
  case 3:
    this.cboEscuela.addItem("Ciencia de la Comunicacion");
    break;
  case 4:
    this.cboEscuela.addItem("Educacion Inicial");
    this.cboEscuela.addItem("Educacion Primaria");
    break;
  case 5:
    this.cboEscuela.addItem("Derecho");
    break;
  case 6:
    this.cboEscuela.addItem("Medicina");
    this.cboEscuela.addItem("Psicologia");
    this.cboEscuela.addItem("Estomatologia");
    break;
  case 7:
    this.cboEscuela.addItem("Enfermeria");
    break;
  case 8:
    this.cboEscuela.addItem("Contabilidad");
    this.cboEscuela.addItem("Administracion");
    this.cboEscuela.addItem("Economia y Finanzas");
    break;
  }
}

Despues debemos de crear un método para limpiar las cajas de textos, los combo box cada vez que se haga una actualización o un registro.

//Limpia los datos del formulario
private void limpiar() {
  this.txtNombre.setText("");
  this.txtApellido.setText("");
  this.cboFacultad.setSelectedIndex(0);
  this.llenarEscuelas();
  this.rbtA.setValue(true);
  this.indiceEditar = -1;
}

Luego hacemos un método para seleccionar ciertos elementos del combo cuando deseamos editar la información de un alumno.

//Selecciona la facultad cuando lo vamos editar
//Men=La Facultad seleccionada
private void seleccionarFacultad(String men) {
  for (int i = 0; i < this.cboFacultad.getItemCount(); i++) {
   if (this.cboFacultad.getItemText(i).equals(men)) {
     this.cboFacultad.setSelectedIndex(i);
   }
  }
}
//Seleccion la escuela cuando lo vamos editar
//Men=La Escuela seleccionada
private void seleccionarEscuela(String men) {
  this.llenarEscuelas();
  for (int i = 0; i < this.cboEscuela.getItemCount(); i++) {
   if (this.cboEscuela.getItemText(i).equals(men)) {
     this.cboEscuela.setSelectedIndex(i);
   }
  }
}

Y debemos de crear un método para poder registrar y actualizar un Alumno dentro de nuestro array que actua como nuestra base de datos temporal.

//Agregar un alumno a la tabla o modificarlo
private void agregarAlumno() {
 String nombre = this.txtNombre.getText().toUpperCase().trim();
 String apellido = this.txtApellido.getText().toUpperCase().trim();
 String facultad = this.cboFacultad.getItemText(this.cboFacultad.getSelectedIndex());
 String escuela = this.cboEscuela.getItemText(this.cboEscuela.getSelectedIndex());
 // Que solo permita letras y 20 caracteres
 if (!nombre.matches("^[A-Z\\.\\ ]{1,20}$")) {
  // Manda mensaje alerta tipo JavaScrip
  Window.alert("Nombre no valido");
  this.txtNombre.selectAll();
  // Salimos del metodo
  return;
 }
 if (!apellido.matches("^[A-Z\\.\\ ]{1,20}$")) {
   // Manda mensaje alerta tipo JavaScrip
   Window.alert("Apellido no valido");
   this.txtApellido.selectAll();
   return;
 }
 String categoria;
 double monto;
 if (this.rbtA.getValue()) {
  categoria = this.rbtA.getText();
  monto = 440;
 } else if (this.rbtB.getValue()) {
  categoria = this.rbtB.getText();
  monto = 400;
 } else {
  categoria = this.rbtC.getText();
  monto = 330;
 }
 //Creamos la clase que vamos a registrar o a modificar
 final Alumno alu = new Alumno(codigo, 
        nombre, 
    apellido, 
    facultad, 
    escuela, 
    categoria, 
    monto);
 // 1. Obtener nº de filas
 int filas = this.tablaAlumnos.getRowCount();
 // 2. Agrego a mi array el elemento
 if (this.indiceEditar == -1) {
  //Si indice = -1 es porque vamos a registrar un elemento a mi array
  this.listaAlumnos.add(alu);
 } else {
  //Si indice es diferente es poque estamos editando la información
  this.listaAlumnos.set(this.indiceEditar, alu);
 }
 if (this.indiceEditar == -1) {
  // 3. Agrego a mi tabla
  this.tablaAlumnos.setText(filas, 0, String.valueOf(this.codigo));
  this.codigo++;
  this.tablaAlumnos.setText(filas, 1, alu.toString());
  this.tablaAlumnos.setText(filas, 2, facultad);
  this.tablaAlumnos.setText(filas, 3, escuela);
  this.tablaAlumnos.setText(filas, 4, categoria);
  this.tablaAlumnos.setText(filas, 5, String.valueOf(monto));
  //En el constructor se pone la ubicación de la imagen que esta
  //en la carpeta "images"
  PushButton btnEliminar = new PushButton(new Image("images/eliminar.png"));
  //El tamaño del boton
  btnEliminar.setWidth("16px");
  btnEliminar.setHeight("16px");
  btnEliminar.addClickHandler(new ClickHandler() {
   //Agregamos el evento clic al boton eliminar, que eliminara un elemento
   //de la tabla
   @Override
   public void onClick(ClickEvent event) {
    int filaDel = listaAlumnos.indexOf(alu);
    listaAlumnos.remove(filaDel);
    tablaAlumnos.removeRow(filaDel + 1);
   }
  });
  this.tablaAlumnos.setWidget(filas, 6, btnEliminar);
  PushButton btnEditar = new PushButton(new Image("images/editar.png"));
  btnEditar.setWidth("16px");
  btnEditar.setHeight("16px");
  btnEditar.addClickHandler(new ClickHandler() {
   //Agregamos el evento clic al boton modificar, que mostrara los datos
   //del alumno seleccionado en las cajas de texto y combos
   @Override
   public void onClick(ClickEvent event) {
    indiceEditar=listaAlumnos.indexOf(alu);
    Alumno aluTemp = listaAlumnos.get(indiceEditar);
    txtNombre.setText(aluTemp.getNombre());
    txtApellido.setText(aluTemp.getApellido());
    seleccionarFacultad(aluTemp.getFacultad());
    seleccionarEscuela(aluTemp.getEscuela());
    if (aluTemp.getCategoria().equals(rbtA.getText())) {
     rbtA.setValue(true);
    } else if (aluTemp.getCategoria().equals(rbtB.getText())) {
     rbtB.setValue(true);
    } else {
     rbtC.setValue(true);
    }
   }
  });
  this.tablaAlumnos.setWidget(filas, 7, btnEditar);
  // 4. Formatos, agregamos formatos css, que se encuentra
  // En el archivo GWTConEclipse.css
  this.tablaAlumnos.getCellFormatter().addStyleName(filas, 
        5,"columnaNumerica");
  this.tablaAlumnos.getCellFormatter().addStyleName(filas, 
        6,"columnaBoton");
  this.tablaAlumnos.getCellFormatter().addStyleName(filas, 
        7,"columnaBoton");
 }else{
  //Estamos editando la información del alumno o actualizando la 
  //información del mismo
  this.tablaAlumnos.setText(this.indiceEditar+1, 1, alu.toString());
  this.tablaAlumnos.setText(this.indiceEditar+1, 2, facultad);
  this.tablaAlumnos.setText(this.indiceEditar+1, 3, escuela);
  this.tablaAlumnos.setText(this.indiceEditar+1, 4, categoria);
  this.tablaAlumnos.setText(this.indiceEditar+1, 5, String.valueOf(monto));
 }
 this.limpiar();
}

Y finalmente creamos un método para poder cargar los componentes de la pagina web cuando se cargue el proyecto.

public void onModuleLoad() {
 // Fila del Nombre
 this.gridPrincipal.setWidget(0, 0, this.lblNombre);
 this.gridPrincipal.setWidget(0, 1, this.txtNombre);
 // Fila del Apellido
 this.gridPrincipal.setWidget(1, 0, this.lblApellido);
 this.gridPrincipal.setWidget(1, 1, this.txtApellido);
 // Fila de la Facultad
 this.gridPrincipal.setWidget(2, 0, this.lblFacultad);
 this.gridPrincipal.setWidget(2, 1, this.cboFacultad);
 this.llenarFacultades();
 this.cboFacultad.addChangeHandler(new ChangeHandler() {
  public void onChange(ChangeEvent event) {
    llenarEscuelas();
  }
 });
 this.cboFacultad.setSelectedIndex(0);
 // Fila de la Escuela
 this.gridPrincipal.setWidget(3, 0, this.lblEscuela);
 this.gridPrincipal.setWidget(3, 1, this.cboEscuela);
 this.llenarEscuelas();
 // Fila de la Categoria
 this.gridPrincipal.setWidget(4, 0, this.lblCategoria);
 Grid gridCategoria = new Grid(1, 3);
 gridCategoria.setWidget(0, 0, this.rbtA);
 gridCategoria.setWidget(0, 1, this.rbtB);
 gridCategoria.setWidget(0, 2, this.rbtC);
 this.gridPrincipal.setWidget(4, 1, gridCategoria);
 // Seleccionar la categoria A por defecto
 this.rbtA.setValue(true);
 // Fila del Boton
 this.gridPrincipal.setWidget(5, 0, this.btnAgregar);
 this.gridPrincipal.setWidget(5, 1, this.lblTiempo);
 this.lblTiempo.setText(new java.util.Date().toString());
 // Agregando el Grid
 this.principal.add(gridPrincipal);
 // Creando la tabla
 // Estableciendo el nombre a las columnas
 this.tablaAlumnos.setText(0, 0, "Codigo");
 this.tablaAlumnos.setText(0, 1, "Alumno");
 this.tablaAlumnos.setText(0, 2, "Facultad");
 this.tablaAlumnos.setText(0, 3, "Escuela");
 this.tablaAlumnos.setText(0, 4, "Categoria");
 this.tablaAlumnos.setText(0, 5, "Monto");
 this.tablaAlumnos.setText(0, 6, "Eliminar");
 this.tablaAlumnos.setText(0, 7, "Editar");
 this.tablaAlumnos.addStyleName("estiloTabla");
 // Agregando los estilos a las columnas
 this.tablaAlumnos.getRowFormatter().addStyleName(0, "cabezeraTabla");
 this.tablaAlumnos.getCellFormatter().addStyleName(0, 5,"columnaNumerica");
 // Agregando la tabla de alumnos
 this.principal.add(this.tablaAlumnos);
 // Asociando nuestro codigo con nuestro Html
 RootPanel.get("principal").add(principal);
 // Creamos el evento click del boton
 this.btnAgregar.addClickHandler(new ClickHandler() {
  @Override
  public void onClick(ClickEvent event) {
   // Nombre del envento a desencadenar
   agregarAlumno();
  }
 });
 //Actualizar hora
 //Creando un timer para simular cambios 
 Timer timer=new Timer() {
  @Override
  public void run() {
    //Va a llamar un metodo
    lblTiempo.setText(new java.util.Date().toString());
  }
 };
 //Cada 1000 ms se llamara al metodo run del Timer
 timer.scheduleRepeating(1000);
}

Y eso son los métodos necesarios para poder realizar el mantenimiento de la información de un Alumno

3.4. Pagina GWTConEclipse.html

Modificar la pagina "GWTConEclipse.html" para que pueda ser llamado a traves de la clase anterior


<!doctype html>
<html>
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 <link type="text/css" rel="stylesheet" href="Sesion09.css">
  <title>Man. Alumnos - Henry Wong</title>
    <script type="text/javascript" language="javascript" src="sesion09/sesion09.nocache.js"></script>
  </head>
  <body>
 <center>
  <h1>REGISTRO DE ALUMNOS</h1>
 </center>
    <div id="principal"></div>
      <iframe src="javascript:''" 
  id="__gwt_historyFrame" 
       tabIndex="position:absolute;width:0;height:0;border:0">
   </iframe>
  </body>
</html>

3.5. El archivo GWTConEclipse.css

El archivo "GWTConEclipse.css" tiene la siguiente información


h1 {
  font-size: 2em;
  font-weight: bold;
  color: #777777;
  margin: 40px 0px 70px;
  text-align: center;
}
.sendButton {
  display: block;
  font-size: 16pt;
}
.gwt-DialogBox {
  width: 400px;
}
.dialogVPanel {
  margin: 5px;
}
.serverResponseLabelError {
  color: red;
}
#closeButton {
  margin: 15px 6px 6px;
}
body {
  padding: 10px;
}
.cabezeraTabla {
  background-color: #2062B8;
  color: white;
  font-style: italic;
}
.estiloTabla {
  border: 1px solid silver;
  padding: 2px;
  margin-bottom:6px;
}
.columnaNumerica {
  text-align: right;
  width:4em;
}
.columnaBoton {
  text-align: center;
}

4. Ejemplo de la aplicación


4.1. Ejecutar la aplicación

Para ejecutar la aplicación debemos de ejecutarla como una aplicación del tipo Google para ellos hacemos clic derecho en el proyecto creado, luego nos vamos a "Run As" y seleccionamos "Web Aplication" de Google.

















Luego nos sale una dirección electrónica que lo copias y lo pegamos en nuestro navegador para poder ejecutar la aplicación.









4.1. Registrar Alumno
















4.2. Eliminar al alumno

Hacemos clic en el botón de eliminar de alumno con código 2
















4.3. Modificar a un alumno

Haces clic en el botón de Editar del Alumno con código 1 y veremos que su información se nuestra en las cajas de texto, los combos y los radio button














Modificamos su información y luego damos clic en el botón "Agregar" y veremos que su información se actualizara en la tabla

2 comentarios:

Hola amigo excelente tutorial sobre Google Web Tookit. Hace dos dias comence a empaparme sobre esta nueva herramienta de google y me ha parecido muy interesante. Queria hacerte una pregunta. No existe una herramienta que me ayude a diseñar el componente visual de un proyecto. Muchas Gracias!!!!!!!!!!

Hola gracias por los saludos .. Una herramienta para diseño visual lo puedes encontrar en http://marketplace.eclipse.org/content/gwt-designer-gui-builder . Saludos