Announcement

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

    ListGrid incomplete on load

    SmartGWT 3.0 Power NB from Aug 28

    The ListGrid on my app's initial page consistently renders the last row (sometimes two) with missing components. I've overridden createRecordComponent() in order to create control buttons based on the record state, and it's those buttons that are not rendered in the initial draw; any subsequent navigation to the page is fine, all buttons show up. I also have a refresh button that fixes it but I really need the display to be complete on startup.

    Code:
    public class SummaryTable extends ListGrid
    {
       /**
        * Constructor.
        */
       public SummaryTable(DataSource aDatasource, final RPCCallback anRPCCallback, NotificationBar aNotificationBar)
       {
          super();
          
          theRPCCallback = anRPCCallback;      
          theNotificationBar = aNotificationBar; 
    
          setDataSource(aDatasource);
          
          // not all fields are displayed in the table
          setUseAllDataSourceFields(false);
          
          setAutoFetchData(true);
          setCellPadding(CELL_PADDING);
    
          // render each cell individually in order to format
          setShowRecordComponents(true);
          setShowRecordComponentsByCell(true);
          setCanEdit(false);
    
          ListGridField statusField = new ListGridField(STATUS_FIELD);
          statusField.setShowValueIconOnly(true);
    
          // get a map of all ElementServiceState status codes-to-icons that can be passed into 
          // the ListGridField.setValueIcons() method, a SmartGWT convenience method
          Map<String, String> stateToIconMap = ElementServiceState.getStateToIconMap();
          statusField.setValueIcons(stateToIconMap);
          statusField.setValueIconSize(BUTTON_HEIGHT);
    
          ListGridField nameField = new ListGridField(ELEMENT_SERVICE_FIELD, ELEMENT_SERVICE_DISPLAY_NAME);
          
          ListGridField commandField = new ListGridField(COMMAND, COMMAND_DISPLAY_NAME);
          commandField.setAlign(Alignment.CENTER);
    
          setFields(statusField, nameField, commandField);
    
       }
    
       /**
        * This method is overridden in order to format the timestamp from the database and also to create command buttons
        * that depend on the status code of the associated record (an ElementService).
        */
       @Override
       protected Canvas createRecordComponent(final ListGridRecord aRecord,
                                              final Integer aColumnNumber)
       {
          // returning null will result in all table cells using default Canvas supplied by the framework 
          // only the canvases for the Command cells will be supplied in this method
          Canvas recordCanvas = null;
          
          String fieldName = getFieldName(aColumnNumber);
          final String elementService = aRecord.getAttribute(FUNCTION);
    
          // the status of this record
          final ElementServiceState status = ElementServiceState.getStatus(aRecord.getAttribute(STATUS_FIELD));
    
          // the timestamp value read from the database must be formatted into GOES-R date display
          if (fieldName.equals(LAST_REPORTED_TIME_FIELD))
          {
             String displayedDate = ServiceManagementInterface.formatTimestamp(aRecord.getAttribute(LAST_REPORTED_TIME_FIELD));
             aRecord.setAttribute(LAST_REPORTED_TIME_FIELD, displayedDate);
          }
          else if (fieldName.equals(COMMAND))
          {
             final ResourceManagerCommand command = status.getCommand();
             
             // add a command button if this element service has a valid command
             if (command != ResourceManagerCommand.NONE)
             {
                // create the buttons used to start and stop element services
                recordCanvas = new HLayout();
                recordCanvas.setHeight(BUTTON_HEIGHT);
                recordCanvas.setAlign(Alignment.CENTER);
    
                IButton commandBtn = ServiceManagementInterface.makeIconButton(command.getIcon());
    
                String blank = " ";
                commandBtn.setPrompt(command.getAction() + blank + elementService);
    
                // command button uses an anonymous inner click handler class
                commandBtn.addClickHandler(new ClickHandler() {
                   public void onClick(ClickEvent anEvent)
                   {
                      if (command.equals(ResourceManagerCommand.START_ES))
                      {
                         ConfirmCommand dialog = new ConfirmCommand(ResourceManagerCommand.START_ES,
                                                                    elementService,
                                                                    theRPCCallback,
                                                                    theNotificationBar);
                         dialog.show();
                      }
                      else if (command.equals(ResourceManagerCommand.STOP_ES))
                      {
                         // if the command is not ResourceManagerCommand.START_ES,
                         // then ResourceManagerCommand.STOP_ES is deduced
                         ConfirmCommand dialog = new ConfirmCommand(ResourceManagerCommand.STOP_ES,
                                                                    elementService,
                                                                    theRPCCallback,
                                                                    theNotificationBar);
                         dialog.show();
                      }
                      else
                      {
                         SC.warn("Invalid command for " + elementService);
                      }
                   }
                });// end ClickHandler
    
                ((Layout) recordCanvas).addMember(commandBtn);
             }
          }
    
          return recordCanvas;
       }
    
    }
    Any help greatly appreciated!

    #2
    There was a fix in this area after your build. Can you try the latest 3.0p build?

    Comment


      #3
      Will do. Four minute response time - awesome!

      Comment


        #4
        Unfortunately the update did not effect this issue. I put a sysout into the createRecordComponent method and found that it's being called fewer times than there are records, showing exactly why those last few buttons are not showing up.

        I'm redesigning the code to create the buttons in the constructor.

        Comment


          #5
          By design, components are not created until records are scrolled into view (so createRecordComponent won't be called).

          It's not quite clear if you're saying there are records that are in view but for which createRecordComponent() has not been called.

          This would potentially be a framework bug, but could also be created by doing something that interferes with the ListGrid's ability to figure out what records are currently visible, such as using CSS to affect record heights instead of setting listGrid.cellHeight.

          If visible records with no buttons is what you're seeing, if you can isolate this to a runnable test case we can take a look.

          Comment


            #6
            Sorry for any confusion but the case is that some records which are in view have no buttons. In this display there are always 8 exactly records and more than enough room to view all of them. What I saw in the sysout was that createRecordComponent was called only 6 times. I'm not doing anything with CSS at all.

            What do you need other than the class I gave you above, which extends ListGrid, to constitute a runnable test case? Here s my ds.xml:
            Code:
            <DataSource 
            	ID="function"
            	dataFormat="iscServer"
            	serverType="sql"
            	dataSourceVersion="1"
            	dbName="ServiceManagement" 
            	schema="foo"
            	tableName="FUNCTION">
            	<fields>
            		<field name="FUNCTION_NAME" 	  type="text"   title="Name" 	primaryKey="true"/>
            		<field name="LAST_REPORTED_STATE" type="number" title="State"/>
            			<valueMap>
            				<value ID="0">Inactive</value>
            				<value ID="1">Up</value>
            				<value ID="2">Down</value>
            				<value ID="3">Degraded</value>
            			</valueMap>
            		<field name="LAST_REPORTED_TIME"  type="number" title="Updated"/>
            	</fields>	
            </DataSource>
            Also, for completeness, here is the code to create the button:
            Code:
               /**
                * Create uniform buttons for commands.
                * 
                * @param anIcon
                *    name of an icon file
                * @return
                *    a uniform button with the appropriate icon
                */
               public static IButton makeIconButton(String anIcon)
               {
                  IButton button = new IButton("");
                  button.setHeight(BUTTON_HEIGHT);
                  button.setWidth(BUTTON_HEIGHT);
                  button.setIcon(anIcon);
                  button.setIconSize(12);
                  button.setShowHover(true);
                  int extraSpace = 10;
                  button.setExtraSpace(extraSpace);
                  return button;
               }
            Unfortunately I've been directed to find a workaround instead of preparing code I can post here.
            Last edited by susanpemble; 9 Nov 2012, 10:15. Reason: more detail

            Comment


              #7
              We just need a way to reproduce the problem. We have a dozen test cases covering just this one area (ensuring recordComponents are drawn when they should be and not drawn when they don't need to be), so given that all of these are passing, you must be doing something pretty novel that we can't simply guess.

              So the best thing would be to closely compare your code to the (working) samples and eliminate differences until you find the culprit.

              The first thing we would do is revert to the default skin and make the grid the only component on the page.

              Comment


                #8
                I am using the default skin, and the listgrid is the only thing in the layout other than a very simple toolbar above it. There is nothing remotely novel about what I'm doing. I tried to attach a screenshot but I'm working to make one small enough to upload.
                Last edited by susanpemble; 9 Nov 2012, 10:44.

                Comment


                  #9
                  Unfortunately that does not move us forward, because that's exactly what our (several) test cases look like.

                  If it's really that simple, it should also be trivial to put together as code we can run.

                  Comment


                    #10
                    OK, I don't mean to be dense but are you asking me to prepare an Eclipse project and zip it up and post it? It seems like you could take my class that extends ListGrid with its ds.xml and substitute them into your test project and see what happens. Since I don't have your test code I need you to tell me more about what it is you need from me.
                    Attached Files
                    Last edited by susanpemble; 9 Nov 2012, 10:48.

                    Comment


                      #11
                      No, we never ask for Eclipse projects - as the FAQ says, be minimal, ideally just a single .java file that can be dropped into a standard project.

                      Your code has a ton of references to other classes. It is not runnable, and in trimming code off to make it runnable, it's very likely we'll deactivate whatever code is actually creating the problem.

                      So we're just asking for standard debugging procedure here: deactivate code until you find the culprit, and if you end up with something that's just a grid with some settings, you can pass it to us as a possible framework bug.

                      Comment


                        #12
                        I apologize for being testy. Long hours - no excuse. I'm starting 2 weeks vacation at COB today and trying to wrap things up. Everyone who posts here is frustrated and we need to maintain an appropriately professional decorum.

                        I've been working on a standalone class but there is a lot to it. I wonder whether this stripped down class helps at all:
                        Code:
                        package com.foo.bar.client;
                        
                        import com.smartgwt.client.data.DataSource;
                        import com.smartgwt.client.types.Alignment;
                        import com.smartgwt.client.util.SC;
                        import com.smartgwt.client.widgets.Canvas;
                        import com.smartgwt.client.widgets.IButton;
                        import com.smartgwt.client.widgets.events.ClickEvent;
                        import com.smartgwt.client.widgets.events.ClickHandler;
                        import com.smartgwt.client.widgets.grid.ListGrid;
                        import com.smartgwt.client.widgets.grid.ListGridField;
                        import com.smartgwt.client.widgets.grid.ListGridRecord;
                        import com.smartgwt.client.widgets.layout.HLayout;
                        import com.smartgwt.client.widgets.layout.Layout;
                        
                        public class SummaryTable extends ListGrid
                        {  
                           public SummaryTable()
                           {
                              super();      
                              setDataSource(DataSource.get("function"));
                              setUseAllDataSourceFields(false);
                              
                              setAutoFetchData(true);
                              setCellPadding(10);
                        
                              setShowRecordComponents(true);
                              setShowRecordComponentsByCell(true);
                              setCanEdit(false);
                        
                              ListGridField statusField = new ListGridField("LAST_REPORTED_STATE");
                              ListGridField nameField = new ListGridField("FUNCTION_NAME", "Element Service");      
                              ListGridField commandField = new ListGridField("COMMAND", "Command");   
                        
                              setFields(statusField, nameField, commandField);
                        
                           }
                        
                           @Override
                           protected Canvas createRecordComponent(final ListGridRecord aRecord, final Integer aColumnNumber)
                           {
                              Canvas recordCanvas = null;      
                              String fieldName = getFieldName(aColumnNumber);
                        
                              if (fieldName.equals("COMMAND"))
                              {         
                                 System.out.println("adding button ");
                                 
                                 recordCanvas = new HLayout();
                                 recordCanvas.setHeight(20);
                                 recordCanvas.setAlign(Alignment.CENTER);
                        
                                 IButton commandBtn = new IButton("");
                                 commandBtn.setHeight(20);
                                 commandBtn.setWidth(20);
                                 commandBtn.setIcon("stopped.png");
                                 commandBtn.setIconSize(12);
                                 
                                 commandBtn.addClickHandler(new ClickHandler() {
                                    public void onClick(ClickEvent anEvent)
                                    {
                                       SC.warn("Button click");
                                    }
                                 });
                        
                                 ((Layout) recordCanvas).addMember(commandBtn);
                              }
                              return recordCanvas;
                           }
                        }
                        How do you recommend I provide sample data for a standalone test case?

                        Comment


                          #13
                          Its usually easiest to make a little client-only dataSource. That way you can have a small for-loop build a set of records of the appropriate length / appropriate test data and apply it to the DS via setTestData(). Alternatively you could define test data in XML format and show us that along with the datasource.ds.xml file.

                          Ultimately your complete test case would probably be an EntryPoint class with an onModuleLoad that creates the dataSource and populates it with test data, or loads it from a ds.xml file if you prefer, creates and draws the components in question (the grid instance, etc) and lets us reproduce the problem on our end.

                          Comment


                            #14
                            I'm back from two weeks off and I have a workaround. I added a DataArrivedHandler in the constructor for my ListGrid extension and use it to redraw only on the first rendering. Can't say why it works, but it does.

                            Code:
                                  addDataArrivedHandler(new DataArrivedHandler() {
                                     
                                     @Override
                                     public void onDataArrived(DataArrivedEvent event)
                                     {
                                        if (isFresh)
                                        {
                                           isFresh = false;
                                           markForRedraw();
                                        }            
                                     }
                                  });

                            Comment


                              #15
                              I had a similar problem.
                              In my case only the last row was not rendered, "createRecordComponent" was never called for it. Only when resizing the window it was invoked.
                              I then realized that I had set "setShowAllRecords(true)" on the grid. After removing it, it worked.

                              Comment

                              Working...
                              X