Mostrando las entradas con la etiqueta GWTEXT. Mostrar todas las entradas
Mostrando las entradas con la etiqueta GWTEXT. Mostrar todas las entradas

lunes, 1 de febrero de 2010

RCP en Gwt (Netbeans gwt-ext)

Hola:

Para esta entrada es necesario que tengan configurado previamente un proyecto con gwt en Netbeans y también configurado en plugin de gwt-ext (jar).

Primero me gustaría hablar de las ventajas de Gwt y después hablar de las desventajas.

- Todo lo programas en Back End, lo que quiere decir que no tienes que aprender forzosamente html, css, javaScript solo tienes que saber java, el Front End lo programas en Back End aunque suene extraño asi es, el compilador de gwt se encarga de generar un codigo optimo en js para tu aplicación.

- La manera de hacer peticiones asíncronas se hacen de manera rápida por medio de RCP.

- La curva de aprendizaje es rápida.

- Las aplicaciones funcionan en la mayoría de los navegadores (IE,Firefox).

Bueno después de esta breve introducción vamos a crear una aplicación que de administre usuarios un CRUD.

Paso 1: Como siempre crear un bean que es parte del modelo para este ejemplo se llamara el clásico usuario, es muy importante que lo coloquen en el paquete donde van a poner su Gwt Modulo.

Para nuestro ejemplo tendremos que crear nuestro paquete del modelo y view al nivel de: org.aplication.client donde va todo en codigo que se convierte en Front End.

Despues creamos un clase de llamada Usuario dentro del paquete org.aplication.client.modelo


Creamos una clase llamada Usuario.

package org.aplication.client.modelo;

import com.google.gwt.user.client.rpc.IsSerializable;

/**
*
* @author isaac
*/
public class Usuario implements IsSerializable{

private String nombre;
private String apellido;
private int edad;
private int cve;

public String getApellido() {
return apellido;
}

public void setApellido(String apellido) {
this.apellido = apellido;
}

public int getCve() {
return cve;
}

public void setCve(int cve) {
this.cve = cve;
}

public int getEdad() {
return edad;
}

public void setEdad(int edad) {
this.edad = edad;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}



}

Esta clase implementa IsSerializable de gwt que es la que encargara de serializar nuestra clase y permite la comunicación entre en cliente y el servidor.

Paso 2. Creamos un paquete llamado view (org.aplication.client.view) y una clase llamada GuiUsuario, el diagrama de clase Uml para esta clase sera mas o menos como este aunque despues iremos agregando mas metodos o clases.



Bueno primero crearemos nuestro formulario y despues nuestro rcp.


package org.aplication.client.view;

import com.gwtext.client.core.EventObject;
import com.gwtext.client.core.Position;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.MessageBox;
import com.gwtext.client.widgets.Window;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.form.FormPanel;
import com.gwtext.client.widgets.form.TextField;
import org.aplication.client.modelo.Usuario;

/**
*
* @author isaac
*/
public class GuiUsuario {

private Usuario usuario;
private Window window;
private FormPanel formPanel;
private TextField nombre;
private TextField apellido;
private TextField edad;

public FormPanel getFormPanel() {
formPanel = new FormPanel();
formPanel.setFrame(true);
formPanel.setTitle("Usuario");
nombre = new TextField("Nombre", "nombre", 230);
apellido = new TextField("Apellido", "apellido", 230);
edad = new TextField("Edad", "edad", 230);
formPanel.add(nombre);
formPanel.add(apellido);
formPanel.add(edad);
return formPanel;

}

public Usuario getUsuario() {
return usuario;
}
public Window getWindow() {
window = new Window();
window.setTitle("Layout Window");
window.setClosable(true);
window.setWidth(600);
window.setHeight(350);
window.setPlain(true);
window.setCloseAction(Window.HIDE);
window.add(getFormPanel());

Button buttonNewUser = new Button("Nuevo Usuario"); buttonNewUser.addListener(new ButtonListenerAdapter(){
@Override public void onClick(Button button, EventObject e) {

MessageBox.alert("prueba de evento");


}
} ); window.setButtonAlign(Position.CENTER);
window.addButton(buttonNewUser); return window; }

public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}



}

El metodo getWindow() se encarga de crear la ventana y tambien de crear el FormPanel por medio del metodo getFormPanel(), despues solo hace falta llamar a nuestra Gui desde el EntryPoint que sera la clase MainEntryPoint que esta en el paquete org.aplication.client.


package org.aplication.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.ClickListener;
import com.gwtext.client.widgets.Window;
import org.aplication.client.view.GuiUsuario;

/**
* Main entry point.
*
* @author isaac
*/
public class MainEntryPoint implements EntryPoint {
/**
* Creates a new instance of MainEntryPoint
*/
public MainEntryPoint() {
}

/**
* The entry point method, called automatically by loading a module
* that declares an implementing class as an entry-point
*/
public void onModuleLoad() {

final Button button = new Button("Click me!");

button.addClickListener(new ClickListener(){
public void onClick(Widget w) {
GuiUsuario guiUsuario = new GuiUsuario();
Window winUsu = guiUsuario.getWindow();
winUsu.show();
}
});

RootPanel.get().add(button);

}
}



winUsu.show(); Este metodo de la clase Window hace que la ventana se visualize en el navegador del cliente.

Depues damos run a proyecto y deberiamos tener algo como esto.



Paso 3. Crear el RCP damos click derecho en new / other depues aparecera la opcion de gwt y una lista donde esta gwtrcp damos click y despues nos pedira en nombre del servicio en paquete donde lo pondremos.


Creación del servio: Lo llamaremos GWTServiceUser y estará dentro del paquete org.aplication.client.servicio

Después tendremos una estructura como la siguiente:


Un rcp de gwt necesita de 3 clases principales y un mapeo en el web.xml que ya hace por defecto el ayudante de netbeans.

dentro del paquete org.aplication.client.servicio
- interface GWTServiceUserAsync
-interface GWTServiceUser
y del lado del servidor en el paquete org.aplication.server.servicio esta la clase:
-class GWTServiceUserImpl

El diagrama de clases para la creación de usuarios desde el cliente al servidor es la siguiente:

El código para cada clase es el siguiente:

package org.aplication.client.servicio;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import org.aplication.client.modelo.Usuario;

/**
*
* @author isaac
*/
@RemoteServiceRelativePath("servicio/gwtserviceuser")
public interface GWTServiceUser extends RemoteService {
public String nuevoUsuario(Usuario usuario);
}

---------------

package org.aplication.client.servicio;

import com.google.gwt.user.client.rpc.AsyncCallback;
import org.aplication.client.modelo.Usuario;

/**
*
* @author isaac
*/
public interface GWTServiceUserAsync {
public void nuevoUsuario(Usuario usuario, AsyncCallback callback);
}

--------------------------------------

package org.aplication.server.servicio;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import org.aplication.client.modelo.Usuario;
import org.aplication.client.servicio.GWTServiceUser;

/**
*
* @author isaac
*/


public class GWTServiceUserImpl extends RemoteServiceServlet implements GWTServiceUser {

private static List usuarios = null;
private static int contCve = 0;

public String nuevoUsuario(Usuario usuario) {
contCve++;
usuario.setCve(contCve);

if(usuarios==null){

usuarios = new ArrayList();
usuarios.add(usuario);

}else
usuarios.add(usuario);

for(Usuario u:usuarios){
System.out.println("usuario "+u.getNombre());
}

return "Se ha creado el usuario";
}




}

-------------------------------------------------------------


package org.aplication.client.view;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.core.Position;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.MessageBox;
import com.gwtext.client.widgets.Window;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.form.FormPanel;
import com.gwtext.client.widgets.form.TextField;
import org.aplication.client.modelo.Usuario;
import org.aplication.client.servicio.GWTServiceUser;
import org.aplication.client.servicio.GWTServiceUserAsync;

/**
*
* @author isaac
*/
public class GuiUsuario {

private Usuario usuario;
private Window window;
private FormPanel formPanel;
private TextField nombre;
private TextField apellido;
private TextField edad;
private static GWTServiceUserAsync service;

public FormPanel getFormPanel() {


formPanel = new FormPanel();
formPanel.setFrame(true);
formPanel.setTitle("Usuario");
nombre = new TextField("Nombre", "nombre", 230);
apellido = new TextField("Apellido", "apellido", 230);
edad = new TextField("Edad", "edad", 230);
formPanel.add(nombre);
formPanel.add(apellido);
formPanel.add(edad);


return formPanel;
}

public Usuario getUsuario() {
return usuario;
}

public Window getWindow() {

window = new Window();
window.setTitle("Layout Window");
window.setClosable(true);
window.setWidth(600);
window.setHeight(350);
window.setPlain(true);
window.setCloseAction(Window.HIDE);
window.add(getFormPanel());

Button buttonNewUser = new Button("Nuevo Usuario");
buttonNewUser.addListener(new ButtonListenerAdapter(){

@Override
public void onClick(Button button, EventObject e) {
Usuario u = new Usuario();
u.setEdad(Integer.parseInt(edad.getText()));
u.setNombre(nombre.getText());
u.setApellido(apellido.getText());

insertaUsuario(u);

}

}
);


window.setButtonAlign(Position.CENTER);
window.addButton(buttonNewUser);



return window;
}

public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}



public void insertaUsuario(Usuario usuario) {


// Create an asynchronous callback to handle the result.
final AsyncCallback callback = new AsyncCallback() {

public void onSuccess(Object result) {
String respuesta = (String) result;

MessageBox.alert(respuesta);

}

public void onFailure(Throwable caught) {
MessageBox.alert("Error " + caught);
}
};

getService().nuevoUsuario(usuario, callback);

}


public static GWTServiceUserAsync getService() {
service = (GWTServiceUserAsync) GWT.create(GWTServiceUser.class);
ServiceDefTarget endpoint = (ServiceDefTarget) service;
String moduleRelativeURL = GWT.getModuleBaseURL() + "servicio/gwtserviceuser";
endpoint.setServiceEntryPoint(moduleRelativeURL);
return service;
}



}

----------------------------------------

- La parte importante que debemos entender de los rcp de gwt es que podemos mandar beans desde los clientes hasta nuestro servidor de manera clara sin necesidad de ocupar
request.

La menera que se logra esto es atravez de del siguiente metodo de la clase
GuiUsuario.

public static GWTServiceUserAsync getService() {
service = (GWTServiceUserAsync) GWT.create(GWTServiceUser.class);
ServiceDefTarget endpoint = (ServiceDefTarget) service;
String moduleRelativeURL = GWT.getModuleBaseURL() + "servicio/gwtserviceuser";
endpoint.setServiceEntryPoint(moduleRelativeURL);
return service;
}

y para llamarlo ocupamos el metodo siguiente dentro de la misma clase:

public void insertaUsuario(Usuario usuario) {

// Create an asynchronous callback to handle the result.
final AsyncCallback callback = new AsyncCallback() {
public void onSuccess(Object result) {
String respuesta = (String) result;

MessageBox.alert(respuesta);

}

public void onFailure(Throwable caught) {
MessageBox.alert("Error " + caught);
}
};

getService().nuevoUsuario(usuario, callback);

}

Cuando se ejecuta este metodo llama directemente a metodo getService() el cual tiene un metodo llamado nuevoUsuario que ha este le mandamos como parametro el usuario y el callback que su tarea va ser recibir la respuesta del rcp del servidor en este caso de la clase GWTServiceUserImpl que sobreescribe el método nuevoUsuario que es donde creamos la lista y insertamos elementos a ella y esta responde con el mensaje return "Se ha creado el usuario" el cual es recibido por el callback en:

public void onSuccess(Object result) {
String respuesta = (String) result;

MessageBox.alert(respuesta);
.
.
.

Por ultimo necesitamos el evento del boton de la GuiUsuario para crear el usuario y llamar al método insertaUsuario

Button buttonNewUser = new Button("Nuevo Usuario");
buttonNewUser.addListener(new ButtonListenerAdapter(){

@Override
public void onClick(Button button, EventObject e) {
Usuario u = new Usuario();
u.setEdad(Integer.parseInt(edad.getText()));
u.setNombre(nombre.getText());
u.setApellido(apellido.getText());

insertaUsuario(u);

}

}
);

Después damos run al proyecto y nuestra aplicación esta lista para crear usuarios yo puse una lista estática de usuarios pero bien se pueden insertar en una base de datos con hibernate o con jdbc.


Bueno eso es todo despues crearemos un grid ....

Dedicado a mi princesita.


Segunda Parte


martes, 31 de marzo de 2009

Como configurar GWT-EXT en NetBeans

Como configurar GWT-EXT, primero tienen que descargar el jar de Gwt-Ext y la libreria de java script que nos permite manejar widgets (Js-Ext), de este sitio http://gwt-ext.com/download/


Paso 1: El mas importante, tener ganas de terminar este pequeñito tutorial.

Paso 2: Copiamos las libreria de js-ext, pero se preguntaran donde diablos esta,
http://yogurtearl.com/ext-2.0.2.zip , la reombramos con js y la copiamos a nuestro proyecto dentro de Web Pages



Después debería estar así:


3. Agregamos el jar de gwtext.jar que esta en el zip en libreries de nuestro proyecto:

Dar click derecho en libreries, ADD jar/Folder.



4. Configuar Main.gwt.xml este archivo esta nuestro MainEntryPoint, este tiene quien es la clase principal que contiene el metodo para iniciar una aplicación gwt, debemos colocar lo siguiente tag :

<inherits name="com.gwtext.GwtExt"/>

<?xml version="1.0" encoding="UTF-8"?>
<module>
<inherits name="com.google.gwt.user.User"/>
<entry-point class="
org.yournamehere.client"/>
<!-- Do not define servlets here, use web.xml -->
<inherits name="com.gwtext.GwtExt"/>
</module>



5. Tomen un descanso

6. Configuarar las librerias de js en html o jsp donde va a estar alojada nuestra aplicación gwt, para este ejemplo sera: welcomeGwt.html, primero borren lo que tienen y copian lo siguiente:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name='gwt:module' content='org.yournamehere.Main=org.yournamehere.Main'>
<title>Main</title>
<link rel="stylesheet" type="text/css" href="js/resources/css/ext-all.css"/>
<link rel="stylesheet" type="text/css" href="js/resources/css/xtheme-gray.css" />
<script type="text/javascript" src="js/adapter/yui/yui-utilities.js"></script>
<script type="text/javascript" src="js/adapter/yui/ext-yui-adapter.js"></script>
<script type="text/javascript" src="js/ext-all.js"></script>
</head>
<body>
<script language="javascript" src="org.yournamehere.Main/org.yournamehere.Main.nocache.js"></script>
</body>
</html>

7. Llamen a ala policía escucho ruidos extraños en mi cubículo...
En este paquete org.yournamehere.client hay una clase que es la principal-> MainEntryPoint remplacen su código por este:

/*
* MainEntryPoint.java
*
* Created on 17 de junio de 2009, 06:39 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package org.yournamehere.client;

import com.google.gwt.core.client.EntryPoint;
import com.gwtext.client.core.RegionPosition;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.TabPanel;
import com.gwtext.client.widgets.Window;
import com.gwtext.client.widgets.layout.BorderLayout;
import com.gwtext.client.widgets.layout.BorderLayoutData;

/**
*
* @author isaac
*/
public class MainEntryPoint implements EntryPoint {

/** Creates a new instance of MainEntryPoint */
public MainEntryPoint() {
}

/**
* The entry point method, called automatically by loading a module
* that declares an implementing class as an entry-point
*/
public void onModuleLoad() {

TabPanel tabPanel = new TabPanel();
tabPanel.setActiveTab(0);

Panel tab1 = new Panel();
tab1.setTitle("Bogus Tab");
tab1.setHtml(getBogusMarkup());
tab1.setAutoScroll(true);

Panel tab2 = new Panel();
tab2.setTitle("Another Tab");
tab2.setHtml(getBogusMarkup());
tab2.setAutoScroll(true);

Panel tab3 = new Panel();
tab3.setTitle("Closable Tab");
tab3.setHtml(getBogusMarkup());
tab3.setAutoScroll(true);
tab3.setClosable(true);

tabPanel.add(tab1);
tabPanel.add(tab2);
tabPanel.add(tab3);

//west panel
Panel navPanel = new Panel();
navPanel.setTitle("Navigation");
navPanel.setWidth(200);
navPanel.setCollapsible(true);

BorderLayoutData centerData = new BorderLayoutData(RegionPosition.CENTER);
centerData.setMargins(3, 0, 3, 3);

BorderLayoutData westData = new BorderLayoutData(RegionPosition.WEST);
westData.setSplit(true);
westData.setMargins(3, 3, 0, 3);
westData.setCMargins(3, 3, 3, 3);

final Window window = new Window();
window.setTitle("Layout Window");
window.setClosable(true);
window.setWidth(600);
window.setHeight(350);
window.setPlain(true);
window.setLayout(new BorderLayout());
window.add(tabPanel, centerData);
window.add(navPanel, westData);
window.setCloseAction(Window.HIDE);
window.show();
}

private static String getBogusMarkup() {
return "
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. " +
"Sed metus nibh, sodales a, porta at, vulputate eget, dui. " +
"In pellentesque nisl non sem. Suspendisse nunc sem, pretium eget, " +
"cursus a, fringilla vel, urna.";
}

}

Primero crea un TabPanel con tres pestañas y después es agregado ala ventana en la posición del centro atravez de:
BorderLayoutData centerData = new BorderLayoutData(RegionPosition.CENTER);
centerData.setMargins(3, 0, 3, 3);
También contiene otro panel en zona oeste que es agregado a la ventana con:
BorderLayoutData westData = new BorderLayoutData(RegionPosition.WEST);
westData.setSplit(true);
westData.setMargins(3, 3, 0, 3);
westData.setCMargins(3, 3, 3, 3);

8 . Run al archivo welcomeGwt.html despues tendran algo como esto:


Como ven es facil se pueden hacer aplicaciones bastantes vistosas, ademas de ser rapidas, depues explicare como comunicar estas GUI mediante RPC con aplicaciones cliente servidor...

Continuara