B4J Question Item ID as opposed to Sub ID

tsteward

Well-Known Member
Licensed User
Longtime User
Thought I'd start a new thread rather than hijack the calculator one.
I understand how to do this in B4A but not in B4J

I have used fx scene builder to create my layout with 12 buttons.
How do I:
a: Reference each button individually to set text dynamically throughout my app.
b: Send all the button clicks to one sub.
 

tsteward

Well-Known Member
Licensed User
Longtime User
a: Build a list that holds your buttons.

B4X:
For Each v As View In MainForm.RootPane.GetAllViewsRecursibe
If v.Id = "your id" Then ListOfButtons.Add(b)
Next

Dim b As Button = ListOfButtons.Get(5)
b.Text = "aaa"

b: This will happen automatically. You can use Sender to get the button that raised the event.
I have knocked up a test app.
It seems to get two references to each button but only the first reference is valid.
Not sure if my method is correct?
 

Attachments

  • test.zip
    1.1 KB · Views: 273
Upvote 0

tsteward

Well-Known Member
Licensed User
Longtime User
Ok in my app when I create a list of the buttons using the method above it creates 2 entries per button but using the same method to create a list of imageviews it creates one entry as expected. Maybe a bug?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
If you do:
B4X:
For Each v As Node In MainForm.RootPane.GetAllViewsRecursive
    Log(v)
Next

You will see that there are more nodes than you'd expect, probably because the search is recursive, as MainForm.RootPane.NumberOfNodes returns 4. Maybe a non-recursive getChildren method would be useful, although it's probably quite straightforward with JavaObject (I haven't looked).

Some are composites that make up one view, it looks like a button also has ButtonSkin and LabeledText Nodes and ButtonSkin shares the button Id.

If you do:

B4X:
For Each v As Node In MainForm.RootPane.GetAllViewsRecursive
     If GetType(v) = "Button" Then ListOfButtons.Add(v)
Next

instead, you'll get your desired result. You can additionally test for ID="Btn" if you have different ID's for different uses.
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
stevel is correct. Each button holds another node (ButtonSkin). The best solution is:
B4X:
Sub AppStart (Form1 As Form, Args() As String)
   MainForm = Form1
   MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
   MainForm.Show
   ListOfButtons.Initialize
   For Each v As Node In MainForm.RootPane.GetAllViewsRecursive
     If v.Id = "Btn" AND v Is Button Then
       ListOfButtons.Add(v)
     End If
   Next
   Dim i As Int = 0
   For Each b As Button In ListOfButtons
     b.Text = "Num " & i
     i = i + 1
   Next
End Sub
 
Upvote 0
Top