B4J Question What replaces inline Java method parameter File in b4j?

jkhazraji

Active Member
Licensed User
Longtime User
What parameter in B4J is to replace the File parameter of the following inline java method to call it with RunMethod??
e.g,
B4X:
(Me).As(JavaObject).RunMethod("process",Array As Object("sometext",??))

B4X:
#if java
public static void process(String name, File... files)  {
            for (File file : files){
                sub_process(name, file, ".");
            }
    }
#end if
I know the ... refers to a variable number of paramaters
I really could not figure it!!
 
Last edited:
Solution
Calling a varargs method is not a problem

B4X:
(Me).as(JavaObject).RunMethod("test", Array("Fred", Array As String("one", "two", "three")))

...
#If Java
public static void test(String name, String ... s){
    for (String ss : s){
        System.out.println(ss);
   }
}
#End If

Will work quite happily.

It works because we can have an array of String.

Your problem will be you are passing a File object, which B4X knows nothing about.

You can either pass them as an Object Array, then in the java code cast them back to File , or pass the filenames as Strings and create the File in the java code.

The first option will require you to create some java objects for the File class.
B4X:
Dim file1 As JavaObject...

drgottjr

Expert
Licensed User
Longtime User
in theory, you could pass a second array as the second parameter, eg
RunMethod("process",Array As Object("sometext",Array As Object)
but runmethod() is not quite what it looks like. javaobject.jar is worthy of study.

i've made a half-hearted attempt to use the ...'s form, but runmethod() didn't like it. i put it aside for the moment.

in any case, i think you should be able to pass a list or an array as the second parameter to solve your problem.
the ...'s just create an array anyway when the compiler sees them, so make life simple and put an array or list on the stack yourself.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Calling a varargs method is not a problem

B4X:
(Me).as(JavaObject).RunMethod("test", Array("Fred", Array As String("one", "two", "three")))

...
#If Java
public static void test(String name, String ... s){
    for (String ss : s){
        System.out.println(ss);
   }
}
#End If

Will work quite happily.

It works because we can have an array of String.

Your problem will be you are passing a File object, which B4X knows nothing about.

You can either pass them as an Object Array, then in the java code cast them back to File , or pass the filenames as Strings and create the File in the java code.

The first option will require you to create some java objects for the File class.
B4X:
Dim file1 As JavaObject
file1.InitializeNewInstance("java.io.File",array( "somefilepath" ))
...
(Me).As(JavaObject).RunMethod("process",Array As Object("sometext",Array (file1, file2)))

...
#if java
import java.util.Arrays;
import java.io.File;

public static void process(String name, Object... files)  {
            File[] f = Arrays.copyOf(files, files.length, File[].class;
            for (File file : f){
                sub_process(name, file, ".");
            }
    }
#end if

The second option is easier as using your code you could have
B4X:
(Me).As(JavaObject).RunMethod("process",Array As Object("sometext",Array As String ("C:/file1.txt", "C:/file2.txt")))

...
#if java
import java.io.File;

public static void process(String name, String... files)  {
            for (String file : files){
                sub_process(name, New File(file), ".");
            }
    }
#end if

(I hope that is clear enough)
 
Last edited:
Upvote 1
Solution

drgottjr

Expert
Licensed User
Longtime User
or pass the array as the second parameter: jo.RunMethod("process",Array As Object("hello",sarray)) either way works.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
or pass the array as the second parameter: jo.RunMethod("process",Array As Object("hello",sarray)) either way works.

I agree with you, it's the File thats the problem as B4X doesnt know what they are.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
yeah, for sure. but he could pass the file names and convert to File types in the inline as you point out. full disclosure, i also tried with a list with the thought that it's easier to build a list without knowing how big it would be (eg, every time the user clicked on some file, it would be added to a list. then pass the list). but passing a list
proved troublesome; given the differences between b4x's list wrapper and java's arraylist type. b4x's array mirrors java's, so easier to deal with. so if op went with list, he would probably have to convert it to an array before passing that to runmethod(). i didn't spend a lot of time trying to pass the list, but if you have nothing better to do, it might be worth a few minutes. the issue seemed to be whether to pass it as a b4x list or a javaobject and then back your way into how java receives it even with casting or whether to try and deal with it as a b4x collections List type
 
Upvote 0

jkhazraji

Active Member
Licensed User
Longtime User
Calling a varargs method is not a problem

B4X:
(Me).as(JavaObject).RunMethod("test", Array("Fred", Array As String("one", "two", "three")))

...
#If Java
public static void test(String name, String ... s){
    for (String ss : s){
        System.out.println(ss);
   }
}
#End If

Will work quite happily.

It works because we can have an array of String.

Your problem will be you are passing a File object, which B4X knows nothing about.

You can either pass them as an Object Array, then in the java code cast them back to File , or pass the filenames as Strings and create the File in the java code.

The first option will require you to create some java objects for the File class.
B4X:
Dim file1 As JavaObject
file1.InitializeNewInstance("java.io.File",array( "somefilepath" ))
...
(Me).As(JavaObject).RunMethod("process",Array As Object("sometext",Array (file1, file2)))

...
#if java
import java.util.Arrays;
import java.io.File;

public static void process(String name, Object... files)  {
            File[] f = Arrays.copyOf(files, files.length, File[].class;
            for (File file : f){
                sub_process(name, file, ".");
            }
    }
#end if

The second option is easier as using your code you could have
B4X:
(Me).As(JavaObject).RunMethod("process",Array As Object("sometext",Array As String ("C:/file1.txt", "C:/file2.txt")))

...
#if java
import java.io.File;

public static void process(String name, String... files)  {
            for (String file : files){
                sub_process(name, New File(file), ".");
            }
    }
#end if

(I hope that is clear enough)
Great.. Thanks. Both options worked like a breeze šŸ’šŸ’..marked as a solution.
 
Upvote 0

jkhazraji

Active Member
Licensed User
Longtime User
Calling a varargs method is not a problem

B4X:
(Me).as(JavaObject).RunMethod("test", Array("Fred", Array As String("one", "two", "three")))

...
#If Java
public static void test(String name, String ... s){
    for (String ss : s){
        System.out.println(ss);
   }
}
#End If

Will work quite happily.

It works because we can have an array of String.

Your problem will be you are passing a File object, which B4X knows nothing about.
Could it be a wish to make B4X know this guy having a File object of its own!!
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Could it be a wish to make B4X know this guy having a File object of its own!!
No. By design there are less types in B4X.

And if you need it for inline Java then convert the strings to Files as @Daestrum did. Don't worry about performance. It will not have any impact.
 
Upvote 0

jkhazraji

Active Member
Licensed User
Longtime User
No. By design there are less types in B4X.

And if you need it for inline Java then convert the strings to Files as @Daestrum did. Don't worry about performance. It will not have any impact.
Thanks @Erel for you reply.. and thanks for making B4X such an open space for dialog opportunities between newbies (like me) and experts.
 
Upvote 0
Top