Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    [ListGrid/RPC] Listgrid keep empty whereas data are retrieved

    Hi,

    I'm evaluating SmartGWT. I made a sample application which retrieves data from server (via GWT RPC) and display them in a listgrid. And here is my problem because nothing appear in the listgrid but "No items to show" message.

    Here is my code :

    The main class (entryPoint) :

    Code:
    package fr.ct.client;
    
    import com.google.gwt.core.client.EntryPoint;
    import com.google.gwt.core.client.GWT;
    import com.smartgwt.client.widgets.layout.HLayout;
    
    import fr.ct.client.widget.WCTGrillePers;
    
    public class Principal implements EntryPoint {
    
    	private HLayout mainLayout;
    
    	public void onModuleLoad() {
    
    		mainLayout = new HLayout();
                    mainLayout.setWidth100();
                    mainLayout.setHeight100();
    
                    affichePanneau();
    	}
    
    	private void affichePanneau() {
    		WCTGrillePers grillePers = new WCTGrillePers();
    		mainLayout.addMember(grillePers);
    
    		mainLayout.draw();
    	}
    }
    Listgrid widget :

    Code:
    package fr.ct.client.widget;
    
    import com.smartgwt.client.types.Alignment;
    import com.smartgwt.client.types.Autofit;
    import com.smartgwt.client.types.ListGridFieldType;
    import com.smartgwt.client.types.VerticalAlignment;
    import com.smartgwt.client.widgets.Canvas;
    import com.smartgwt.client.widgets.grid.ListGrid;
    import com.smartgwt.client.widgets.grid.ListGridField;
    import com.smartgwt.client.widgets.layout.HLayout;
    import com.smartgwt.client.widgets.layout.LayoutSpacer;
    import com.smartgwt.client.widgets.layout.VLayout;
    
    import fr.ct.client.model.PersonneDS;
    
    public class WCTGrillePers extends Canvas {
    
    	public WCTGrillePers() {
    
    		final ListGrid grille = new ListGrid();
    		grille.setWidth(250);
    		grille.setAlternateRecordStyles(true);
    		grille.setShowAllRecords(true);
    
    //		ListGridField matricule = new ListGridField("matricule", "Matricule", 60);
    //		matricule.setType(ListGridFieldType.INTEGER);
    //		ListGridField nom = new ListGridField("nom", "Nom", 80);
    //		ListGridField prenom = new ListGridField("prenom", "Prenom", 80);
    //
    //		grille.setFields(new ListGridField[] {matricule, nom, prenom});
    
    		grille.setCanResizeFields(true);
    		grille.setCanReorderFields(true);
    		grille.setCanSort(true);
    
    		grille.setDataSource(PersonneDS.getInstance());
    		grille.setAutoFetchData(true);
    
    		grille.setAutoFitData(Autofit.BOTH);
    		grille.fetchData();
    
    		setShowResizeBar(true);
    		setResizeBarTarget("next");
    
    		VLayout vlayout = new VLayout();
    		vlayout.setDefaultLayoutAlign(Alignment.CENTER);
    		vlayout.addMember(new LayoutSpacer());
    		vlayout.addMember(grille);
    		vlayout.addMember(new LayoutSpacer());
    
    		HLayout hlayout = new HLayout();
    		hlayout.setHeight100();
    		hlayout.setWidth100();
    		hlayout.setDefaultLayoutAlign(VerticalAlignment.CENTER);
    		hlayout.addMember(new LayoutSpacer());
    		hlayout.addMember(vlayout);
    		hlayout.addMember(new LayoutSpacer());
    
    		addChild(hlayout);
    	}
    }
    Custom datasource :

    Code:
    package fr.ct.client.model;
    
    import java.util.List;
    
    import com.google.gwt.core.client.GWT;
    import com.google.gwt.user.client.rpc.AsyncCallback;
    import com.smartgwt.client.core.DataClass;
    import com.smartgwt.client.data.DataSource;
    import com.smartgwt.client.data.fields.DataSourceDateField;
    import com.smartgwt.client.data.fields.DataSourceIntegerField;
    import com.smartgwt.client.data.fields.DataSourceTextField;
    import com.smartgwt.client.types.FieldType;
    
    import fr.ct.client.PersonnelService;
    import fr.ct.client.PersonnelServiceAsync;
    
    public class PersonneDS extends DataSource {
    
    	private PersonnelServiceAsync service;
    	private static PersonneDS instance = null;
    
    	public static PersonneDS getInstance() {
    		if (instance == null) {
    			instance = new PersonneDS("personne_ds");
    		}
    
    //		instance.fetchData();
    
    		return instance;
    	}
    
    	public PersonneDS(String id) {
    		setID(id);
    		DataSourceIntegerField matricule = new DataSourceIntegerField("matricule", "Matricule");
    		DataSourceTextField nom = new DataSourceTextField("nom", "Nom");
    		DataSourceTextField prenom = new DataSourceTextField("prenom", "Prenom");
    		DataSourceDateField dentr = new DataSourceDateField("dentr", "Entre le");
    		DataSourceDateField dmaj = new DataSourceDateField("dmaj", "Calcule au");
    		DataSourceTextField email = new DataSourceTextField("email", "Email");
    
    		setFields(matricule, nom, prenom, dentr, dmaj, email);
    		setClientOnly(true);
    
    		if (service == null) {
    			service = (PersonnelServiceAsync)GWT.create(PersonnelService.class);
    		}
    
    		service.getPersonnes(new AsyncCallback<List<Personne>>() {
    
    			public void onFailure(Throwable caught) {
    				System.out.println("[ERREUR] Probleme de recuperation des personnes");
    				caught.printStackTrace();
    			}
    
    			public void onSuccess(List<Personne> result) {
    				PersonneDC[] donnees = new PersonneDC[result.size()];
    
    				int i = 0;
    				for(Personne p : result) {
    					donnees[i] = new PersonneDC(p.getMatricule(), p.getNom(), p.getPrenom(),
    							p.getDentr(), p.getDmaj(), p.getEmail());
    					i++;
    				}
    
    				System.out.println("Recuperation des donnees en cours.....");
    				setTestData(donnees);
    				System.out.println("Nb personnes : " + donnees.length);
    				for(PersonneDC p : donnees) {
    					System.out.println(p.getMatricule() + "/" + p.getNom() + "/" + p.getPrenom());
    				}
    				System.out.println("--------------------");
    				for(DataClass e : getTestData()) {
    					System.out.println(e.getAttributeAsInt("matricule")+ "/" + e.getAttributeAsString("nom") + "/" + e.getAttributeAsString("prenom"));
    				}
    				System.out.println("Recuperation des donnees terminee.");
    			}
    
    		});
    	}
    }
    Custom dataclass :

    Code:
    package fr.ct.client.model;
    
    import java.util.Date;
    
    import com.smartgwt.client.core.DataClass;
    
    public class PersonneDC extends DataClass {
    
    	public PersonneDC(Integer matricule, String nom, String prenom, Date dentr, Date dmaj, String email){
    		setAttribute("matricule", matricule);
    		setAttribute("nom", nom);
    		setAttribute("prenom", prenom);
    		setAttribute("dentr", dentr);
    		setAttribute("dmaj", dmaj);
    		setAttribute("email", email);
    	}
    
    	public Integer getMatricule() {
    		return getAttributeAsInt("matricule");
    	}
    
    	public String getNom() {
    		return getAttributeAsString("nom");
    	}
    
    	public String getPrenom() {
    		return getAttributeAsString("prenom");
    	}
    
    	public Date getDentr() {
    		return getAttributeAsDate("dentr");
    	}
    
    	public Date getDmaj() {
    		return getAttributeAsDate("dmaj");
    	}
    
    	public String getEmail() {
    		return getAttributeAsString("email");
    	}
    }
    The POJO :

    Code:
    package fr.ct.client.model;
    
    import java.io.Serializable;
    import java.util.Date;
    
    public class Personne implements Serializable {
    
    	private Integer matricule;
    	private String nom;
    	private String prenom;
    	private Date dentr;
    	private Date dmaj;
    	private String email;
    
    	public Personne() {
    
    	}
    
    	public Personne(Integer matricule, String nom, String prenom) {
    		this.matricule = matricule;
    		this.nom = nom;
    		this.prenom = prenom;
    		this.dentr = new Date();
    		this.dmaj = new Date();
    		this.email = "";
    	}
    
    	public Personne(Integer matricule, String nom, String prenom, Date dentr, Date dmaj, String email) {
    		this.matricule = matricule;
    		this.nom = nom;
    		this.prenom = prenom;
    		this.dentr = dentr;
    		this.dmaj = dmaj;
    		this.email = email;
    	}
    
    	public void setEmail(String email) {
    		this.email = email;
    	}
    
    	public void setDentr(Date dentr) {
    		this.dentr = dentr;
    	}
    
    	public void setDmaj(Date dmaj) {
    		this.dmaj = dmaj;
    	}
    
    	public Integer getMatricule() {
    		return this.matricule;
    	}
    
    	public String getNom() {
    		return this.nom;
    	}
    
    	public String getPrenom() {
    		return this.prenom;
    	}
    
    	public Date getDentr() {
    		return this.dentr;
    	}
    
    	public Date getDmaj() {
    		return this.dmaj;
    	}
    
    	public String getEmail() {
    		return this.email;
    	}
    
    }
    The GWT RPC service :

    Code:
    package fr.ct.client;
    
    import java.util.List;
    
    import com.google.gwt.user.client.rpc.RemoteService;
    import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
    
    import fr.ct.client.model.Personne;
    
    @RemoteServiceRelativePath("personnel")
    public interface PersonnelService extends RemoteService {
    
    	public List<Personne> getPersonnes();
    
    }
    Code:
    package fr.ct.client;
    
    import java.util.List;
    
    import fr.ct.client.model.Personne;
    import com.google.gwt.user.client.rpc.AsyncCallback;
    
    public interface PersonnelServiceAsync {
    
    	public void getPersonnes(AsyncCallback<List<Personne>> callback);
    
    }
    Code:
    package fr.ct.server;
    
    import java.util.List;
    
    import com.google.gwt.user.server.rpc.RemoteServiceServlet;
    
    import fr.ct.client.PersonnelService;
    import fr.ct.client.model.Personne;
    import fr.ct.server.model.TestData;
    
    public class PersonnelServiceImpl extends RemoteServiceServlet implements PersonnelService {
    
    	/**
    	 *
    	 */
    	private static final long serialVersionUID = 1L;
    
    	List<Personne> liste;
    
    	public PersonnelServiceImpl() {
    		liste = TestData.getPersonnes();
    	}
    
    	public List<Personne> getPersonnes() {
    		return liste;
    	}
    }
    I can see through generated traces that data are retrieved from server and stored in my datasource instance (via setTestData() method).

    The listgrid shows the rights fields as columns, from the datasource. But, it still keeps empty... no data on screen. Why ?

    I must forget something, an obvious one, certainly !!!!

    Thanks.

    #2
    What version / build of SmartGWT are you using? There was a change made recently to support calling setTestData after the widget has been rendered (as opposed to setting it at initialization).

    Can you try running your code against a SVN build?

    Sanjiv

    Comment


      #3
      Actually it might be simpler than that. It looks like fetchData() is happening on the grid before the DataSource has actually loaded data. Best to call a method on the DataSource to the load data, wait for it to load, then create the grid.

      Comment


        #4
        I downloaded svn version yesterday and built it. When build process finished, I got version 1.0b2.

        Did you see any omission or error in my code ?

        Thanks a lot.

        Comment


          #5
          I had the same issue (I think there is a problem with the setTestData() method).

          My workaround is :

          to replace the DataClass object with a ListGridRecord (same method and constructor)
          And replace the setDataTest by a bunch of call to the addData (one per record) method on my store.

          It works now fine for me, my db data are correctly displayed in the grid

          Regards

          Comment


            #6
            Thanks Olinsha for your workaround. I tried it and it works fine for me too.

            I think, like you, that the setTestData method IS the problem.

            Thanks once again.

            Comment


              #7
              The addData-trick works for me as well, however I do get warnings in my gwt-log. The code that I use when retrieving data looks like this:
              Code:
                for (Vm vm : result) {
                  ListGridRecord g = VMListEntry(vm) ;
                  addData(g);
                }
              where VMListEntry is a class extending ListGridRecord. My log file now shows, for each record retrieved, an entry like this
              Code:
              [WARN] Malformed JSNI reference 'constructor'; expect subsequent failures
              java.lang.NoSuchFieldError: constructor
              	at com.google.gwt.dev.shell.CompilingClassLoader$DispatchClassInfoOracle.getDispId(CompilingClassLoader.java:119)
              	at com.google.gwt.dev.shell.CompilingClassLoader.getDispId(CompilingClassLoader.java:531)
              	at com.google.gwt.dev.shell.ie.IDispatchProxy.getIDsOfNames(IDispatchProxy.java:124)
              	at com.google.gwt.dev.shell.ie.IDispatchImpl.GetIDsOfNames(IDispatchImpl.java:273)
              	at com.google.gwt.dev.shell.ie.IDispatchImpl.method5(IDispatchImpl.java:189)
              	at org.eclipse.swt.internal.ole.win32.COMObject.callback5(COMObject.java:108)
              	at org.eclipse.swt.internal.ole.win32.COM.VtblCall(Native Method)
              	at org.eclipse.swt.internal.ole.win32.IDispatch.Invoke(IDispatch.java:64)
              	at org.eclipse.swt.ole.win32.OleAutomation.invoke(OleAutomation.java:493)
              	at org.eclipse.swt.ole.win32.OleAutomation.invoke(OleAutomation.java:417)
              	at com.google.gwt.dev.shell.ie.ModuleSpaceIE6.doInvokeOnWindow(ModuleSpaceIE6.java:67)
              	at com.google.gwt.dev.shell.ie.ModuleSpaceIE6.doInvoke(ModuleSpaceIE6.java:152)
              	at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:447)
              	at com.google.gwt.dev.shell.ModuleSpace.invokeNativeVoid(ModuleSpace.java:248)
              	at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeVoid(JavaScriptHost.java:107)
              	at com.smartgwt.client.data.DataSource.addData(DataSource.java)
              	at nl.tudelft.opencenter.ui.client.VMDataSource$1.onSuccess(VMDataSource.java:50)
              
              .. more lines deleted...
              Line 50 of the last message is the addData-call in the snippet above.

              Can anyone tell me if there is a way to get rid of this, or wether I should be worried at all...

              Thanks.

              Comment


                #8
                You can safely ignore these messages.

                Comment


                  #9
                  I was sent here from my own thread http://forums.smartclient.com/showthread.php?t=3721 (geee, how do you create a proper link here)...

                  I also worked with the example, and the Word document that explains it, posted by a GWT-Ext developer in their forum at http://www.gwt-ext.com/forum/viewtopic.php?f=0&t=3465&p=10991#p10991.

                  What irritates me with both solutions is that the RPC invocation happens in either the data source's constructor or in a custom private method. From the DataSource API I concluded that I simply needed to override the fetchData() method for that. It would get called by the widget that sits on top of the data source.
                  I tried that, but fetchData() was never called. Hence, I'm still stuck with a solution that "feels" wrong.

                  Any thoughs on this?

                  Comment


                    #10
                    After a call to setTestData() to populate the dataSource, there will be potentially many calls to fetchData(), so that's not really the right override point.

                    Regardless, this approach of using clientOnly DataSources is a temporary workaround for using existing GWT-RPC services in a style similar to GWT-Ext. We'll be showing examples of using GWT-RPC services in a way that makes more sense with SmartClient's DataSources soon.

                    Comment


                      #11
                      We all look forward to it.
                      Preloading all the data (in my case, several thousand records) when a user opens the page significantly slows down normal IE and kills the hosted-mode IE.

                      Hence, loading data on demand is necessary, but I dont see what methods I should override to achieve this functionality. Does anyone have an example of doing this in SmartGWT?

                      Comment


                        #12
                        Works for me as well. Thanks.

                        Any news when we can skip the workaround?

                        By the way, this is how I did it (if anybody might be interested in):

                        Snipped from my class which extends DataSource
                        Code:
                        ...public void onSuccess(List<Vehicle> result) {
                        
                        	// Map Vehicle-Entities to ListGridRecords
                        	for(Vehicle vehicle : result) {
                        		addData(new VehicleLGR(
                        			vehicle.getId(), 
                        			vehicle.getDescription(), 
                        	}
                        	...
                        My VehicleLGR which replaces the DataClass
                        Code:
                        public class VehicleLGR extends ListGridRecord
                        {
                        	
                        	public VehicleLGR(int id, String description){
                        		setAttribute("id", id);
                        		setAttribute("description", description);
                        	}
                        
                        	public String getId() {
                        		return getAttributeAsInteger("id");
                        	}
                        
                        	public String getDescription() {
                        		return getAttributeAsString("description");
                        	}
                        
                        }

                        Comment


                          #13
                          Originally posted by tanguylaver
                          Thanks Olinsha for your workaround. I tried it and it works fine for me too.

                          I think, like you, that the setTestData method IS the problem.

                          Thanks once again.
                          Hi Tanguylaver,

                          I'm trying do implement a grid like your example.
                          I did a copy of the code that you post.

                          So, could you please post the TestData class code?

                          Thanks in advance...

                          Comment


                            #14
                            GWT-RPC with SmartGWT DataSources

                            Hi Isomorphic/Everyone,

                            I hope someone could point me to links showing examples of using GWT-RPC services in a way that makes more sense with SmartGWT DataSources.

                            Thanks and Regards.

                            Comment

                            Working...
                            X