B4J Question SelectionChanged event in TextArea

Discussion in 'B4J Questions' started by jolx, Oct 11, 2016.

  1. jolx

    jolx Member Licensed User

    How can I have a SelectionChanged event in a TextArea view?

    Thanks
     
  2. Daestrum

    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.

    Code:
    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 JavaObjectAs 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
     
    Erel likes this.
  3. Erel

    Erel Administrator Staff Member Licensed User

    I recommend removing the try / catch block. It will only make it more complicate to find errors.
     
  4. Daestrum

    Daestrum Well-Known Member Licensed User

    Better version that allows you to name the called sub.
    Code:
    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 JavaObjectAs 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.
     
    ilan likes this.
  5. Erel

    Erel Administrator Staff Member Licensed User

    try {
    ...
    } catch (Exception e) {
    throw new RuntimeException(e);
    }
    [/code]

    However it is better to implement a small library for this code, pass BA to the method and raise an event with ba.raiseEvent.
     
  6. jolx

    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.
     
    xulihang likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice