Bug? XCLV Index out of bounds exception when removing the last item (or is it me?)

walt61

Well-Known Member
Licensed User
Longtime User
See title; the attached demo project shows what happens, and this exception occurs (only when removing the last item, removing any others works fine):
Call B4XPages.GetManager.LogEvents = True to enable logging B4XPages events.
customlistview._getrawlistitem (java line: 449)
java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)
at java.base/java.util.Objects.checkIndex(Objects.java:385)
at java.base/java.util.ArrayList.get(ArrayList.java:427)
at anywheresoftware.b4a.objects.collections.List.Get(List.java:122)
at b4j.example.customlistview._getrawlistitem(customlistview.java:449)
at b4j.example.customlistview$ResumableSub_PanelClickHandler.resume(customlistview.java:775)
at b4j.example.customlistview._panelclickhandler(customlistview.java:751)
at b4j.example.customlistview._panel_mouseclicked(customlistview.java:742)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:117)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:104)
at anywheresoftware.b4j.objects.NodeWrapper$1.handle(NodeWrapper.java:109)
at anywheresoftware.b4j.objects.NodeWrapper$1.handle(NodeWrapper.java:1)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3602)
at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3906)
at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1878)
at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2623)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:557)
at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:943)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:1589)

The code is (I've only tested it with B4J):
Sub Class_Globals
Private Root As B4XView
Private xui As XUI
Private CustomListView1 As CustomListView
Private Label1 As Label ' Is from layout 'clvrow' and sits in a Pane
End Sub

Public Sub Initialize
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
Root = Root1
Root.LoadLayout("MainPage")
End Sub

Private Sub B4XPage_Appear

Dim i As Int
For i = 0 To 5
Wait For (CreateClvItem(i)) Complete(pnl As B4XView)
CustomListView1.Add(pnl, pnl.Tag)
Sleep(0)
Next

End Sub

Private Sub CreateClvItem(i As Int) As ResumableSub

Dim p As B4XView = xui.CreatePanel("")
p.SetLayoutAnimated(0, 0, 0, CustomListView1.AsView.Width, 50dip)
p.LoadLayout("clvrow")
Sleep(0)

p.Tag = i
Label1.Tag = i
Label1.Text = " Click here to delete item #" & i

Return p

End Sub

Private Sub Label1_MouseClicked (EventData As MouseEvent)

'!!!!!!!!!!!!!!!!!!!!!!!!
' The exception occurs when the label in the last item (#5) is clicked
'!!!!!!!!!!!!!!!!!!!!!!!!

Dim lbl As Label = Sender
DeleteFromCustomListView(lbl.Tag)
'EventData.Consume ' <---- If this is added, the exception does NOT occur
End Sub

Private Sub DeleteFromCustomListView(id As Int)

Dim i As Int

For i = (CustomListView1.Size - 1) To 0 Step -1
Dim p As B4XView = CustomListView1.GetPanel(i)
Dim tagId As Int = p.Tag
If tagId = id Then
CustomListView1.RemoveAt(i)
Return
End If
Next

End Sub

EDIT:
1. In B4A, the exception doesn't occur
2. If 'EventData.Consume' is added to the Label's MouseClicked event sub, the exception doesn't occur
 

Attachments

  • CLVdeleteBug.zip
    4.2 KB · Views: 37
Last edited:

josejad

Expert
Licensed User
Longtime User
Why don't you just do:

B4X:
Private Sub CustomListView1_ItemClick (Index As Int, Value As Object)
    CustomListView1.RemoveAt(Index)
End Sub
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
if 'EventData.Consume' is added to the Label's MouseClicked event sub, the exception doesn't occur
This is actually the explanation for this issue.
If you don't call EventData.Consume then the event propagates to the underlying panel and when the CLV event logic fires it fails because the item was already removed. I will add a check for this case, though it is a mistake not to consume the event.
 
Top