B4J Question addHandler works in debug but not release mode

Nokia

Active Member
Licensed User
Longtime User
i'v noticed that this code works in debug mode but not in release mode. I'm thinking it has to do with getting getfield(BA) but not sure. not sure what I'm missing?

B4X:
    Dim pwd As JavaObject
    pwd.InitializeNewInstance("javafx.scene.control.PasswordField",Null)
    Dim joMe As JavaObject = Me
    Dim ba As Object = joMe.GetField("ba")
    Me.as(JavaObject).RunMethod("addHandler",Array(pwd, ba, Me))


#If java
import anywheresoftware.b4j.objects.PaneWrapper.ConcretePaneWrapper;
import anywheresoftware.b4a.BA;
import javafx.scene.control.PasswordField;

public static void addHandler(PasswordField pw, BA ba, Object b4xPage){
    pw.textProperty().addListener((obs, oldText, newText) -> {
        ba.raiseEventFromUI(b4xPage, "onpasswordchanged", newText);
    });
}
#End If


Sub OnPasswordChanged(NewPassword As String)
    'called from java code below  
    Dim strength As Int = pg.CalcPwdStrength(NewPassword)
    Log("Strength P: " & strength)
    hp.Value = strength
End Sub
 
Solution
it doesn't work in obfuscated as is - you need to change the name of the sub and the call from onpasswordchanged to onpassword_changed then the java can find it.

{this might explain why combo etc wasn't working for you either)

I expanded the code to look for the obfuscated name if you don't want to add _ to the name. (doesn't seem to work in standalone package)
B4X:
#if java
import javafx.scene.control.PasswordField;
import anywheresoftware.b4a.*;
import java.lang.reflect.*;
import java.io.*;
import java.nio.file.*;

public static void addHandler(PasswordField pw,Object caller,String callee){
    pw.textProperty().addListener((obs, oldText, newText) -> {
        Field field = null;
        BA ba = null;
        String...

b4x-de

Active Member
Licensed User
Longtime User
You have asked a similar question already on Sep, 15th and received answers that suggested to change to a regular text field, set die password field property and add events via designer. It might help to give the instructions already given another try.


 
Upvote 0

Nokia

Active Member
Licensed User
Longtime User

If you seen my response, you would have seen that its issue is not just for password field, it's for combobox with editable enabled. I also do not use the internal designer. I use the fx Scene builder. I might be blind, but I don't see that option for textfield.

I use the addhandler on the passwordfield and combobox.
 
Upvote 0

Nokia

Active Member
Licensed User
Longtime User
Also, this is a different issue than on my previous thread.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
I did play around a bit more with it after giving you last answer in your other thread.
This version seems to work in debug and release mode.

B4X:
import javafx.scene.control.PasswordField;
import anywheresoftware.b4a.*;
import java.lang.reflect.*;

public static void addHandler(PasswordField pw,Object caller){
	pw.textProperty().addListener((obs, oldText, newText) -> {
		Field field = null;
		BA ba = null;
		try{
			field = caller.getClass().getField("ba");
			if (field == null) IO.println("ba is null");
		    ba = (BA)field.get(caller);
			ba.raiseEventFromUI(caller, "onpasswordchanged", newText);
                } catch (NoSuchFieldException | IllegalAccessException e) {
		IO.println("Error " + e);
		}

	});
}
***Note change IO.println(...) to System.out.println(...) if not using latest java

It works out 'ba' for itself you just pass the pwfield and 'Me' as a javaobject
B4X:
Me.as(JavaObject).RunMethod("addHandler",Array(pw,Me.as(JavaObject)))
 
Upvote 0

Nokia

Active Member
Licensed User
Longtime User
I have updated the code and works in debug but still does not work in release. I'm using Java jdk1.8.0_251. I pass the passwordfield to a B4Xview. I have tried bypassing that and add to form directly. still same issue. I did notice in release mode the passwordfield or combobox text fields, I have to click on them a few times before I can type in them or select anything out of them. Does not do that in debug mode.
 
Upvote 0

Nokia

Active Member
Licensed User
Longtime User
I can see the java part of the code is executing.

Java:
import anywheresoftware.b4j.objects.PaneWrapper.ConcretePaneWrapper;
import anywheresoftware.b4a.BA;
import javafx.scene.control.PasswordField;

public static void addHandler(PasswordField pw, BA ba, Object b4xPage){

    // Print when the method is called
    System.out.println("addHandler executed.");
    
    pw.textProperty().addListener((obs, oldText, newText) -> {
    
    // Print when the method is called
    System.out.println(newText);
    
        ba.raiseEventFromUI(b4xPage, "onpasswordchanged", newText);
    });
}

it's this line not working ( ba.raiseEventFromUI(b4xPage, "onpasswordchanged", newText)).
 
Upvote 0

Nokia

Active Member
Licensed User
Longtime User

So, I have noticed if I compile in just Release mode it works. Something I never do. I alway use Rel;ease (obfuscated), and it does not work when I do this. Daestrum, can you configm yours does the same thing?
 
Upvote 0

Nokia

Active Member
Licensed User
Longtime User
I have added the the #event and still dos not work.

B4X:
#Event: onpasswordchanged(NewPassword As String)

Sub onpasswordchanged(NewPassword As String)
    'called from java code below   
    Dim strength As Int = pg.CalcPwdStrength(NewPassword)
    Log("Strength P: " & strength)
    hp.Value = strength
End Sub
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
it doesn't work in obfuscated as is - you need to change the name of the sub and the call from onpasswordchanged to onpassword_changed then the java can find it.

{this might explain why combo etc wasn't working for you either)

I expanded the code to look for the obfuscated name if you don't want to add _ to the name. (doesn't seem to work in standalone package)
B4X:
#if java
import javafx.scene.control.PasswordField;
import anywheresoftware.b4a.*;
import java.lang.reflect.*;
import java.io.*;
import java.nio.file.*;

public static void addHandler(PasswordField pw,Object caller,String callee){
    pw.textProperty().addListener((obs, oldText, newText) -> {
        Field field = null;
        BA ba = null;
        String called = null;
        try{
            field = caller.getClass().getField("ba");
            if (field == null) IO.println("ba is null");
            ba = (BA)field.get(caller);
            if (ba.subExists(callee)){
                called = callee;
            } else {
                called = findObs(callee);
                if (called==null) IO.println("sub not found - check name");
            }  
            ba.raiseEventFromUI(caller, called, newText);
        } catch (NoSuchFieldException | IllegalAccessException | IOException e) {
        IO.println("Error " + e);
        }

    });
}
// find the obfuscated name in name map
public static String findObs(String name) throws IOException {
    Path path = Paths.get("../Objects/ObfuscatorMap.txt");
    String beforeEquals = null;
    try (BufferedReader reader = Files.newBufferedReader(path)) {
        String line;
        while ((line = reader.readLine()) != null) {
            if (line.contains(name)) {
                int index = line.indexOf('=');
                if (index != -1) {
                    beforeEquals = line.substring(0, index);
                }
                break;
            }
        }
    }
    return beforeEquals;
}
#End If

also it takes a new parameter in the call so the callback name isn't hard coded in the routine anymore
B4X:
Me.as(JavaObject).RunMethod("addHandler",Array(pw, Me, "onpasswordchanged"))
 
Last edited:
Upvote 0
Solution

Nokia

Active Member
Licensed User
Longtime User

That worked, I added the _ to the event and it worked. Thanks!! I had the cbo events passed as you talked about, so I update the password to be the same.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…