Sencha GXT 3 (Ext GWT): Exemplo Grid Simples
No post de hoje vamos aprender passo a passo como implementar um Grid simples usando Sencha GXT 3, também conhecido como Ext GWT 3.
Requisitos:
- Eclipse
- Google plugin para Eclipse
- Sencha GXT 3
Se você não souber como configurar o ambiente, pode ler esse tutorial que mostra o passo a passo de como fazer isso.
Passo a passo:
- Criar o Projeto
- Criar o código GXT 3
- Criar a classe Entry Point (public static void main do GWT)
- Executar o projeto
1- Criando o Projeto
A primeira coisa que precisamos é criar o projeto e adicionar o jar do GXT 3. Segue o passo a passo:
1.1 - Para criar um novo projeto, clique na “seta para baixo” ao lado do ícone do Google e selecione “New Web Application Project”:
1.2 - Dê um nome para o projeto (neste tutorial dei o nome de sencha-gxt3-simple-grid), informe o nome do pacote base que irá usar (neste caso escolhi com.loiane.gxt3). Depois deixe apenas a opção “Use Google Web Toolkit” selecionada. Assim vamos criar um projeto “zerado”:
1.3 – Depois adicione a biblioteca do GXT 3 no projeto. Este post mostra como fazer isso.
2 – Criando o Grid com Sencha GXT 3
2.1 - Agora que o projeto já está todo configurado, vamos começar com a diversão e implementar a nossa aplicação com GXT 3. Para isso, selecione o projeto, clique com o botão direto e escolha “New” -> “Other”. Ache o folder do “Google Web Toolkit” e escolha “Module”:
2.2 – Escolha o pacote (que escolhemos quando criamos o projeto, lembra?) e dê um nome para o módulo. Chamei o módulo de SimpleGrid. Outro detalhe é que se reparamos na parte de Inherited modules, apenas o com.google.gwt.user.User vem por padrão. Como vamos desenvolver uma aplicação com GXT, também precisamos adicionar o módulo da Sencha, que o o com.sencha.gxt.ui.GXT. Para isso, basta clicar no botão “Add” e procurar por essa classe. Depois de tudo pronto, basta clicar no botão “Finish“:
Repare que o plugin do Google irá gerar a estrutura de pacotes (nesse caso com.loiane.gxt3.client) e um arquivo xml com a configuração do módulo que acabamos de criar.
2.3 – Agora podemos começar a codificar! O Primeiro passo é criar um POJO que represente o dado que queremos mostrar no Grid. Nesse exemplo vamos criar uma classe simples que representa um contato. Vou colocar essa classe dentro do pacote com.loiane.gxt3.client.model e essa classe também precisa implementar a interface Serializable:
2.4 – Depois que a classe está criada, vamos adicionar os atributos, métodos getters e setter e dois construtores: um vazio e um que recebe todos os atributos:
package com.loiane.gxt3.client.model;
import java.io.Serializable;
public class Contact implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private String phone;
private String email;
public Contact(){
super();
}
public Contact(Integer id, String name, String phone, String email) {
super();
this.id = id;
this.name = name;
this.phone = phone;
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
2.5 – Para o grid, vamos precisar configurar as colunas que vão aparecer no grid. As colunas irão mostrar os dados que representam os atributos que acabamos de criar na classe Contact. E para configurarmos as colunas do grid, o GXT 3 precisa de uma classe Properties, que nós vamos criar agora:
2.6 – A classe ContactProperties vai ficar assim:
package com.loiane.gxt3.client.model;
import com.google.gwt.editor.client.Editor.Path;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.data.shared.ModelKeyProvider;
import com.sencha.gxt.data.shared.PropertyAccess;
public interface ContactProperties extends PropertyAccess<Contact> {
@Path("id")
ModelKeyProvider<Contact> key();
ValueProvider<Contact, String> name();
ValueProvider<Contact, String> phone();
ValueProvider<Contact, String> email();
}
E a pergunta que não quer calar: O que é essa tal interface PropertyAccess? Essa interface serve para que o grid consiga acessar os atributos da classe POJO que criamos. Precisamos criar um método para acessar cada atributo que criamos na nossa classe Contact. Esse métodos podem retornar um ModelKeyProvider ou ValueProvider (no nosso caso). O ModelKeyProvider significa que tem um retorno único, como por exemplo, o id do registro que vai ser retornado do banco de dados; neste caso ainda usamos a anotação Path para dizer que esse método serve para acessar o atributo id da classe Contact. Os outros métodos são do tipo ValueProvider, o que significa que vamos acessar diretamente o valor dos outros atributos, que queremos mostrar no grid.
2.7 – Agora já temos tudo pronto para criar o código do Grid em GXT 3. Vamos criar uma nova classe que extende da classe Grid do GXT 3:
2.8 – Bem, para implementarmos um Grid simples simples, precisamos de apenas 2 coisas: da configuração de colunas (afinal, precisamos dizer quais são as colunas que irão aparecer no grid né?), e uma store, que é responsável por popular o grid com dados.
Primeiro vamos então criar a configuração das colunas:
private static final ContactProperties props = GWT.create(ContactProperties.class);
private static ColumnConfig<Contact, String> nameCol = new ColumnConfig<Contact, String>(props.name(), 150, "Name");
private static ColumnConfig<Contact, String> phoneCol = new ColumnConfig<Contact, String>(props.phone(), 75, "Phone");
private static ColumnConfig<Contact, String> emailCol = new ColumnConfig<Contact, String>(props.email(), 150, "Email");
private static ColumnModel<Contact> createColumnModel(){
List<ColumnConfig<Contact, ?>> columnConfigList = new ArrayList<ColumnConfig<Contact, ?>>();
columnConfigList.add(nameCol);
columnConfigList.add(phoneCol);
columnConfigList.add(emailCol);
return new ColumnModel<Contact>(columnConfigList);
}
Na linha 1 temos a instância da classe ContactProperties que criamos no passo anterior. Logo abaixo temos mais 3 atributos que representam a configuração de 3 colunas. E logo depois temos um método que retorna um objeto do tipo ColumnModel que vamos setar no grid daqui a pouco. Para quem já tem experiência com ExtJS, pode notar que é praticamente a mesma coisa, só que agora estamos codificando em java ao invés de codificar com javascript. E para quem nunca trabalhou com ExtJS, sugiro que estude esses conceitos do ExtJS.
Agora precisamos criar a Store:
private static ListStore<Contact> generateData(){
ListStore<Contact> store = new ListStore<Contact>(props.key());
store.addAll(ContactTestData.generateData());
return store;
}
Como nesse primeiro exemplo criei apenas alguns dados manualmente para popular a store, criei essa classe ContactTestData. Em um próximo post veremos como buscar esses dados diretamente de um banco de dados:
package com.loiane.gxt3.client.util;
import java.util.ArrayList;
import java.util.List;
import com.loiane.gxt3.client.model.Contact;
public class ContactTestData {
public static List<Contact> generateData(){
List<Contact> list = new ArrayList<Contact>();
list.add(new Contact(1, "Loiane", "1234-5678", "loiane@email.com"));
list.add(new Contact(2, "Peter", "2345-6789", "peter@email.com"));
list.add(new Contact(3, "Andrew", "9876-1234", "andrew@email.com"));
list.add(new Contact(4, "Caroline", "5647-8473", "caroline@email.com"));
list.add(new Contact(5, "Jared", "4034-4585", "jared@email.com"));
list.add(new Contact(6, "Linda", "3455-0234", "linda@email.com"));
list.add(new Contact(7, "Elena", "3454-4543", "elena@email.com"));
list.add(new Contact(8, "Stefan", "5677-5677", "stefan@email.com"));
list.add(new Contact(9, "Ana", "2434-2343", "ana@email.com"));
return list;
}
}
Por último, só falta a gente adicionar a store e o columnModel ao grid, e vamos fazer isso através do construtor. Adicionei também umas configuração para deixar o grid mais bonito, mas para criar o grid mesmo só precisamos da instância!
public SimpleGrid() {
super(generateData(), createColumnModel());
this.getView().setStripeRows(true);
this.getView().setColumnLines(true);
this.getView().setAutoExpandColumn(nameCol);
this.setBorders(false);
this.setColumnReordering(true);
}
A classe SimpleGrid fica assim então:
package com.loiane.gxt3.client.grid;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.loiane.gxt3.client.model.Contact;
import com.loiane.gxt3.client.model.ContactProperties;
import com.loiane.gxt3.client.util.ContactTestData;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.ColumnModel;
import com.sencha.gxt.widget.core.client.grid.Grid;
public class SimpleGrid extends Grid<Contact> {
private static final ContactProperties props = GWT.create(ContactProperties.class);
private static ColumnConfig<Contact, String> nameCol = new ColumnConfig<Contact, String>(props.name(), 150, "Name");
private static ColumnConfig<Contact, String> phoneCol = new ColumnConfig<Contact, String>(props.phone(), 75, "Phone");
private static ColumnConfig<Contact, String> emailCol = new ColumnConfig<Contact, String>(props.email(), 150, "Email");
public SimpleGrid() {
super(generateData(), createColumnModel());
this.getView().setStripeRows(true);
this.getView().setColumnLines(true);
this.getView().setAutoExpandColumn(nameCol);
this.setBorders(false);
this.setColumnReordering(true);
}
private static ColumnModel<Contact> createColumnModel(){
List<ColumnConfig<Contact, ?>> columnConfigList = new ArrayList<ColumnConfig<Contact, ?>>();
columnConfigList.add(nameCol);
columnConfigList.add(phoneCol);
columnConfigList.add(emailCol);
return new ColumnModel<Contact>(columnConfigList);
}
private static ListStore<Contact> generateData(){
ListStore<Contact> store = new ListStore<Contact>(props.key());
store.addAll(ContactTestData.generateData());
return store;
}
}
3 – Criando a Classe EntryPoint
3.1 – Tudo pronto! Só precisamos criar agora uma maneira de chamar esse código todo que acabamos de criar! Para isso, vamos criar uma classe EntryPoint, que possui um método chamado onModuleLoad, que é uma espécie de método main do GWT:
3.2 – Vamos criar a classe:
3.3 – Vamos ao código então:
package com.loiane.gxt3.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;
import com.loiane.gxt3.client.grid.SimpleGrid;
import com.sencha.gxt.widget.core.client.ContentPanel;
import com.sencha.gxt.widget.core.client.Resizable;
import com.sencha.gxt.widget.core.client.Resizable.Dir;
public class SimpleGridExample implements EntryPoint {
@Override
public void onModuleLoad() {
ContentPanel root = new ContentPanel();
root.setHeadingText("Simple Grid");
root.setPixelSize(550, 250);
root.addStyleName("margin-10");
Resizable r = new Resizable(root, Dir.E, Dir.SE, Dir.S);
r.setMinHeight(200);
r.setMinWidth(300);
root.setWidget(new SimpleGrid());
RootPanel.get().add(root);
}
}
No código acima apenas criamos um painel que pode ser redimencionado e adicionamos o grid como o único item. O painel será renderizado dentro da tag body do html.
3.4 – Falando em HTML, só falta agora criar a página html dentro da pasta war:
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Simple Grid Example - loiane.com</title>
<link rel="stylesheet" type="text/css" href="simplegrid/reset.css" />
<style type="text/css">
body {
padding: 30px;
}
</style>
<script type="text/javascript" language="javascript" src="simplegrid/simplegrid.nocache.js"></script>
</head>
<body>
</body>
</html>
4 – Executando o Projeto
4.1 - Para executar o projeto, vamos clicar novamente com o botão direito no projeto, e escolher a opção “Run As” -> “Web Application” (repare no ícone do plugin do Google)!
5 – Live – Demo
Se quiser ver o resultado final do projeto, basta acessar esse link para executar a demonstração: http://loiane.com.br/sencha-gxt3-simple-grid/ (agora estou com uma hospedagem java tb!
)
6 – Download Código Fonte
Para fazer download do código fonte completo (ou fazer um fork) do repositório do github: https://github.com/loiane/sencha-gxt3-simple-grid
Até a próxima!



















Parabéns pelo artigo, muito bem escrito e detalhado!
O que vc acha do GXT? vinga ou não? Até hoje nao vi ninguém usando.
Oi Daniel,
Pois é, antes não divulgava artigos sobre GXT aqui no blog justamente por pensar isso! Mas recentemente dei uma palestra sobre Extjs em um evento Java e me vieram perguntar: pq vc não fala sobre gxt? Tem bastante gente que usa! Acho que essa informação apenas não é divulgada.
Olá Loaine.
Eu uso Ext JS 2.2 + GWT-EXT que depois virou SmartGWT, mas não migrei pra ele e nem para o GTX, estou em fase de projeto para migrar par ao puro EXT JS 4.1, tirando o GWT ja jogada, pois uma coisa que está me limitando é o fato de mesmo eu modulando os subprojetos, fazendo modulo para as funcionalidades internas, ele precisa de todo os modulos para compilar e funcionar juntos, não permitindo que sejam feito modulos (plugins) para o sistema isolados e adicionados depois em runtime, minha estratégia está em usar o EXT-JS puro na camada de view e para dinamizar ainda mais o server usar o framework PLAY, para nem precisar ficar compilando o java antes e gerar um war, com isso vou poder ter plugins feitos por terceiros e adicionados a aplicação principal em runtime, com um simples ADD no sistema, onde pretendo que venha um zip com todos os arquivos, descompacto no lugar certo e BINGO, nova função.
Como não acompanhei o GXT, mas pelo que ainda sei do GWT 2.4 não seria possível fazer tudo isso que desejo sem precisar complicar o projeto inteiro junto, pois ele precisa fazer as referencias e linkagens corretas na hora que transcrever em JS, correto?
Forte abraço e parabéns pelos tutorias, ainda bem que já finalizou o Diablo III , rsrs
Olá Loiane!
Parabéns pela qualidade do artigo!
Sobre o GXT:
- você já tentou desenhar as telas através GWT Designer? Eu tentei aqui mas ficou muito lento e instável…
- também achei que o GXT tem pouca documentação (getting started, tutoriais, etc.) em relação as demais produtos da Sencha (Archivetct, Ext JS).
Estou dando uma olhada no Sencha Architect. Você já usou ele?
Muito obrigado e até mais.
Oi Danilo,
- ainda não usei o designer, não gosto muito, prefiro fazer o código na mão.
- sim tem pouca documentação pois não é um dos produtos mais usados na Sencha, então eles dão mais atenção ao extjs e sencha touch, por exemplo.
Sim, eu uso o SA2, recomendo a ferramenta.
[]‘s
Alguem tem um exemplo de campos mascarados em GXT? Exemplo datas, CEP, CNPJ, etc.
Eu não entendi a criação do module no inicio do tutorial. Na sequencia não se comenta mais nele. Ele serve para alguma coisa? Se sim, como funciona? Obrigado.
Oi Jean,
Faz parte do GWT, que é um requisito para Sencha GXT 3.
Dê uma lida nesse artigo para entender melhor como o GWT funciona: https://developers.google.com/web-toolkit/doc/latest/DevGuideOrganizingProjects
[]‘s
Olá Loiane,
Parabéns pelo artigo. Você escreve e explica muito bem!
Estava pensando nos prós e contras em utilizar o GXT ou utilizar o ExtJs com back-end Java funcionando como um web service.
Pelo que pude perceber, o GXT é vantagem para quem não conhece ou não quer codificar interfaces com JavaScript, correto ?
Caso contrário, o ExtJS com back-end em Java é uma solução mais elegante e deixa as coisas bem separada em camadas concorda ?
Obrigado,
Edison
Exato Edison,
GXT é mais fácil para quem não sabe JS e quer criar projetos com interfaces ricas.
O contra do GXT é que os exemplos e documentação são escassos, então dá um pouco mais de trabalho.
Já com ExtJS, a comunidade é enorme e suporte, exemplos é o que não faltam na net!
[]‘s