Short question is how do I get multiple buttons to go to the same sub routine?
This should have a simple solution but I can't figure it out for B4J. I have this working in Android but the same logic isn't working in B4J. I have 30 buttons that I want to change the Button.Text dynamically for, but I want to do the text change in one sub routine via the array. I am saving the buttons in an array to do this. I am not creating the buttons with code. I'm using Scene Builder.
If I give each button its own unique Java FX CSS Id (Node ID?) everything works fine but I have to create a separate sub routine for each button. If I give them all the same Id it doesn't work. How can I give each button its own Id but have them all go to the same sub routine when it is clicked?
Editing to add more info:
I see areas in the Scene Builder called "On Action" and "On Mouse Click" under the fx:id but can't find any doc to explain these. Will these give me what I want?
I see areas in the Scene Builder called "On Action" and "On Mouse Click" under the fx:id but can't find any doc to explain these. Will these give me what I want?
The difference between B4A is that there is only one ID field. In B4A we have Name and EventName. If you can then you should give all these buttons the same ID.
Dave, thanks for your reply but that is exactly what I am doing and that part produces the results as it should but that is not the problem. See my reply to Erel.
Erel,
Thanks for the reply. The problem is that giving all the buttons the same Id somehow messes up the way the array works. If I give all the buttons the same Id then all the names in the array have to be the same or else I get the "Object should first be initialized..." error. I have to be missing something because this is a common practice, isn't it? Where you have multiple buttons but want them to go to the same sub routine?
So, if I do this, after giving each button a unique id in Scene Builder:
B4X:
Buttons = Array As Button(Button1, Button2, Button3, Button4, Button5, _
Button6, Button7, Button8, Button9, Button10)
For i = 0 To Gx -1
Buttons(i).text = GrabName(i).Substring2(11,13) & "/" & GrabName(i).Substring2(13,15) & "/" &
GrabName(i).Substring2(15,17) & " " & GrabName(i).Substring2(17,24) 'parse the file date
Buttons(i).Tag = GrabName(i) 'save the file name
Next
then all the buttons get the text changed correctly.
But this needs a unique sub routine for each button:
B4X:
Sub Button1_MouseClicked (EventData As MouseEvent)
b = Sender 'Cast the Object to Button
MyFile = b.tag 'full file name
End Sub
Sub Button2_MouseClicked (EventData As MouseEvent)
b = Sender 'Cast the Object to Button
MyFile = b.tag 'full file name
End Sub
And I get the correct results.
but If I do this after giving all the buttons the same id of "Button" in Scene Builder:
Only one button gets the text changed (and strangely it's the 7th button of the 10 buttons).
If I change the id in Scene builder to "Button" but leave the names in the array as "Button1, Button2..." then I get a "Object should first be initialized..." error.
While waiting for a solution to the above issue I decided on the following work-around. It works but it is not neat. At least it will save a lot of potential redundant code.
B4X:
Sub Button1_MouseClicked (EventData As MouseEvent)
' ...1,000 lines of code go here....
End Sub
Sub Button2_MouseClicked (EventData As MouseEvent)
Button1_MouseClicked (EventData) 'This goes back to Button1's logic rather than duplicate it here.
End Sub
Sub Button3_MouseClicked (EventData As MouseEvent)
Button1_MouseClicked (EventData) 'This goes back to Button1's logic rather than duplicate it here.
End Sub
This problem is less about determining which button is pressed and more about how to assign data to the relevant tag in the first place.
There are going to be many potential solutions to this problem as time goes on, but my preference so far is to add tags to the StyleClasses as they won't get in the way of anything else.
I have previously copied them to tags in the objects on starting the app. In this case you can't do that as you want to use the tags for something else. So I've left them in the StyleClass field.
Then, in the Scene Builder, create a group around the buttons, (Select the buttons then in Arrange menu, select Wrap in, then Group a new Node is created with a css id of Group) you can change the css id of the group to something meaningful and you can then generate the Member for the group in the IDE.
Once you know that Group in JavaFX has a method called getChildren, the rest is straight forward:
B4X:
Sub Process_Globals
Private fx As JFX
Private MainForm As Form
Private Btn As Button
Private BtnGroup As Node
End Sub
Sub AppStart (Form1 As Form, Args() As String)
MainForm = Form1
MainForm.RootPane.LoadLayout("1") 'Load the layout file.
AssignTags
MainForm.Show
End Sub
Sub Btn_Action
Dim B As Button = Sender
Log(B.Tag)
End Sub
Sub AssignTags
Dim Children As List
Dim JO As JavaObject = BtnGroup
Children = JO.RunMethod("getChildren",Null)
For Each Child As Button In Children
If Child.StyleClasses.IndexOf("Tag:Btn1") <> -1 Then Child.Tag= "This is Btn1"' or whatever else
If Child.StyleClasses.IndexOf("Tag:Btn2") <> -1 Then Child.Tag= "This is Btn2"
If Child.StyleClasses.IndexOf("Tag:Btn3") <> -1 Then Child.Tag= "This is Btn3"
If Child.StyleClasses.IndexOf("Tag:Btn4") <> -1 Then Child.Tag= "This is Btn4"
If Child.StyleClasses.IndexOf("Tag:Btn5") <> -1 Then Child.Tag= "This is Btn5"
Next
End Sub