B4J Question How to trigger click event?

Chris Guanzon

Active Member
Licensed User
Longtime User
Hello,

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.

Thank you so much!
 

Attachments

  • Sample.zip
    3.4 KB · Views: 41

Cableguy

Expert
Licensed User
Longtime User
I think yor issue is related to the way you are attaching the Clicked event...
You may try to explore the following:


which seems to be much more suited to what you want.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
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
 

Attachments

  • flex-box.zip
    3.4 KB · Views: 36
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
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!
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
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:
that is not the view he is trying to get the click event to trigger!
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
B4X:
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.
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
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...
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
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.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User

(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?

Really hard.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
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.
 
Last edited:
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
What @Chris Guanzon is trying to do is precisely a custom view, a container to which views can be added at runtime.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
What @Chris Guanzon is trying to do is precisely a custom view.
True, but it's a Custom View for the flexbox, and the buttons passed are it's children. As would be with a Pane or similar. An edge case.

For your scenario, it would probably be easier to do something similar.
 
Upvote 0

PaulMeuris

Well-Known Member
Licensed User
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...
B4X:
Log("view width " & fbv.GetBase.GetView(btn.Tag).Width)
 
Last edited:
Upvote 0

stevel05

Expert
Licensed User
Longtime User
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.
 
Last edited:
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…