Could anyone please help me figure out how to make this click event work? It's not triggering when I click it, and I’m not sure what I’m doing wrong. What I’m trying to achieve is to detect which button or view was clicked.
If your aim is just to get the click event in the Main module and do not need to know in the Justflexbox class that it has been clicked, you do not need to capture the click event in the JustFlexbox Class and pass it back to the main module.
As you are creating the button in the Main module, it will automatically get the default events which will be called in the module in which the views are created, so you just need to add the sub in the Main module:
B4X:
Private Sub btn_Click
Dim btn As B4XView = Sender
Log(btn.Text)
End Sub
he is creating an array of B4XViews (passed from the FlexBox initialize method) in the class, so the click method is triggered in that class.
Since he is creating them dynamically, he need to bound the click events by code.
Sender is only useful if the views are created using the Visual Designer, in which the views event name can be set!
As you are creating the button in the Main module, it will automatically get the default events which will be called in the module in which the views are created, so you just need to add the sub in the Main module:
Public Sub AddFlexChild(v As B4XView, width As Int, height As Int)
nView = v
mBase.AddView(nView, 0, 0, width, height)
Children.Add(nView)
' Attach click event if callback exists
If xui.SubExists(mCallBack, mEventName & "_Click", 1) Then
nView.Tag = "justflexbox_child"
#If B4J
Dim jo As JavaObject = nView
jo.RunMethod("setOnMouseClicked", Array(jo.CreateEvent("javafx.event.EventHandler", "FlexChild_Clicked", True)))
#End If
End If
LayoutChildren
End Sub
v As B4xview is the button created in Main and passed to the JustFlexbox Class, the event is already attached at this point, the method only creates an array of the views. Check my example project.
Public Sub AddFlexChild(v As B4XView, width As Int, height As Int)
nView = v
mBase.AddView(nView, 0, 0, width, height)
Children.Add(nView)
' Attach click event if callback exists
If xui.SubExists(mCallBack, mEventName & "_Click", 1) Then
nView.Tag = "justflexbox_child"
#If B4J
Dim jo As JavaObject = nView
jo.RunMethod("setOnMouseClicked", Array(jo.CreateEvent("javafx.event.EventHandler", "FlexChild_Clicked", True)))
#End If
End If
LayoutChildren
End Sub
v As B4xview is the button created in Main and passed to the JustFlexbox Class, the event is already attached at this point, the method only creates an array of the views. Check my example project.
You are Right, as usual....
I didn't see this because i was concentrated in the Flex class, and it is ilogic for me to the buttons be created outside the class... but it's the OP choice...
For completeness, if you did want to know that the button had been clicked in a helper class, you can use an event filter as opposed to replacing the click event, that way (as long as you don't consume the event), both events will be triggered. The filtered event first.
Public Sub AddFlexChild(v As B4XView, width As Int, height As Int)
nView = v
mBase.AddView(nView, 0, 0, width, height)
Children.Add(nView)
' Attach click event if callback exists
If xui.SubExists(mCallBack, mEventName & "_Click", 1) Then
nView.Tag = "justflexbox_child"
#If B4J
Dim jo As JavaObject = nView
jo.RunMethod("setOnMouseClicked", Array(jo.CreateEvent("javafx.event.EventHandler", "FlexChild_Clicked", True)))
#End If
End If
LayoutChildren
End Sub
v As B4xview is the button created in Main and passed to the JustFlexbox Class, the event is already attached at this point, the method only creates an array of the views. Check my example project.
(I'm "half asleep" and have a nasty headache, so I might be about to write nonsense).
That's interesting. That's a great solution (well done Steve), but thinking about it... it's limited to the button click event and certainly isn't cross-platform. What if you wanted to create a B4X Custom View that's a container for different types of Views, say native ones, and trigger different events?
Custom views are different, the views used need to be created within the custom view itself and events on the contained views need to be handled in the Custom View class and passed to the parent module as required. Otherwise it wouldn't be a custom view but a container.
Custom views are different, the views used need to be created within the custom view itself and events on the contained views need to be handled in the Custom View class and passed to the parent module as required. Otherwise it wouldn't be a custom view but a container.
And how about this...
Use the button tag as an index...
The B4J subroutine is called: btn_MouseClicked...
B4X:
Sub Process_Globals
Private fx As JFX
Private MainForm As Form
Private xui As XUI
Private Button1 As B4XView
Private Pane1 As Pane
Private fbv As JustFlexbox
Private index As Int = 0
End Sub
Sub AppStart (Form1 As Form, Args() As String)
MainForm = Form1
MainForm.RootPane.LoadLayout("Layout1")
MainForm.Show
' Initialize JustFlexbox with Pane1 as base
fbv.Initialize(Pane1, "fbv")
fbv.FlexDirection = "row"
fbv.Wrap = True
fbv.GapX = 10dip
fbv.GapY = 10dip
fbv.JustifyContent = "center"
fbv.AlignItems = "center"
' Add buttons dynamically
For i = 1 To 12
Dim btn As Button
btn.Initialize("btn")
btn.Text = "Btn " & i
btn.Tag = index
Dim w As Int = 80 + Rnd(0, 40)
Dim h As Int = 50
fbv.AddFlexChild(btn, w, h)
index = index + 1
Next
For i = 1 To 8
Dim btn As Button
btn.Initialize("btn")
btn.Text = "Btn " & i
btn.Tag = index
fbv.AddFlexChild(btn, 80dip, 50dip)
index = index + 1
Next
End Sub
Private Sub fbv_Click(view As B4XView)
Log("Clicked: " & view.Text)
End Sub
Private Sub btn_MouseClicked(EventData As MouseEvent)
Dim btn As Button = Sender
Log("mouse clicked " & btn.Text & " tag = " & btn.tag)
Log("view text " & fbv.GetBase.GetView(btn.Tag).Text)
End Sub
Or if you are interested in the width of the button...
Yes, all of the default events are available. Although in this case, it would be better to add the index in the JustFlexbox LayoutChildren method. If the views are later sorted, filtered or added / deleted, the index will be maintained correctly.