Uploaded image for project: 'ZK'
  1. ZK
  2. ZK-4549

Adding items then clear() a ListModel linked to a Grid during afterCompose cause IndexOutOfBoundsException

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Major Major
    • 9.5.0
    • 8.6.0, 9.0.1
    • None
    • Security Level: Jimmy
    • None
    • ZK 9.5.0 S1
    • None

      Steps to Reproduce

      Run fiddle

      https://zkfiddle.org/sample/h0diii/3-Grid-ROD-IndexOutOfBounds-example#source-2

      Current Result

      In Java console:

       

      java.lang.IndexOutOfBoundsException: Index: 0, Size: 0java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(Unknown Source) at java.util.ArrayList.get(Unknown Source) at org.zkoss.zul.ListModelList.getElementAt(ListModelList.java:158) at org.zkoss.zul.Grid$Renderer.render(Grid.java:1246) at org.zkoss.zul.Grid.doInitRenderer(Grid.java:1126) at org.zkoss.zul.Grid.onInitRender(Grid.java:1081) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:3165) at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:3096) at org.zkoss.zk.ui.impl.EventProcessor.process(EventProcessor.java:138) at org.zkoss.zk.ui.impl.UiEngineImpl.processEvent(UiEngineImpl.java:1890) at org.zkoss.zk.ui.impl.UiEngineImpl.process(UiEngineImpl.java:1662) at org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage0(UiEngineImpl.java:556) at org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage(UiEngineImpl.java:377) at org.zkoss.zk.ui.http.DHtmlLayoutServlet.process(DHtmlLayoutServlet.java:215) at org.zkoss.zk.ui.http.DHtmlLayoutServlet.doGet(DHtmlLayoutServlet.java:140) at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:401) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:450) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at org.mortbay.jetty.Server.handle(Server.java:326) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:928) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:549) at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410) at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
      

       

       

      in Client, error window:

       
      Index: 0, Size: 0
       

      Expected Result

      No error

      Debug Information

      When the listmodel has been linked to a grid with grid.setModel(model)

      Calling model.add(entry) cause the grid to generate Row objects for each entry (during afterCompose)

      Creating row at:

       

      Row.<init>() line: 39 Row.<init>() line: 39 LiveGridDataLoader(GridDataLoader).newRow(RowRenderer) line: 203 LiveGridDataLoader(GridDataLoader).newUnloadedItem(Object, int) line: 189 LiveGridDataLoader.loadModel(int, int) line: 230 LiveGridDataLoader.syncModel(int, int) line: 187 LiveGridDataLoader.doLiveListDataChange(ListDataEvent) line: 114 LiveGridDataLoader.doListDataChange(ListDataEvent) line: 96 Grid.onListDataChange(ListDataEvent) line: 1175 Grid.access$1500(Grid, ListDataEvent) line: 220 Grid$2.onChange(ListDataEvent) line: 916 ListModelList<E>(AbstractListModel<E>).fireEvent(int, int, int) line: 73 ListModelList<E>.add(E) line: 170 GridOutOfBoundsComposer.doAfterCompose(Component) line: 23 UiEngineImpl.doAfterCompose(Composer, Component) line: 625 
      

       

       

      If later during afterCompose, the model is updated (with clear() for example), the grid still has these row objects preloaded during onInitRender(), resulting is the grid trying to poll model data for rows that no longer have a model entry matching their index in the ListModel

      Grid.doInitRenderer() line: 1125 Grid.doInitRenderer() line: 1125 Grid.onInitRender() line: 1081 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available Method.invoke(Object, Object...) line: not available Grid(AbstractComponent).service(Event, Scope, List<EventListenerInfo>, EventHandler, Method, boolean) line: 3165 Grid(AbstractComponent).service(Event, Scope) line: 3096 EventProcessor.process() line: 138 UiEngineImpl.processEvent(Desktop, Component, Event) line: 1890 
      

      Workaround

      Force the grid to reset ListModel information by setting a null model, then setting the right model:

              grid.setModel((ListModel)null);
              grid.setModel(myModel);
      

       

            Leon03 Leon03
            MDuchemin MDuchemin
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:

                Estimated:
                Original Estimate - 1 day
                1d
                Remaining:
                Remaining Estimate - 1 day
                1d
                Logged:
                Time Spent - Not Specified
                Not Specified