GWT Componentes graficos

Pessoal, comecei a estudar GWT, no começo achei muito legal, olhei o showcase dos componentes como por exemplo http://gwt.google.com/samples/Showcase/Showcase.html#!CwDataGrid e fiquei facinado com a maneira meio Swing de desenvolver as telas, enfim, gostei bastante… Mas agora que comecei a fazer coisas mais “complexas”, como esse datagrid ai, vi que estava enganado…

eu achei q esse datagrid fosse um componente pronto assim como existe no richfaces, primefaces, etc, que era só usar, mas não, nao é um componente pronto, e por sinal é bem complicadinho de fazer, fazer uma tabelinha é facil, mas fazer uma como no exemplo do showcase, que seja bem apresentavel, funcional com recursos de paginação e alteração de objetos é bem complicado…

alguem já fez algo assim ? é mesmo meio complicado, a gnt tem q fazer td do zero ? ou eu estou enganado indo pelo lado errado ?

bom galera, eu nao tinha visto isso ainda http://gwt-ext.com/

já testei uma tabelinha filé aqui, agora acho q vai ficar legal, com cara de rich, hahahha e sem muitas dificuldades (assim espero !!!)

bom, pra não perder o tópico, depois mando um mini-tutorial aqui de como usar, e das dificuldades que estou tendo e se estou conseguindo resolver…

Olá,

eu sempre digo para os iniciantes em GWT que o mesmo não nasceu com o objetivo de ser um framework de UI. Ele nasceu com o objetivo de ser um compilador cross-browser que converte arquivos fontes Java em JavaScript.

Eu ainda não gosto muito dos CellWidgets, ele muito custoso pro ambiente de produção. Eu ainda prefiro os antigos widgets.

Com relação a table, você poderá usar algum framework de UI que contenha esse widget ou construir a sua própria, é meio trabalhoso para que é iniciante. Algumas coisas você mesmo vai ter que criar se não quiser usar de terceiros. O Pure GWT por exemplo, ele é um framework que estou construindo, ele basicamente foi construído do zero. Aqui você pode ver uma demo do Pure GWT antes de ter uma versão de avaliação liberada.

[quote=cleiton herrmann]bom galera, eu nao tinha visto isso ainda http://gwt-ext.com/

já testei uma tabelinha filé aqui, agora acho q vai ficar legal, com cara de rich, hahahha e sem muitas dificuldades (assim espero !!!)

bom, pra não perder o tópico, depois mando um mini-tutorial aqui de como usar, e das dificuldades que estou tendo e se estou conseguindo resolver…

[/quote]

Mande ai o tutorial, já ia postar no forum como que mexe com o data grid, estou tomando uma surra desse cara.

Att

opa vamos lá, bom eu tbem estou começando, comecei ontem, kkkk mas basicamente o q eu fiz pra usar os componentes do gwtext foi o seguinte:

  1. Baixar 2 arquivos e descompactalos num diretório de sua preferencia, são eles: o gwt-ext e o ExtJS neste link tem os 2 http://gwt-ext.com/download/
  2. Estou usando o netbeans, adicionei no pacote lib, o gwtext.jar
  3. Depois dentro do pacote padrão da minha aplicação eu criei um pacote chamado /public ficando ± assim a estrutura:

[quote]pacote padrão: org.yournamehere
org.yournamehere.public
org.yournamehere.client
org.yournamehere.server
org.yournamehere.dao
org.yournamehere.beans
e por ai vai…[/quote]
4) Copiei dentro do pacote /public os seguintes arquivos e diretorios do extjs

[quote]/adapter
/resources
ext-all.js
ext-all-debug.js
ext-core.js
ext-core-debug.js[/quote]
5) Fiz a minha classe de teste segue ela abaixo tah meio grandinha e bagunçada, mas é um teste q funciona hahaha:[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package org.yournamehere.client.consultas;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.Image;
import com.gwtext.client.data.Record;
import java.util.List;
import org.yournamehere.beans.Clientes;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.data.ArrayReader;
import com.gwtext.client.data.FieldDef;
import com.gwtext.client.data.MemoryProxy;
import com.gwtext.client.data.Reader;
import com.gwtext.client.data.RecordDef;
import com.gwtext.client.data.Store;
import com.gwtext.client.data.StringFieldDef;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.Toolbar;
import com.gwtext.client.widgets.ToolbarButton;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.grid.ColumnConfig;
import com.gwtext.client.widgets.grid.ColumnModel;
import com.gwtext.client.widgets.grid.GridPanel;
import com.gwtext.client.widgets.grid.RowSelectionModel;
import com.gwtext.client.widgets.grid.event.RowSelectionListener;

/**

  • Example class using the ConsultarClientesService service.

  • @author Cleiton
    */
    public class ConsultarClientes extends DecoratorPanel {

    private Image gif = new Image("./imagens/carregando.gif");
    private Panel panel = new Panel();

    private RecordDef recordDef = new RecordDef(
    new FieldDef[]{
    new StringFieldDef(“cpf”),
    new StringFieldDef(“nome”),});

    private ColumnConfig[] columns = new ColumnConfig[]{
    new ColumnConfig(“Cpf”, “cpf”, 100, true, null, “cpf”),
    new ColumnConfig(“Nome”, “nome”, 300, true)};

    private ColumnModel columnModel = new ColumnModel(columns);
    private final GridPanel grid = new GridPanel();
    private Reader reader = new ArrayReader(recordDef);
    private Store store = new Store(reader);

    public ConsultarClientes() {
    gif.setVisible(false);

     panel.setBorder(false);
     panel.setPaddings(15);
    
     grid.setColumnModel(columnModel);
    
     grid.setFrame(true);
     grid.setStripeRows(true);
     grid.setAutoExpandColumn("cpf");
    
     grid.setHeight(350);
     grid.setWidth(600);
     grid.setTitle("Array Grid");
    
     Toolbar bottomToolbar = new Toolbar();
     bottomToolbar.addFill();
     bottomToolbar.addElement(gif.getElement());
     bottomToolbar.addButton(new ToolbarButton("Listar clientes", new ButtonListenerAdapter() {
    
         @Override
         public void onClick(Button button, EventObject e) {
             gif.setVisible(true);
             listarClientes();
         }
     }));
     grid.setBottomToolbar(bottomToolbar);
     RowSelectionModel selectionModel = new RowSelectionModel(true);
     selectionModel.addListener(new RowSelectionListener() {
    
         @Override
         public boolean doBeforeRowSelect(RowSelectionModel sm, int rowIndex, boolean keepExisting, Record record) {
             return true;
         }
    
         @Override
         public void onRowDeselect(RowSelectionModel sm, int rowIndex, Record record) {}
    
         @Override
         public void onRowSelect(RowSelectionModel sm, int rowIndex, Record record) {
             String[] fields = record.getFields();
             String linha = "";
             for (String s : fields) {
                 linha += record.getAsString(s) + " - \n";
             }
             Window.alert(linha);
         }
    
         @Override
         public void onSelectionChange(RowSelectionModel sm) {}
     });
     grid.setSelectionModel(selectionModel);
     panel.add(grid);
     
     Object[][] data = getCompanyData();
     MemoryProxy proxy = new MemoryProxy(data);
     store.setDataProxy(proxy);
     store.load();
     grid.setStore(store);
    
     setWidget(panel);
    

    }

    private Object[][] getCompanyData() {
    return new Object[][]{
    new Object[]{“00000000000”, “aaa”},
    new Object[]{“11111111111”, “bbb”},
    new Object[]{“22222222222”, “ccc”},
    new Object[]{“33333333333”, “ddd”},
    new Object[]{“44444444444”, “eee”},
    new Object[]{“55555555555”, “fff”},
    new Object[]{“66666666666”, “ggg”},
    new Object[]{“77777777777”, “iii”},
    new Object[]{“88888888888”, “hhh”},
    new Object[]{“99999999999”, “jjj”},};
    }

    private void listarClientes() {
    AsyncCallback<List> cbClientes = new AsyncCallback<List>() {

         @Override
         public void onFailure(Throwable caught) {
             gif.setVisible(false);
             Window.alert(caught.getClass().getName() + " - " + caught.getMessage());
         }
    
         @Override
         public void onSuccess(List<Clientes> result) {
             gif.setVisible(false);
    
             Object[][] data = new Object[result.size()][];
             
             for (int i = 0; i < result.size(); i++) {
                 Clientes c = result.get(i);
                 data[i] = new Object[]{c.getCpf(), c.getNome()};
             }
             
             MemoryProxy proxy = new MemoryProxy(data);
             store.setDataProxy(proxy);
             store.load();
             grid.reconfigure(store, columnModel);
             gif.setVisible(false);
         }
     };
    
     getService().listarClientes(cbClientes);
    

    }

    public static ConsultarClientesServiceAsync getService() {
    ConsultarClientesServiceAsync service = (ConsultarClientesServiceAsync) GWT.create(ConsultarClientesService.class);
    ServiceDefTarget endpoint = (ServiceDefTarget) service;
    String moduleRelativeURL = GWT.getModuleBaseURL() + “consultas/consultarclientesservice”;
    endpoint.setServiceEntryPoint(moduleRelativeURL);
    return service;
    }
    }[/code]inicialmente, a grid exibe dados estaticos, mas depois de clicar no botão listar clientes na bottomToolBar, ele busca clientes de uma tabela no banco, e tem o evento onRowSelect que exibe um Window.alert(…), com os dados da linha selecionada. E pra testar, basta na sua classe entrypoint fazer assimpublic void onModuleLoad() { RootLayoutPanel.get().add(new ConsultarClientes()); } eu acho q pra quem ja tem uma “noçãozinha” de como funciona a comunicação com banco e do gwt em geral, o código nao esta dificil de entender, mas qq duvida sobre o código tamo ai pra trocar idéias, que aliás eu ja vou fazer uma pergunta pra vcs sobre esse grid ai a respeito de um columnModel de objetos, como é feito em swing…

os passos descritos acima foram originalmente seguidos de http://www.gwt-ext.com/wiki/index.php?title=Tutorial:Introduction_to_GWT-Ext_2.0

esqueci de um passo importante, no seu arquivo modulo.gwt.xml adicione as seguintes linhas[code]

[/code]

Aqui,

Quando eu baixei o .zip desse site http://code.google.com/p/smartgwt/ tem um hello world desse cara.
O smartgwt tem uma versao GPL. Achei mais facil de configurar.

http://www.smartclient.com/smartgwt/showcase/#featured_grid_live url onde estão os demos.

na verdade eu preciso so do inferno do grid, onde que no GWT puro é um parto para fazer isso funcionar, mas estou achando bem legal essas ferramentas.

Att

bom, vamos a minha pergunta então, em swing a gnt geralmente tem:
um bean[code]public class Telefones implements java.io.Serializable {

private Long idtelefones;    
private String ddd;    
private String numero;    
private String ramal;    
private String contato;   
private Clientes clientesIdclientes;
private Tipotelefone tipotelefoneIdtipotelefone;

//gets and sets[/code][b]e seu table model[/b][code]public class TableModelTelefones extends AbstractTableModel {

private static final int COL_TIPO_TELEFONE = 0;
private static final int COL_DDD = 1;
private static final int COL_NUMERO = 2;
private static final int COL_RAMAL = 3;
private static final int COL_CONTATO = 4;
private List<Telefones> telefones;

public TableModelTelefones(List<Telefones> telefones) { this.telefones = new ArrayList<Telefones>(telefones); }

public void setTelefones(List<Telefones> telefones) {
    this.telefones = new ArrayList<Telefones>(telefones);
    fireTableDataChanged();
}

public int getRowCount() { return telefones.size(); }

public int getColumnCount() { return 5; }

@Override
public String getColumnName(int column) {
    if (column == COL_TIPO_TELEFONE) return "Tipo";
    if (column == COL_DDD) return "DDD";
    if (column == COL_NUMERO) return "Número";
    if (column == COL_RAMAL) return "Ramal";
    if (column == COL_CONTATO) return "Contato";
    return ""; //Nunca deve ocorrer
}

@Override
public Object getValueAt(int row, int column) {
    Telefones telefone = telefones.get(row);
    if (column == COL_TIPO_TELEFONE) return telefone.getTipotelefoneIdtipotelefone().getDescricao();
    else if (column == COL_DDD) return telefone.getDdd();
    else if (column == COL_NUMERO) return telefone.getNumero();
    else if (column == COL_RAMAL) return telefone.getRamal();
    else if (column == COL_CONTATO) return telefone.getContato();
    return ""; //Nunca deve ocorrer
}

@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {}

@Override
public Class<?> getColumnClass(int columnIndex) { return String.class;}

@Override
public boolean isCellEditable(int rowIndex, int columnIndex) { return false; }

public Telefones get(int row) { return telefones.get(row); }

}[/code]
e no gwt eu nao achei nd diferente de:[code]RecordDef recordDef = new RecordDef(
new FieldDef[]{
new StringFieldDef(“cpf”),
new StringFieldDef(“nome”)
}
);

    GridPanel grid = new GridPanel();  

    Object[][] data = getCompanyData();  
    MemoryProxy proxy = new MemoryProxy(data);  

    ArrayReader reader = new ArrayReader(recordDef);  
    Store store = new Store(proxy, reader);  
    store.load();  
    grid.setStore(store);  


    ColumnConfig[] columns = new ColumnConfig[]{  
            //column ID is company which is later used in setAutoExpandColumn  
            new ColumnConfig("CPF", "cpf", 100, true, null, "cpf"),  
            new ColumnConfig("Nome", "nome", 250, true)  
    };  

    ColumnModel columnModel = new ColumnModel(columns);  
    grid.setColumnModel(columnModel);

private Object[][] getCompanyData() {
return new Object[][]{
new Object[]{“00000000000”, “aaaaa”},
new Object[]{“11111111111”, “bbbbb”},
new Object[]{“22222222222”, “ccccc”},
new Object[]{“33333333333”, “ddddd”},
new Object[]{“44444444444”, “eeeee”}
};
}[/code]ou seja, existe alguma forma de trabalhar com um tablemodel no gwt, ou algo parecido pra q eu nao precise ficar convertendo minha lista de objetos em uma matriz e depois convertendo os dados dessa matriz em objeto novamente?

pois é vcsmetallica, na minha opinião gwt puro nao resolve muita coisa… mas com esses componentes prontos a história muda, to gostando até agora !..

cleiton herrmann

Voce ja se deparou com esse erro?

[ERROR] [teste2] - Line 32: No source code is available for type br.com.teste2.datasource.CountryData; did you forget to inherit a required module?

Att

sim cara, eu tive esse erro quando comecei a tentar fazer comunicação com o banco de dados, mais especificamente com meus beans…
resolvi colocando o código abaixo no meu modulo.gwt.xml<source path='beans'/>onde “beans” é um pacote “org.yournamehere.beans”.
acho q no seu caso se nao estiver enganado “CountryData” é uma classe e “br.com.teste2.datasource.” é o pacote que o gwt nao está encontrando, então se vc colocar o código abaixo no seu modulo.gwt.xml deve funcionar, eu acho… hahahha<source path='datasource'/>

Cara, fiz da seguinte maneira e resolveu.

Coloquei as minhas classes abaixo no pacote client.

por exemplo:

pacote princpal client :br.com.teste2.client

para as outras classes que estou usando fiz assim:

br.com.teste2.client.data
br.com.teste2.client.dadosgrid

Cara, funcionou!!!
Ma se caso o erro aparecer novamente eu faço o que vc sugeriu.

certo, pode ser tbem, mas lembre q o compilador do gwt vai compilar td q estiver no pacote client, e as vezes tem coisas q nao precisam ser compiladas por ele, ai vc deixa fora do pacote client e só informa o path pra conseguir usar, pelo menos foi isso q entendi num site gringo q vi, se eu estiver errado me corrijam por favor !!!

Entendi. Por hora vou deixar assim.
Depois pego a documetnação e dou uma lida, pq vai ser foda ficar carregando o que esta abaixo do cliente.

Nope! Se você usar a tag source indica que você quer que tal pacote também seja utilizado no lado client, ou seja, os fontes java sob esse pacote também serão convertidos para JS. Deixar um pacote fora da visão do client é não tê-lo sob o pacote client e nem sob ou marcado com a tag source.

Se as coisas apertarem por ai, postem as dúvidas no GWT Brasil Group. Pois lá o retorno é mais rápido.

opa araujo921, até q enfim apareceu mais alguem ai pra trocar idéias, hahhaha cara 3 perguntas em uma só…

  1. meus beans e classes diversas, enfim… isso tbem é convertivo pra JS ?
  2. ou é simplesmente usado nas minhas lógicas (ifs, laços, enfim…) que estão no lado client ?
  3. não seria convertido pra JS somente as classes do GWT independente de usar ou não classes apontadas pela tag ?

só pra completar minha idéia, pelo q eu entendi, as classes q nao podem ser convertidas pra JS, sempre são usadas em alguma lógica que retorna algum resultado, que é exibido em componentes gwt, que por sua vez são convertidos pra JS…

Sim, se você for usá-las no lado client, então elas também serão convertidas para JS. Desde que elas estejam no pacote client ou em algum pacote marcado com tag source.

Não, se a classe é vista no lado client, então toda classe é vista, e a mesma pode ser usada com todos os seus métodos e atributos.

Não, além das classes do GWT que estão no pacote client, também serão convertidas para JS as classes GWT em pacotes marcados com a tag source. Além disso, as suas classes que estão no pacote client ou que estão em pacotes marcados com a tag source ou sob pacotes com essa tag também serão convertidas. Pegue como exemplo o pacote server, ele não é marcado com essa tag, e sendo assim as classes nesse pacote não são vistas pelo client, o que significa que você não poderá utilizar as classes nesse pacote. Caso vc tente utilizar alguma classe nesse pacote no lado client, vc terá aquele erro apontado pelo vcsmetallica que foi de [ERROR] [teste2] - Line 32: No source code is available for type br.com.teste2.datasource.CountryData; did you forget to inherit a required module?

P.S 1: quando eu uso a palavra classe(s) não estou me referindo aos arquivos.class, e sim ao arquivos.java. Como escrevi antes, o que o GWT converte para JS são os arquivos.java.

P.S 2: Note que o GWT emula apenas um conjunto pequenos de classes do Java, isso porque o JS é infinitamente limitado se for comparado com o Java.

certo entendi…

vamos usar como exemplo um bean “Clientes”, e então uma busca no banco de dados q retorne um List, dai um laço que irá criar labels com os nomes dos clientes e adicionar num VerticalPanel, que será exibido na tela. (aqui q eu estava meio confuso) essa lógica, do laço, será executada pelo browser, em javascript, após o retorno da lista de clientes e não pela maquina virtual java como a gnt está acostumado, portanto, minhas classes tem q ser convertidas pra JS para poderem ser usadas em trechos de código executados pelo browser…

é isso ou eu ainda não entendi ?

mas ai é q esta, isso q me confundiu um pouco, se for assim, um bean “Clientes” por exemplo, virá o q ? em javascript ? vc sabe me dizer ?

vlw pelas respostas t+

[quote]vamos usar como exemplo um bean “Clientes”, e então uma busca no banco de dados q retorne um List<Clientes>, dai um laço que irá criar labels com os nomes dos clientes e adicionar num VerticalPanel, que será exibido na tela. (aqui q eu estava meio confuso) essa lógica, do laço, será executada pelo browser, em javascript, após o retorno da lista de clientes e não pela maquina virtual java como a gnt está acostumado, portanto, minhas classes tem q ser convertidas pra JS para poderem ser usadas em trechos de código executados pelo browser…

é isso ou eu ainda não entendi ? [/quote]

Sim, isso mesmo.

Esse bean vira uma function em JS. Note que em seu projeto você deve ter arquivos*.cache.html, esses arquivos contém todas as classes java que foram convertidas para JS, se você os abrir você verá que o código estará ofuscado, mas você pode torná-lo mais legível trocando o argumento do compilador de OBF para DETAILED. E se você procurar nesse(s) arquivo(s), você encontrará o seu bean client como uma function, na verdade você verá várias functions relacionadas com o seu bean. Veja o exemplo abaixo extraído de um desses arquivos compilados pelo GWT.

function com_javaneses_web_desktop_demo_client_ClientBean_ClientBean__V(){
}

function com_javaneses_web_desktop_demo_client_ClientBean(){
}

_ = com_javaneses_web_desktop_demo_client_ClientBean_ClientBean__V.prototype = com_javaneses_web_desktop_demo_client_ClientBean.prototype = new java_lang_Object;
_.getClass__Ljava_lang_Class_2$ = function com_javaneses_web_desktop_demo_client_ClientBean_getClass__Ljava_lang_Class_2(){
return com_google_gwt_lang_ClassLiteralHolder_Lcom_1javaneses_1web_1desktop_1demo_1client_1ClientBean_12_1classLit;
}
;
_.com_javaneses_web_desktop_demo_client_ClientBean_firstName = null;
_.com_javaneses_web_desktop_demo_client_ClientBean_lastName = null;

certo araujo921, agora deu uma boa clareada nas idéias, na verdade eu nem tinha visto esses arquivos *.cache.html que vc falou, vou dar uma procurada aqui por eles…
por enquanto vlw pelas explicações e até a proxima :smiley: