B4J Question [B4X][XUI] RequestFocus

udg

Expert
Licensed User
Hi all,

I'm working on custom view which has an EditText/TextField at its core.
I'd like to expose a SetFocus function so to give the programmer control on this respect.
When control receives focus it should select and highlight all the text it holds.
So far the best way I found is the following (simplified code):
B4X:
Private tf As B4XView ' defined in Class_Globals
'tf initialized in DesignerCreateView by means of a locally dimmed EditText or TextFiled var


'Changes view's focus and eventually calls corresponding event in calling module (if set).
'If current text doesn't pass the matching-pattern test, focus is forced to stay unless LetFocusOut permits it anyway
Private Sub tf1_FocusChanged(HasFocus As Boolean)
   Dim okmsg As Boolean = True
   If Not(HasFocus) Then
       If Not(LetFocusOut) Then
           If Not(Regex.IsMatch(mpattern, tf.Text)) Then
               tf.RequestFocus   
               okmsg = False
           End If
       End If
   Else
       tf.RequestFocus  'this is the "second" call to RF, needed to have the selectall effect
   End If
   If okmsg And SubExists(mCallBack, mEventName&"_FocusChanged") Then CallSub2(mCallBack, mEventName&"_FocusChanged", HasFocus)
End Sub

Public Sub setFocus
   tf1_FocusChanged(True)
End Sub

The above causes a double RequestFocus (intentional in order to obtain the "selectAll" effect).
I tried with JO and several other ways to no avail.

Can you suggest a different approach, but yet valid in a XUI/B4X context? TIA
 

Erel

Administrator
Staff member
Licensed User
Trying to force the focus to be kept on a specific field will result in a bad user experience. It is better to mark the field with a red line or something similar.

Don't be afraid to use conditional compilation to solve it. Something like:
B4X:
tf.RequestFocus
Sleep(50)
#if B4A
Dim et As EditText = tf
et.SelectAll
#else if B4J Or B4I
Dim ttf As TextField = tf
ttf.SelectAll
#end if
 
Upvote 0

udg

Expert
Licensed User
Thank you.
Plan B is exactly that (red border + move away) and a property is used to enable/disable that kind of behaviour.

If I use your exact code in my SetFocus sub, commenting out the extra tf.RequestFocus in tf1_FocusChanged, it leads to an unexpected event message:
Unexpected event (missing RaiseSynchronousEvents): tf1_focuschanged

The same I fought against several times while looking for a good solution. BTW, code runs ok after that message, but since I can't say whether is safe to ignore it or not I would like to get rid of it.
 
Upvote 0

udg

Expert
Licensed User
Thanks a lot.
It seems to happen (in debug mode) only on the first call of SetFocus. Once the class will be complete I'll make sure to test it both in B4J/B4A and debug/release.
BTW, it's a porting of your excellent RegexTextField..
 
Upvote 0
Top