0

LiveListboxDataLoader triggers an IndexOutOfBoundException

asked 2013-07-29 11:36:05 +0800

cvarona gravatar image cvarona
554 1 6

Hi,

I've come across an strange, scheduled event (not triggered by the user) meant to refresh live listboxes that ends up causing an IndexOutOfBoundException if the target listbox happens to be empty:

SEVERE: >>java.lang.IndexOutOfBoundsException: Index: 1
>>      at java.util.AbstractSequentialList.get(AbstractSequentialList.java:90)
>>      at org.zkoss.zul.Listbox$1.get(Listbox.java:365)
>>      at org.zkoss.zul.Listbox$1.get(Listbox.java:359)
>>      at org.zkoss.zkmax.zul.impl.LiveListboxDataLoader.loadModelAndRenderItems(LiveListboxDataLoader.java:242)
>>      at org.zkoss.zkmax.zul.impl.LiveListboxDataLoader.access$200(LiveListboxDataLoader.java:60)
>>      at org.zkoss.zkmax.zul.impl.LiveListboxDataLoader$1.onEvent(LiveListboxDataLoader.java:289)
>>      at org.zkoss.zkmax.zul.impl.LiveListboxDataLoader$1.onEvent(LiveListboxDataLoader.java:278)
>>      at org.zkoss.zk.ui.AbstractComponent.onEvent(AbstractComponent.java:2742)
>>      at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:2713)
>>      at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:2654)
>>      at org.zkoss.zk.ui.impl.EventProcessor.process(EventProcessor.java:136)
>>      at org.zkoss.zk.ui.impl.UiEngineImpl.processEvent(UiEngineImpl.java:1717)
>>      at org.zkoss.zk.ui.impl.UiEngineImpl.process(UiEngineImpl.java:1502)
>>      at org.zkoss.zk.ui.impl.UiEngineImpl.execUpdate(UiEngineImpl.java:1212)
>>      at org.zkoss.zk.au.http.DHtmlUpdateServlet.process(DHtmlUpdateServlet.java:600)
>>      at org.zkoss.zk.au.http.DHtmlUpdateServlet.doGet(DHtmlUpdateServlet.java:482)
>>      at org.zkoss.zk.au.http.DHtmlUpdateServlet.doPost(DHtmlUpdateServlet.java:491)
>>      at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
>>      at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)

I have two related listboxes; the first shows n items of some kind, the second shows the m values that make up a multiple property of the item selected in the first listbox.

The user interface provides the user with means to remove items from the second listbox, so that the matching values are removed from the multivalued property of the item selected in the first listbox. Every time the user does so 1) these changes are persisted and the item in the first listbox is searched for again 2) the old instance is replaced by this new instance 3) the first listbox' selection is cleared.

The IndexOutBoundException is raised when the item removed from the second listbox is the only remaining one (and thus the multivalued property of the selected item in the first listbox gets empty) and the user triggers some other ui event afterwards.

The following piece of code (testable in the online zksandbox) can be used to reproduce the behaviour described above:

<window title="My First Window" border="normal">
    <hlayout>
        <label value="Please select the only item in L1" id="lbl" />
        <button id="btn" visible="false" label="Now press this in order to remove the selected L2 item" onClick='l2Removal(); event.getTarget().setLabel( "Now select the only item in L1 again" );' />
    </hlayout>
    <separator />
    <listbox id="l1" onSelect='l1Selection();' rows="2">
        <listhead>
            <listheader label="L1" />
        </listhead>
    </listbox>
    <listbox id="l2" rows="2" onSelect='l2Selection();'>
        <listhead>
            <listheader label="L2" />
        </listhead>
    </listbox>
    <zscript><![CDATA[
    import java.util.*;

    Map l1Item = new HashMap();

    List l2Items = new ArrayList();
    l2Items.add( "Just one l2 item" );
    l1Item.put( "l2Items", l2Items );

    List l1Items = new ArrayList();
    l1Items.add( l1Item );    
    l1.setModel( new ListModelList( l1Items ) );

    void l1Selection() {
        lbl.setValue( "Now select the only item in L2" );        
        Collection l2Items = l1.getModel().getSelection().iterator().next().get( "l2Items" );
        l2.setModel( l2Items == null || l2Items.isEmpty()? null : new ListModelList( l2Items ) );
    }

    void l2Selection() {
        lbl.setVisible( false );
        btn.setVisible( true );
    }

    void l2Removal() {
        Object l2SelectedItem = l2.getModel().getSelection().iterator().next();
        l2.getModel().remove( l2SelectedItem );
        l1.getModel().getSelection().iterator().next().get( "l2Items" ).remove( l2SelectedItem );

        Map l1Selection = l1.getModel().getSelection().iterator().next();
        int index = l1.getModel().indexOf( l1Selection );
        l1.getModel().set( index, l1Selection.clone() );
        l1.getModel().clearSelection();

        lbl.setVisible( true );
        lbl.setValue( "Now select the L1 item again" );
        btn.setVisible( false );
    }    
    ]]></zscript>
</window>

The reissuing of the first listbox instance modified via removal is mimicked by means of classical java cloning.

I think this is a bug, a very strange one that only gets revealed under very special circumstances, but any clue or help is welcome.

Kind regards

delete flag offensive retag edit

Comments

I just tested your code i did not get any exception at which tme you got the exception?

sjoshi ( 2013-07-29 11:49:44 +0800 )edit

I've tested it again right now and it yielded the exception. Just follow the instructions the test gives out (select item in L1, select item in L2, press the remove button, select the item in L1 again).

cvarona ( 2013-07-30 06:57:19 +0800 )edit

Here is your code added http://zkfiddle.org/sample/1k1l588/2-LiveListboxDataLoader-triggers-an-IndexOutOfBoundException i did not saw any exception.WHich version of Zk you are using

sjoshi ( 2013-07-30 07:05:08 +0800 )edit

I tried it on fiddle and of course I got the said exception; it does not really matter what zk version I'm using, because it's exactly the one in zk's sandbox and zk's fiddle. I'm using ff 22.0. It's very important to follow the instructions (otherwise it won't raise any exception, of course).

cvarona ( 2013-07-30 09:17:31 +0800 )edit

Ok I got the exception now previously i missed the select the item. Can you do one favor please convert into MVVM Design and post the code again

sjoshi ( 2013-07-30 09:21:20 +0800 )edit
Be the first one to answer this question!
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow
3 followers

RSS

Stats

Asked: 2013-07-29 11:36:05 +0800

Seen: 5 times

Last updated: Jul 29 '13

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More