B4J Question SelectionChanged event in TextArea

Daestrum

Expert
Licensed User
Longtime User
Example code uses JavaObject library.
The sub name is hard coded in the java but could be changed to be a parameter.

B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Dim ta As TextArea
    Dim la As Label
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.Show
    ta.Initialize("ta")
    asJO(Me).RunMethod("addChangeListen",Array(ta))
    MainForm.RootPane.AddNode(ta,0,0,200,200)
    la.Initialize("")
    MainForm.RootPane.AddNode(la,300,10,200,20)
End Sub
Sub ta_OnSelectionChanged(oldValue As String,newValue As String)
    la.Text = newValue.Replace(CRLF,"<crlf>")
End Sub
Sub asJO(o As JavaObject) As JavaObject
    Return o
End Sub
#if java
import javafx.scene.control.TextArea;
import javafx.beans.value.*;
import java.lang.Exception.*;

public static void addChangeListen(TextArea ta){
    ta.selectedTextProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(final ObservableValue<? extends String> observable, final String oldValue, final String newValue) {
        try{
           // the next line calls the sub in this module ta_OnSelectionChanged(...)       
            _ta_onselectionchanged(oldValue,newValue);
        } catch (Exception e){
        }
    }
});
}
#end if
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Better version that allows you to name the called sub.
B4X:
Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.Show
    ta.Initialize("ta")
    ' next line will add listener to TextArea ta and sub will be called ta_OnSelectionChanged(...)
    ' params 1 - Me (this class)
    '        2 - The TextArea
    '        3 - The prefix for OnSelectionChanged sub ie; ta
    asJO(Me).RunMethod("addChangeListen",Array(Me,ta,"ta"))
    MainForm.RootPane.AddNode(ta,0,0,200,200)
    la.Initialize("")
    MainForm.RootPane.AddNode(la,300,10,200,20)
End Sub
Sub ta_OnSelectionChanged(oldValue As String,newValue As String)
    la.Text = newValue.Replace(CRLF,"<crlf>")
End Sub
Sub asJO(o As JavaObject) As JavaObject
    Return o
End Sub
#if java
import javafx.scene.control.TextArea;
import javafx.beans.value.*;
import java.lang.Exception.*;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;

public static void addChangeListen(final Class clss,TextArea ta,String subName) throws NoSuchMethodException,Exception{
    String a="";
    final Object o = clss.newInstance();
    final Method m = clss.getDeclaredMethod("_"+subName+"_onselectionchanged",a.getClass(),a.getClass());
    ta.selectedTextProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(final ObservableValue<? extends String> observable, final String oldValue, final String newValue) {
            try{
                m.invoke(o,oldValue,newValue);       
            } catch (IllegalAccessException iae){
                System.out.println("You do not have permission to access this member");
            } catch (InvocationTargetException ite){
                System.out.println("Method not found in "+clss.getName());
            }
    }
});
}
#end if

@Erel - I can't remove the try/catch as it can throw exceptions on calling the sub.
 
Upvote 0

jolx

Member
Licensed User
Longtime User
Thank you very much

Finally I solved it with a Timer, watching the SelectionStart and SelectionEnd properties every X miliseconds. But next time it is possible that I use this solution.
 
Upvote 0
Top