B4J Question How To Constrain Tab/Shft+Tab Navigation Inside of Form Inside of xCustomListView

cklester

Well-Known Member
Licensed User
I have a form inside an xCustomListView. I want to constrain the tab navigation to the form until the user presses Enter.

This is easy enough to do from the "First Name" and "Zip Code" fields with the focus change event with a Tab keypress. But it will require knowing if the user hit Shift+Tab to process any other navigation. This is where I'm stuck.

Here's how I figure it can go:

1. Capture the Tab and Shift+Tab keys. If it's any other field than "First Name" or "Zip Code," let it fall thru. If it is leaving "First Name" with "Tab," let it fall thru. If it is leaving "First Name" with Shift+Tab, intercept and do txt_ZipCode.RequestFocus. If it is leaving "Zip Code" with "Tab," intercept and do txt_FirstName.RequestFocus. If it is leaving "Zip Code" with Shift+Tab, let it fall thru.

-or-

2. Disable all other controls in the xCustomListView until the user is done entering the data.

I've searched the forum and couldn't find a solution, so...

I suspect the first idea above is the better option, but I'm not sure how to capture the Shift+Tab keypress from a TextField.

What's the best way to go about handling this?


1604891244362.png
 

cklester

Well-Known Member
Licensed User
Ah. OK. I had seen those resources, but I was hoping there was a simpler way. Although, now that I've delved into them, they're not complicated, just unfamiliar. I'm sure I'll become more familiar with the Reflection library and Java over time. :)

So, I almost posted the following question: "Can you show me how to know if the Shift key (or any other modifier key)?" But I decided to start digging. I'm going to be here a while, so I might as well do some "deep learning."

So, first, I output e to the Log(). It looks like "code" contains "TAB, shiftDown," but the output doesn't show the "shiftDown." I realized shiftDown was a property, not a value of code! So, I was able to grab that and the target, and came up with this:

B4X:
Sub KeyPressed_Filter(e As Event)
    Dim jo As JavaObject = e
    Dim eventtype As String = jo.RunMethodJO("getEventType",Null).RunMethod("getName",Null)
    If eventtype = "KEY_PRESSED" Then
        Dim target As B4XView = jo.RunMethod("getTarget",Null)
        Dim keycode As String = jo.RunMethod("getCode", Null)
        Dim shiftDown As Boolean = jo.RunMethod("isShiftDown",Null)
        If target = txt_FirstName Then
            If keycode = "TAB" And shiftDown Then
                txt_ZipCode.RequestFocus
                e.Consume
            End If
        Else If target = txt_ZipCode Then
            If keycode = "TAB" And Not (shiftDown) Then
                txt_FirstName.RequestFocus
                e.Consume
            End If
        End If
    End If
End Sub

Is my use of e.Consume correct here? I assume it means, "We've handled this, no need for the OS to process it." Seems to be right!

This is doing exactly what I want. The user is constrained to the form until an exit key is received (which I haven't programmed yet). I'll have to intercept the Enter key eventually, to solidify the form input, and maybe Esc to cancel it...

Is there a better way to handle this? Otherwise, I think I'm good to go! WOo hoo!
 
Upvote 0
Top