B4J Question [ABMaterial] Checking the state of an ABMCheckbox is throwing an error

John Naylor

Active Member
Licensed User
Longtime User
B4J 8.1, ABMaterial 4.51

Background - I have a modal screen with with a few controls and an ABMContainer which contains an ABMTable.

The table is populated such that each row has a text field and an ABMCheckbox.

So far so good, the table gets populated with relevant rows from a mySQL query and the checkbox state gets set and displays correctly.

When I come to save any potential changes to the table (checkbox.state has changed) I get a reference to the container and from there I get the ABMTable component. I loop through each entry on the table, get the text part which works fine and then get the checkbox component by name.

Hovering my cursor over the checkbox object I can see that (in my test case) it's set to true however when I try to set a boolean variable to the state it fails with a null pointer exception.

The code looks like this...

B4X:
    Dim mName As String
    Dim mTicked As Boolean
    Dim mNameID As Int
    Dim Matched As Int
    
    Dim cbCheck As ABMCheckbox
    
    'Now were going to scroll through each row in the table, find out what sort of membership it's referencing and whether it's ticked or not
    
    tblMembershipList.PrepareTableForRetrieval    'ABM Needed
    
    For x=0 To numTypes-1
        mName = tblMembershipList.GetString (x,0)   '<<<<< This works fine'
        
        cbCheck=tblMembershipList.GetComponent(x,"cbSelect") '<<< This *appears to work fine (see pictures below)

        mTicked=cbCheck.State   '<<<<This fails

        ...
        ...

Here's the contents of the checkbox before I read it from the table. As you can see the state is showing as false.


pre.png




A single F8 press later and the state changes to True (as expected I purposely made sure the checkbox is ticked) so I assume I have correctly referenced the relevant checkbox on the table (no errors so far).

post.png


As soon as I execute the next line ( mTicked=cbCheck.State) I get a NullPointerException as shown.

err.png



Any ideas on what I am doing wrong here? As always, thanks for reading.
 

John Naylor

Active Member
Licensed User
Longtime User
Can you expand FutureChecked? When you ask the .State, it uses this to get the actual value from the Browser. Maybe something is null there. (I see that GotLastState is false, so it has to use this)

Ahhh OK this looks suspicious.... Have I missed a step?

fc.png
 
Upvote 0

John Naylor

Active Member
Licensed User
Longtime User
Additionally - I can add cbchecked.refresh and cbchecked.text="xxx" etc between the GetComponent line and the .CheckState line and they work fine.

I've also tried unticking the checkbox then ticking it again which makes no difference. Neither does unticking only.
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
I can not reproduce this. Which version of ABM are you using? I tried it with ABM 4.30 and ABM 4.51.

In the demo app I did this on the ABMTable page:
In ConnectPage()
B4X:
...
' create a table scrollable
    Dim tbl3 As ABMTable
    tbl3.InitializeScrollable(page, "tbl3", False, False, True, Array As Int(300, 200,200,150), "tbl1theme")
    
    tbl3.SetHeaders(Array As String("Card", "First Name", "Last Name", "Sales Profit"))
    tbl3.SetHeaderThemes(Array As String("headerfooter", "headerfooter", "headerfooter", "headerfooterright"))
    
    Dim fName, lName As String
    
    ' add some random values
    For i = 0 To 9
        Dim r As List
        Dim rCellThemes As List
        r.Initialize
        rCellThemes.Initialize
        fName = FirstNames.get(Rnd(0,9))
        lName = LastNames.get(Rnd(0,9))

        ' instead of the card I added a checkbox
        Dim chk As ABMCheckbox
        chk.Initialize(page, "chk", "Test", True, "")
        r.Add(chk)
        rCellThemes.Add("aligntop")
        
        r.Add(fName)
        rCellThemes.Add("aligntop")
        r.Add(lName)
        rCellThemes.Add("aligntop")        
        r.Add(BuildOtherTable("innertable")) ' <--- note we do not give every innertable a unique id.  
        rCellThemes.Add("aligntop")
        tbl3.AddRow("uid" & i, r)
        tbl3.SetRowThemes(rCellThemes) ' make sure you have as many items in rCellThemes as in r!
    Next
    
    tbl3.SetFooter("This is a footer that appears on the bottom of the table.", 12,"headerfooter")
    
    ' scrollable, so we need to set a fixed height IMPORTANT!
    page.Cell(7,1).SetFixedHeight(500, False)
    page.Cell(7,1).AddComponent(tbl3)
    
    Dim btn1 As ABMButton
    btn1.InitializeFlat(page, "btn1", "", "", "Get All", "")
    page.Cell(8,1).AddComponent(btn1)
...

To retrieve the data:
B4X:
Sub btn1_Clicked(Target As String)
    Dim tbl As ABMTable = page.Cell(7,1).Component("tbl3")
    Dim state As Boolean
    
    tbl.PrepareTableForRetrieval
    
    Dim chk As ABMCheckbox
    For i = 0 To 9
        chk = tbl.GetComponent(i,"chk")
        state = chk.State
        Log(state)
    Next
End Sub

Worked fine, in the logs:
B4X:
Waiting for value (101 ms)
true
Waiting for value (100 ms)
false
Waiting for value (101 ms)
true
Waiting for value (101 ms)
true
Waiting for value (101 ms)
true
Waiting for value (100 ms)
true
Waiting for value (101 ms)
true
Waiting for value (101 ms)
true
Waiting for value (101 ms)
true
Waiting for value (100 ms)
true

I will need to see more code to find what you did different (you can mail me the full code of that page at [email protected], as attachment please)

Alwaysbusy
 
Upvote 0

John Naylor

Active Member
Licensed User
Longtime User
Update - I've fixed it (sort of).

I've taken the table out of the container and put it straight into a cell on the modal sheet and everything works perfectly now. I have no idea why I decided to put it in a container in the first place as it isn't needed at all for what I'm doing but I must have thought it was a good idea at the time :-/

[Edit] Of course this still could mean there's a bug when a checkbox is on a table that is in a container
 
Last edited:
Upvote 0
Top