B4J Question Problem updating items on expansion in an Expandable List.

Xyloidhead

Member
Licensed User
Hi
Under B4J, version 6.01 with xCustomListView v1.20, I'm trying to modify an
'Expandable List' example and I'm getting a crash I don't understand.
I expect it is something I'm doing wrong.
What I want to do is to change the test on the buttons in the expanded panel when
the panel is opened. So I have altered the Expand item to:


B4X:
Sub ExpandItem (index As Int)
    clv1.ResizeItem(index, ExpandedHeight)
    Dim p As B4XView = clv1.GetPanel(index)
    ' clv1.GetPanel(index).Tag = True
    p.Tag = True
    Log("list item: " & (FindExapnded + 1))
    For i = 0 To p.NumberOfViews -1
        Dim ele As B4XView = p.GetView(i)
        ele.Text = "Blah"
    Next
    AnimatedArrow(index, 0, 180)
End Sub

Now the editor allows me to do this without complaint, Text is a method on B4XView
as far as it is concerned. But when I run it as soon as I expand an item it crashes
with the error below on the line "ele.Text = "Blah".

B4X:
Waiting for debugger to connect...
Program started.
list item: 2
Error occurred on line: 64 (Main)
java.lang.RuntimeException: Type does not match (class anywheresoftware.b4j.objects.PaneWrapper$ConcretePaneWrapper$NonResizePane)
    at anywheresoftware.b4j.objects.B4XViewWrapper.typeDoesNotMatch(B4XViewWrapper.java:482)
    at anywheresoftware.b4j.objects.B4XViewWrapper.setText(B4XViewWrapper.java:267)
    at b4j.example.main._expanditem(main.java:242)
    at b4j.example.main._clv1_itemclick(main.java:182)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:613)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:231)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:159)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:93)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:482)
    at anywheresoftware.b4a.keywords.Common.CallSubNew3(Common.java:445)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:613)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:231)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:159)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:93)
    at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:61)
    at b4j.example.customlistview$ResumableSub_PanelClickHandler.resume(customlistview.java:1281)
    at b4j.example.customlistview._panelclickhandler(customlistview.java:1265)
    at b4j.example.customlistview._panel_mouseclicked(customlistview.java:1258)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:613)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:231)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:159)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:93)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:77)
    at anywheresoftware.b4j.objects.NodeWrapper$1.handle(NodeWrapper.java:91)
    at anywheresoftware.b4j.objects.NodeWrapper$1.handle(NodeWrapper.java:1)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3470)
    at javafx.scene.Scene$ClickGenerator.access$8100(Scene.java:3398)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3766)
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$353(GlassViewEventHandler.java:432)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:937)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
    at java.lang.Thread.run(Thread.java:748)
Picked up _JAVA_OPTIONS: -Xms256m -Xmx512m

I've tried a number of things, such as casting the view to a Button, and while I
can get different crashes I cannot make it work. I have found the lazy loading
tutorial that might achieve what I want but I'd still like to know why my approach
doesn't work as it seems it should.

Appreciate any help explaining what I have done wrong.

I have attached the my code in case it is helpful.
 

Attachments

  • B4J_expandable_list.zip
    100.7 KB · Views: 324

Eme Fibonacci

Well-Known Member
Licensed User
Longtime User
On item.bjl we have two panels.

1) pnlTitle (view 0)
2) pnlExpanded. (view 1)

With this code snippet you will able to understand how you can get nodes on panels.

B4X:
Sub ExpandItem (index As Int)
    clv1.ResizeItem(index, ExpandedHeight)
    Dim p As B4XView = clv1.GetPanel(index)

    p.Tag = True
         
    Dim p2 As Pane=p.GetView(1)
                 
    For Each n As Node In p2.GetAllViewsRecursive
        Dim count As Int            
     
        If n Is Button Then
            count=count+1
            Dim b As Button=n
            If count=1 Then b.Text="First button"
            If count=2 Then b.Text="Second button"
         
        End If
             
    Next    
     
    AnimatedArrow(index, 0, 180)
 
End Sub
 
Last edited:
Upvote 0

Xyloidhead

Member
Licensed User
Thanks Eme for your response appreciate your help.

Your solution worked but has a minor bug. You have count defined in the wrong place. It ends up being 1 every time through the loop.

B4X:
Sub ExpandItem (index As Int)
    clv1.ResizeItem(index, ExpandedHeight)
    Dim p As B4XView = clv1.GetPanel(index)

    p.Tag = True
        
    Dim p2 As Pane=p.GetView(1)
    Dim count As Int = 0
                
    For Each n As Node In p2.GetAllViewsRecursive
        If n Is Button Then
            count=count+1
            Dim b As Button=n
            If count=1 Then b.Text="First button"
            If count=2 Then b.Text="Second button"
        
        End If
            
    Next
    AnimatedArrow(index, 0, 180)
End Sub

But I'm disappointed that the name of the view doesn't appear to be accessible. Relying on indexes is a way to create more pain for myself if I ever need to change the layout if the Views on the panel.

My work around is to use the Tag field in the designer, less than ideal as it is an extra field you must remember to set. But once set means the items can be re-ordered if user feedback indicates things would be better in a different order. My final code became.

B4X:
Sub ExpandItem (index As Int)
    clv1.ResizeItem(index, ExpandedHeight)
    Dim p As B4XView = clv1.GetPanel(index)

    p.Tag = True
        
    Dim p2 As Pane=p.GetView(1)
                
    For Each n As Node In p2.GetAllViewsRecursive
        If n Is Button Then
            Dim b As Button=n
            If b.Tag = "B1" Then b.Text="First button"
            If b.Tag = "B2" Then b.Text="Second button"

        End If
            
    Next
    AnimatedArrow(index, 0, 180)
End Sub
 
Upvote 0
Top