B4J Question SelectionChanged event in TextArea

Daestrum

Well-Known Member
Licensed 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
 

Daestrum

Well-Known Member
Licensed 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.
 

jolx

Member
Licensed 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.
 
Top