B4J Question Can we trap an up arrow keypress, in a text box?

B4JExplorer

Active Member
Licensed User
Longtime User
Hi,

In a text box, I'd like to perform an action when the Up Arrow is pressed, while the text box has focus.

Is that possible?

I have the txt_input_TextChanged and txt_input_Action events defined, for trapping keystrokes or ENTER. But none of them are triggered, when the arrow keys are pressed.
 

AHilton

Active Member
Licensed User
Longtime User
Here's what I use to trap for TAB. I'm not sure what the Up Arrow KeyCode string is but you can find that out.


B4X:
'In the AppStart sub ...
    ' To trap the Down Arrow key to open the dropdown menu
    Dim Obj As Reflector
    Obj.Target = edtCompany
    Obj.AddEventHandler("edtCompany_KeyPressed", "javafx.scene.input.KeyEvent.ANY")



    Sub edtCompany_KeyPressed_Event (e As Event)
        Dim KE As Reflector
        KE.Target = e     ' e is a KeyEvent instance
    '    Dim KeyChar As String = KE.RunMethod("getCharacter")
        Dim KeyCode As String = KE.RunMethod("getCode")
    '    Dim KeyText As String = KE.RunMethod("getText")
        Dim EventType As String = KE.RunMethod("getEventType")
       
        If EventType = "KEY_PRESSED" Then
            If KeyCode = "TAB" Then
                               ' Do stuff here
                e.Consume
            End If
        Else
            e.Consume
        End If
    End Sub
 
Upvote 0

B4JExplorer

Active Member
Licensed User
Longtime User
Here's what I use to trap for TAB. I'm not sure what the Up Arrow KeyCode string is but you can find that out.


B4X:
'In the AppStart sub ...
    ' To trap the Down Arrow key to open the dropdown menu
    Dim Obj As Reflector
    Obj.Target = edtCompany
    Obj.AddEventHandler("edtCompany_KeyPressed", "javafx.scene.input.KeyEvent.ANY")



    Sub edtCompany_KeyPressed_Event (e As Event)
        Dim KE As Reflector
        KE.Target = e     ' e is a KeyEvent instance
    '    Dim KeyChar As String = KE.RunMethod("getCharacter")
        Dim KeyCode As String = KE.RunMethod("getCode")
    '    Dim KeyText As String = KE.RunMethod("getText")
        Dim EventType As String = KE.RunMethod("getEventType")
       
        If EventType = "KEY_PRESSED" Then
            If KeyCode = "TAB" Then
                               ' Do stuff here
                e.Consume
            End If
        Else
            e.Consume
        End If
    End Sub
AHilton,

Thanks, this is the kind of thing I need. But the subroutine is not responding to the arrow key. I placed a breakpoint on the

KE.Target = e

, but it never gets there.

Also, the Internal Designer doesn't have KeyPressed as an option. It has only the declaration of the TextField; Action; TextChanged; MouseClicked; and FocusChanged. So the event subroutine had to be defined manually,


B4X:
Sub txt_Prompt_KeyPressed_Event( e As Event )
	Private KE As Reflector
	KE.Target = e
	Private KeyChar As String = KE.RunMethod( "getCharacter" )
	Private KeyCode As String = KE.RunMethod( "getCode" )
	Private EventType As String = KE.RunMethod( "getEventType" )
        '...
        '...

End Sub
	
	
	
	
End Sub

Sub txt_Prompt_TextChanged (Old As String, New As String)
	Private s_Char As String
	s_Char = New
	If s_Char = "/" Then
		ta_Output.Text = ta_Output.Text & CRLF & "You pressed slash."
		txt_Prompt.Text = ""
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
A variation on what I use in apps

B4X:
Sub Process_Globals
 Private fx As JFX
 Private MainForm As Form
 Dim tf As TextField
 Dim keycode As JavaObject
End Sub
Sub AppStart (Form1 As Form, Args() As String)
 MainForm = Form1
 'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
 MainForm.Show
 tf.Initialize("tf1")
 keycode.InitializeStatic("javafx.scene.input.KeyCode") 
 MainForm.RootPane.AddNode(tf,10,10,100,20)
 setHandler(tf,"setOnKeyPressed","tf_KeyPress")
End Sub
Sub tf_KeyPress_Event(MethodName As String, Args() As Object)
 Log(Args(0))
 If asJO(Args(0)).RunMethod("getCode",Null) == keycode.GetField("UP") Then
 ' uppercase the text if 'up' is pressed
 tf.text = tf.Text.ToUpperCase
 asJO(tf).RunMethod("end",Null) ' make cursor stay at end of field
 Log("up arrow pressed")
 asJO(Args(0)).RunMethod("consume",Null)' eat the event to stop default behaviour
 End If
End Sub
Sub asJO(o As JavaObject) As JavaObject
 Return o
End Sub
Sub setHandler(ob As JavaObject,eventName As String,handlerName As String)
 ob.RunMethod(eventName, Array(ob.CreateEventFromUI("javafx.event.EventHandler",handlerName,False)))
End Sub
 
Upvote 0

B4JExplorer

Active Member
Licensed User
Longtime User
Disregard. You added an Event Handler, at the top.

Yep, that works like a gem. Thanks, chief.

By the way, the Keycode for the Up Arrow is "UP".


Regards,



AHilton,

Thanks, this is the kind of thing I need. But the subroutine is not responding to the arrow key. I placed a breakpoint on the

KE.Target = e

, but it never gets there.

Also, the Internal Designer doesn't have KeyPressed as an option. It has only the declaration of the TextField; Action; TextChanged; MouseClicked; and FocusChanged. So the event subroutine had to be defined manually,


B4X:
Sub txt_Prompt_KeyPressed_Event( e As Event )
	Private KE As Reflector
	KE.Target = e
	Private KeyChar As String = KE.RunMethod( "getCharacter" )
	Private KeyCode As String = KE.RunMethod( "getCode" )
	Private EventType As String = KE.RunMethod( "getEventType" )
        '...
        '...

End Sub
	
	
	
	
End Sub

Sub txt_Prompt_TextChanged (Old As String, New As String)
	Private s_Char As String
	s_Char = New
	If s_Char = "/" Then
		ta_Output.Text = ta_Output.Text & CRLF & "You pressed slash."
		txt_Prompt.Text = ""
 
Upvote 0

B4JExplorer

Active Member
Licensed User
Longtime User
A variation on what I use in apps

B4X:
Sub Process_Globals
 Private fx As JFX
 Private MainForm As Form
 Dim tf As TextField
 Dim keycode As JavaObject
End Sub
Sub AppStart (Form1 As Form, Args() As String)
 MainForm = Form1
 'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
 MainForm.Show
 tf.Initialize("tf1")
 keycode.InitializeStatic("javafx.scene.input.KeyCode") 
 MainForm.RootPane.AddNode(tf,10,10,100,20)
 setHandler(tf,"setOnKeyPressed","tf_KeyPress")
End Sub
Sub tf_KeyPress_Event(MethodName As String, Args() As Object)
 Log(Args(0))
 If asJO(Args(0)).RunMethod("getCode",Null) == keycode.GetField("UP") Then
 ' uppercase the text if 'up' is pressed
 tf.text = tf.Text.ToUpperCase
 asJO(tf).RunMethod("end",Null) ' make cursor stay at end of field
 Log("up arrow pressed")
 asJO(Args(0)).RunMethod("consume",Null)' eat the event to stop default behaviour
 End If
End Sub
Sub asJO(o As JavaObject) As JavaObject
 Return o
End Sub
Sub setHandler(ob As JavaObject,eventName As String,handlerName As String)
 ob.RunMethod(eventName, Array(ob.CreateEventFromUI("javafx.event.EventHandler",handlerName,False)))
End Sub
This is a more general routine, thanks Daestrum. I should be able to use this, as the project proceeds.
 
Upvote 0
Top