B4J Question [Solved]How to get a selected substring from a B4XFloatTextField?

BlueVision

Well-Known Member
Licensed User
Longtime User
Sometimes it gets tricky...
Imagine you have written some values in the form of a list in a B4XFTF. Double-clicking on an element in this B4XFTF selects it. So far, so good. Is there a way to copy the selected string to the clipboard at the same time?
 
Solution
This would only be possible if the DoubleClick or at least Click event existed
Not strictly true. But B4j only.

As the mouse clicked event is not already used and the input field(s) are exposed, it is possible to add an event handler to capture the click.

The TextField is a JavaFX TextField for a single line field, and a TextArea for a multi line field. Fortunately they both inherit the required methods from javafx.scene.control.TextInputControl so one set of code will do for both.

After layout is loaded:
    Dim JO As JavaObject = B4XFloatTextField1.TextField
    Dim O As Object = JO.CreateEventFromUI("javafx.event.EventHandler","B4xTFClick",Null)
    JO.RunMethod("setOnMouseClicked",Array(O))

Capture Sub:
Private Sub B4xTFCLick_Event (MethodName As...

stevel05

Expert
Licensed User
Longtime User
This would only be possible if the DoubleClick or at least Click event existed
Not strictly true. But B4j only.

As the mouse clicked event is not already used and the input field(s) are exposed, it is possible to add an event handler to capture the click.

The TextField is a JavaFX TextField for a single line field, and a TextArea for a multi line field. Fortunately they both inherit the required methods from javafx.scene.control.TextInputControl so one set of code will do for both.

After layout is loaded:
    Dim JO As JavaObject = B4XFloatTextField1.TextField
    Dim O As Object = JO.CreateEventFromUI("javafx.event.EventHandler","B4xTFClick",Null)
    JO.RunMethod("setOnMouseClicked",Array(O))

Capture Sub:
Private Sub B4xTFCLick_Event (MethodName As String, Args() As Object)
    Dim TF As JavaObject = Sender
    Dim Evt As MouseEvent = Args(0)
    If Evt.PrimaryButtonPressed And Evt.ClickCount = 2 Then
        fx.Clipboard.SetString(TF.RunMethod("getSelectedText",Null))
    End If
End Sub

Will copy the text when it is double clicked.

Although there is a context menu on the field(s) and Ctrl+C will also copy the text.

Be aware that selecting the text alone will not copy it, you would have to add a listener to the SelectionProperty to achieve that.
 
Last edited:
Upvote 0
Solution

LucaMs

Expert
Licensed User
Longtime User
Not strictly true. But B4j only.

As the mouse clicked event is not already used and the input field(s) are exposed, it is possible to add an event handler to capture the click.

The TextField is a JavaFX TextField for a single line field, and a TextArea for a multi line field. Fortunately they both inherit the required methods from javafx.scene.control.TextInputControl so one set of code will do for both.

After layout is loaded:
    Dim JO As JavaObject = B4XFloatTextField1.TextField
    Dim O As Object = JO.CreateEventFromUI("javafx.event.EventHandler","B4xTFClick",Null)
    JO.RunMethod("setOnMouseClicked",Array(O))

Capture Sub:
Private Sub B4xTFCLick_Event (MethodName As String, Args() As Object)
    Dim TF As JavaObject = Sender
    Dim Evt As MouseEvent = Args(0)
    If Evt.PrimaryButtonPressed And Evt.ClickCount = 2 Then
        fx.Clipboard.SetString(TF.RunMethod("getSelectedText",Null))
    End If
End Sub

Will copy the text when it is double clicked.

Although there is a context menu on the field(s) and Ctrl+C will also copy the text.

Be aware that selecting the text alone will not copy it, you would have to add a listener to the SelectionProperty to achieve that.
👏
 
Upvote 0

BlueVision

Well-Known Member
Licensed User
Longtime User
What can I say...
Perhaps my answer will bring a little smile to your faces, to paraphrase Kennedy's famous words:

We decided to copy selected text from a B4XTextField to the clipboard.
We decided to copy selected text from a B4XTextField to the clipboard and do other things in this decade, not because they are easy, but because they are hard!

Steve, that was exactly the missing piece of rocket science I needed!
After a little trial and error to figure out which routine to place the three lines of code for initialising the event handler in, your solution works perfectly.
Thank you so much for making my problem your problem and presenting me with the solution on a silver platter.
Do you know those days when you feel terribly alone on this planet, surrounded by geniuses?

THANK'S A LOT
 
Upvote 0

PaulMeuris

Well-Known Member
Licensed User
And here are a few extra's:
If the ClickCount = 3 then the whole sentence is selected and put on the clipboard.
If you click and drag the mouse to select a piece of text then that selection will be put on the clipboard.
When the B4XFloatTextField focus changes you can get the selection with the properties SelectionStart and SelectionLength.
You can also select text with the keyboard (SHIFT + arrowkeys) and get that selection with the FocusChanged method or from a button click subroutine.
NOTE: when the B4XFloatTextField is NOT multiline getting the keyboard selection text doesn't seem to work.

B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    Dim JO As JavaObject = B4XFloatTextField1.TextField
    Dim O As Object = JO.CreateEventFromUI("javafx.event.EventHandler","B4xTFClick",Null)
    JO.RunMethod("setOnMouseClicked",Array(O))
End Sub
Private Sub B4xTFCLick_Event (MethodName As String, Args() As Object)
    Dim TF As JavaObject = Sender
    Dim Evt As MouseEvent = Args(0)
    If Evt.PrimaryButtonPressed And Evt.ClickCount >= 2 Then
        fx.Clipboard.SetString(TF.RunMethod("getSelectedText",Null))
        Label1.Text = fx.Clipboard.GetString
    Else
        fx.Clipboard.SetString(TF.RunMethod("getSelectedText",Null))
        Label1.Text = fx.Clipboard.GetString
    End If
End Sub
Private Sub B4XFloatTextField1_FocusChanged (HasFocus As Boolean)
    Label1.Text = ""
    Dim selstart As Int = B4XFloatTextField1.TextField.SelectionStart
    Dim sellength As Int = B4XFloatTextField1.TextField.SelectionLength
    Dim txt As String = B4XFloatTextField1.Text.SubString2(selstart,selstart+sellength)
    Label1.Text = txt
End Sub
Private Sub Button1_Click
    Log(B4XFloatTextField1.TextField.As(B4XView).SelectionStart)
    Label2.Text = ""
    Dim selstart As Int = B4XFloatTextField1.TextField.SelectionStart
    Dim sellength As Int = B4XFloatTextField1.TextField.SelectionLength
    Dim txt As String = B4XFloatTextField1.Text.SubString2(selstart,selstart+sellength)
    Label2.Text = txt
End Sub
 

Attachments

  • testenvironment100.zip
    3.5 KB · Views: 42
Upvote 0
Top