Johan Schoeman Expert Licensed User Longtime User Jan 7, 2016 #1 I am a bit lost here...have searched the forum but could thus far not find a suitable solution. I have an ArrayList in a wrapper that is defined as follows: B4X: Expand Collapse Copy ArrayList<ClientScanResult> clients It is returned to the B4A project via: B4X: Expand Collapse Copy ba.raiseEvent2(ba, false, eventName + "_scan_result", true, new Object[] {clients}); My B4A event is as follows: B4X: Expand Collapse Copy Sub hotspot_scan_result (clients As Object) When I log "clients" in the B4A code I get for eg: B4X: Expand Collapse Copy [main.java.ClientScanResult@42c97f00] Each "clients" object consists of 3 x Strings and 1 x Boolean. How do I extract this from the "clients" object that is returned to B4A? Can someone please advise on this? Thanks
I am a bit lost here...have searched the forum but could thus far not find a suitable solution. I have an ArrayList in a wrapper that is defined as follows: B4X: Expand Collapse Copy ArrayList<ClientScanResult> clients It is returned to the B4A project via: B4X: Expand Collapse Copy ba.raiseEvent2(ba, false, eventName + "_scan_result", true, new Object[] {clients}); My B4A event is as follows: B4X: Expand Collapse Copy Sub hotspot_scan_result (clients As Object) When I log "clients" in the B4A code I get for eg: B4X: Expand Collapse Copy [main.java.ClientScanResult@42c97f00] Each "clients" object consists of 3 x Strings and 1 x Boolean. How do I extract this from the "clients" object that is returned to B4A? Can someone please advise on this? Thanks
R Roycefer Well-Known Member Licensed User Longtime User Jan 7, 2016 #2 Do you have access to the main.java.ClientScanResult class in your B4A code? If so, try the following: B4X: Expand Collapse Copy Sub hotspot_scan_result (clients As Object) Dim clientsList As List = clients For Each csr As ClientScanResult In clientsList 'access the member data of csr, for example: Log(csr.String1 & " " & csr.String2 & " " & csr.String3 & " " & csr.TheBooleanValue) 'or whatever, depending on how the data members are named. Next End Sub The above example will require casting an ArrayList to a B4X List. I don't recall if this will work. If it doesn't, you have a couple options. In your Java code, use a B4X List instead of an ArrayList. Or, use JavaObject inside the B4A event to access the "get" and "length" methods of the ArrayList and then run a For-Loop to "get" all of the elements in the ArrayList. Of course, you'll still need to be able to create instances of the ClientScanResult class. Upvote 0
Do you have access to the main.java.ClientScanResult class in your B4A code? If so, try the following: B4X: Expand Collapse Copy Sub hotspot_scan_result (clients As Object) Dim clientsList As List = clients For Each csr As ClientScanResult In clientsList 'access the member data of csr, for example: Log(csr.String1 & " " & csr.String2 & " " & csr.String3 & " " & csr.TheBooleanValue) 'or whatever, depending on how the data members are named. Next End Sub The above example will require casting an ArrayList to a B4X List. I don't recall if this will work. If it doesn't, you have a couple options. In your Java code, use a B4X List instead of an ArrayList. Or, use JavaObject inside the B4A event to access the "get" and "length" methods of the ArrayList and then run a For-Loop to "get" all of the elements in the ArrayList. Of course, you'll still need to be able to create instances of the ClientScanResult class.
JordiCP Expert Licensed User Longtime User Jan 7, 2016 #3 Hi, I tested it, with an arrayList of strings instead of a custom class, with these results: The inline java part B4X: Expand Collapse Copy public void test(){ ArrayList<String> clients = new ArrayList<String>(3); clients.add("ONE"); clients.add("TWO"); clients.add("THREE"); //ba.raiseEvent2(ba, false, "prova_result", true, new Object{clients}); processBA.raiseEvent(null, "prova_result", new Object[]{clients}); } B4A part B4X: Expand Collapse Copy Sub prova_result(clients As Object) Log("Result is:"&clients) End Sub The Logs are [ONE,TWO,THREE] as expected. I suppose that if you have a custom type ArrayList, its fields can only be accessed by "GetField" instance. Test with this simple case to see if the difference is the "simple type" vs the "custom class type" of the ArrayList or there is something else Upvote 0
Hi, I tested it, with an arrayList of strings instead of a custom class, with these results: The inline java part B4X: Expand Collapse Copy public void test(){ ArrayList<String> clients = new ArrayList<String>(3); clients.add("ONE"); clients.add("TWO"); clients.add("THREE"); //ba.raiseEvent2(ba, false, "prova_result", true, new Object{clients}); processBA.raiseEvent(null, "prova_result", new Object[]{clients}); } B4A part B4X: Expand Collapse Copy Sub prova_result(clients As Object) Log("Result is:"&clients) End Sub The Logs are [ONE,TWO,THREE] as expected. I suppose that if you have a custom type ArrayList, its fields can only be accessed by "GetField" instance. Test with this simple case to see if the difference is the "simple type" vs the "custom class type" of the ArrayList or there is something else
Johan Schoeman Expert Licensed User Longtime User Jan 7, 2016 #4 JordiCP said: Hi, I tested it, with an arrayList of strings instead of a custom class, with these results: The inline java part B4X: Expand Collapse Copy public void test(){ ArrayList<String> clients = new ArrayList<String>(3); clients.add("ONE"); clients.add("TWO"); clients.add("THREE"); //ba.raiseEvent2(ba, false, "prova_result", true, new Object{clients}); processBA.raiseEvent(null, "prova_result", new Object[]{clients}); } B4A part B4X: Expand Collapse Copy Sub prova_result(clients As Object) Log("Result is:"&clients) End Sub The Logs are [ONE,TWO,THREE] as expected. I suppose that if you have a custom type ArrayList, its fields can only be accessed by "GetField" instance. Test with this simple case to see if the difference is the "simple type" vs the "custom class type" of the ArrayList or there is something else Click to expand... Thanks Jordi - it is a custom class type so it seems that GetField is probably the way to go then... ArrayList<ClientScanResult> clients Upvote 0
JordiCP said: Hi, I tested it, with an arrayList of strings instead of a custom class, with these results: The inline java part B4X: Expand Collapse Copy public void test(){ ArrayList<String> clients = new ArrayList<String>(3); clients.add("ONE"); clients.add("TWO"); clients.add("THREE"); //ba.raiseEvent2(ba, false, "prova_result", true, new Object{clients}); processBA.raiseEvent(null, "prova_result", new Object[]{clients}); } B4A part B4X: Expand Collapse Copy Sub prova_result(clients As Object) Log("Result is:"&clients) End Sub The Logs are [ONE,TWO,THREE] as expected. I suppose that if you have a custom type ArrayList, its fields can only be accessed by "GetField" instance. Test with this simple case to see if the difference is the "simple type" vs the "custom class type" of the ArrayList or there is something else Click to expand... Thanks Jordi - it is a custom class type so it seems that GetField is probably the way to go then... ArrayList<ClientScanResult> clients
Informatix Expert Licensed User Longtime User Jan 7, 2016 #5 The more convenient way for the end user is to create a Java class to wrap ClientScanResult and to convert your ArrayList to a List. Example: B4X: Expand Collapse Copy for (ClientScanResult CSR: clients) { mylist.Add(new ClientScanResultWrapper(CSR)); } Upvote 0
The more convenient way for the end user is to create a Java class to wrap ClientScanResult and to convert your ArrayList to a List. Example: B4X: Expand Collapse Copy for (ClientScanResult CSR: clients) { mylist.Add(new ClientScanResultWrapper(CSR)); }
Johan Schoeman Expert Licensed User Longtime User Jan 7, 2016 #6 JordiCP said: Hi, I tested it, with an arrayList of strings instead of a custom class, with these results: The inline java part B4X: Expand Collapse Copy public void test(){ ArrayList<String> clients = new ArrayList<String>(3); clients.add("ONE"); clients.add("TWO"); clients.add("THREE"); //ba.raiseEvent2(ba, false, "prova_result", true, new Object{clients}); processBA.raiseEvent(null, "prova_result", new Object[]{clients}); } B4A part B4X: Expand Collapse Copy Sub prova_result(clients As Object) Log("Result is:"&clients) End Sub The Logs are [ONE,TWO,THREE] as expected. I suppose that if you have a custom type ArrayList, its fields can only be accessed by "GetField" instance. Test with this simple case to see if the difference is the "simple type" vs the "custom class type" of the ArrayList or there is something else Click to expand... Jordi, still a bit confused here...so how do you now extract each of the elements in the B4A sub and assign each of them to a separate String variable? Do you define a B4A List and set the List = clients ? Upvote 0
JordiCP said: Hi, I tested it, with an arrayList of strings instead of a custom class, with these results: The inline java part B4X: Expand Collapse Copy public void test(){ ArrayList<String> clients = new ArrayList<String>(3); clients.add("ONE"); clients.add("TWO"); clients.add("THREE"); //ba.raiseEvent2(ba, false, "prova_result", true, new Object{clients}); processBA.raiseEvent(null, "prova_result", new Object[]{clients}); } B4A part B4X: Expand Collapse Copy Sub prova_result(clients As Object) Log("Result is:"&clients) End Sub The Logs are [ONE,TWO,THREE] as expected. I suppose that if you have a custom type ArrayList, its fields can only be accessed by "GetField" instance. Test with this simple case to see if the difference is the "simple type" vs the "custom class type" of the ArrayList or there is something else Click to expand... Jordi, still a bit confused here...so how do you now extract each of the elements in the B4A sub and assign each of them to a separate String variable? Do you define a B4A List and set the List = clients ?
Johan Schoeman Expert Licensed User Longtime User Jan 7, 2016 #7 This is how I have solved it. Probably not the "purest" way of doing it but it is much easier having to take care of a Boolean value that was converted to a String (in the Java code) when it arrives in the B4A event than to try and sort out a "mixed basket of fruits" that gets passed to the B4A event from the wrapper: The Java code: B4X: Expand Collapse Copy public void scan() { wifiApManager.getClientList(false, new FinishScanListener() { @Override public void onFinishScan(final ArrayList<ClientScanResult> clients) { ArrayList<String> mylist = new ArrayList<String>(); for (ClientScanResult clientScanResult : clients) { mylist.add(clientScanResult.getIpAddr()); mylist.add(clientScanResult.getDevice()); mylist.add(clientScanResult.getHWAddr()); //Convert the boolean value of "isReachable()" to a String before adding it to mylist //Now we only need to return a basket of apples and not a basket of mixed fruits //It can then be assigned to a B4A list in the B4A code mylist.add(String.valueOf(clientScanResult.isReachable())); } if (ba.subExists(eventName + "_scan_result")) { ba.raiseEvent2(ba, false, eventName + "_scan_result", true, new Object[] {mylist}); } } }); } The B4A code: B4X: Expand Collapse Copy Sub hotspot_scan_result (mylist As Object) Dim ml As List ml= mylist For i = 0 To ml.Size - 1 If (i+1) mod 4 = 1 Then Log("IpAddr = " & ml.Get(i)) If (i+1) mod 4 = 2 Then Log("Device = " & ml.Get(i)) If (i+1) mod 4 = 3 Then Log("HWAddr = " & ml.Get(i)) If (i+1) mod 4 = 0 Then Log("Reachable = " & ml.Get(i)) If (i+1) mod 4 = 0 Then Log(" ") Next End Sub Upvote 0
This is how I have solved it. Probably not the "purest" way of doing it but it is much easier having to take care of a Boolean value that was converted to a String (in the Java code) when it arrives in the B4A event than to try and sort out a "mixed basket of fruits" that gets passed to the B4A event from the wrapper: The Java code: B4X: Expand Collapse Copy public void scan() { wifiApManager.getClientList(false, new FinishScanListener() { @Override public void onFinishScan(final ArrayList<ClientScanResult> clients) { ArrayList<String> mylist = new ArrayList<String>(); for (ClientScanResult clientScanResult : clients) { mylist.add(clientScanResult.getIpAddr()); mylist.add(clientScanResult.getDevice()); mylist.add(clientScanResult.getHWAddr()); //Convert the boolean value of "isReachable()" to a String before adding it to mylist //Now we only need to return a basket of apples and not a basket of mixed fruits //It can then be assigned to a B4A list in the B4A code mylist.add(String.valueOf(clientScanResult.isReachable())); } if (ba.subExists(eventName + "_scan_result")) { ba.raiseEvent2(ba, false, eventName + "_scan_result", true, new Object[] {mylist}); } } }); } The B4A code: B4X: Expand Collapse Copy Sub hotspot_scan_result (mylist As Object) Dim ml As List ml= mylist For i = 0 To ml.Size - 1 If (i+1) mod 4 = 1 Then Log("IpAddr = " & ml.Get(i)) If (i+1) mod 4 = 2 Then Log("Device = " & ml.Get(i)) If (i+1) mod 4 = 3 Then Log("HWAddr = " & ml.Get(i)) If (i+1) mod 4 = 0 Then Log("Reachable = " & ml.Get(i)) If (i+1) mod 4 = 0 Then Log(" ") Next End Sub
Informatix Expert Licensed User Longtime User Jan 7, 2016 #8 Johan Schoeman said: This is how I have solved it. Probably not the "purest" way of doing it but it is much easier having to take care of a Boolean value that was converted to a String (in the Java code) when it arrives in the B4A event than to try and sort out a "mixed basket of fruits" that gets passed to the B4A event from the wrapper: The Java code: B4X: Expand Collapse Copy public void scan() { wifiApManager.getClientList(false, new FinishScanListener() { @Override public void onFinishScan(final ArrayList<ClientScanResult> clients) { ArrayList<String> mylist = new ArrayList<String>(); for (ClientScanResult clientScanResult : clients) { mylist.add(clientScanResult.getIpAddr()); mylist.add(clientScanResult.getDevice()); mylist.add(clientScanResult.getHWAddr()); //Convert the boolean value of "isReachable()" to a String before adding it to mylist //Now we only need to return a basket of apples and not a basket of mixed fruits //It can then be assigned to a B4A list in the B4A code mylist.add(String.valueOf(clientScanResult.isReachable())); } if (ba.subExists(eventName + "_scan_result")) { ba.raiseEvent2(ba, false, eventName + "_scan_result", true, new Object[] {mylist}); } } }); } The B4A code: B4X: Expand Collapse Copy Sub hotspot_scan_result (mylist As Object) Dim ml As List ml= mylist For i = 0 To ml.Size - 1 If (i+1) mod 4 = 1 Then Log("IpAddr = " & ml.Get(i)) If (i+1) mod 4 = 2 Then Log("Device = " & ml.Get(i)) If (i+1) mod 4 = 3 Then Log("HWAddr = " & ml.Get(i)) If (i+1) mod 4 = 0 Then Log("Reachable = " & ml.Get(i)) If (i+1) mod 4 = 0 Then Log(" ") Next End Sub Click to expand... Instead of creating an ArrayList of strings, you should create a List: B4X: Expand Collapse Copy anywheresoftware.b4a.objects.collections.List mylist = new anywheresoftware.b4a.objects.collections.List(); mylist.Initialize(); So the object passed to the event is a B4A List. Upvote 0
Johan Schoeman said: This is how I have solved it. Probably not the "purest" way of doing it but it is much easier having to take care of a Boolean value that was converted to a String (in the Java code) when it arrives in the B4A event than to try and sort out a "mixed basket of fruits" that gets passed to the B4A event from the wrapper: The Java code: B4X: Expand Collapse Copy public void scan() { wifiApManager.getClientList(false, new FinishScanListener() { @Override public void onFinishScan(final ArrayList<ClientScanResult> clients) { ArrayList<String> mylist = new ArrayList<String>(); for (ClientScanResult clientScanResult : clients) { mylist.add(clientScanResult.getIpAddr()); mylist.add(clientScanResult.getDevice()); mylist.add(clientScanResult.getHWAddr()); //Convert the boolean value of "isReachable()" to a String before adding it to mylist //Now we only need to return a basket of apples and not a basket of mixed fruits //It can then be assigned to a B4A list in the B4A code mylist.add(String.valueOf(clientScanResult.isReachable())); } if (ba.subExists(eventName + "_scan_result")) { ba.raiseEvent2(ba, false, eventName + "_scan_result", true, new Object[] {mylist}); } } }); } The B4A code: B4X: Expand Collapse Copy Sub hotspot_scan_result (mylist As Object) Dim ml As List ml= mylist For i = 0 To ml.Size - 1 If (i+1) mod 4 = 1 Then Log("IpAddr = " & ml.Get(i)) If (i+1) mod 4 = 2 Then Log("Device = " & ml.Get(i)) If (i+1) mod 4 = 3 Then Log("HWAddr = " & ml.Get(i)) If (i+1) mod 4 = 0 Then Log("Reachable = " & ml.Get(i)) If (i+1) mod 4 = 0 Then Log(" ") Next End Sub Click to expand... Instead of creating an ArrayList of strings, you should create a List: B4X: Expand Collapse Copy anywheresoftware.b4a.objects.collections.List mylist = new anywheresoftware.b4a.objects.collections.List(); mylist.Initialize(); So the object passed to the event is a B4A List.
Informatix Expert Licensed User Longtime User Jan 7, 2016 #9 You can also create a map (anywheresoftware.b4a.objects.collections.Map) where the key is a constant string (IP_ADDR, DEVICE, etc.) and the value the string value. So there's no need to know the order of data to get a specific value. Upvote 0
You can also create a map (anywheresoftware.b4a.objects.collections.Map) where the key is a constant string (IP_ADDR, DEVICE, etc.) and the value the string value. So there's no need to know the order of data to get a specific value.
Johan Schoeman Expert Licensed User Longtime User Jan 7, 2016 #10 Informatix said: Instead of creating an ArrayList of strings, you should create a List: B4X: Expand Collapse Copy anywheresoftware.b4a.objects.collections.List mylist = new anywheresoftware.b4a.objects.collections.List(); mylist.Initialize(); So the object passed to the event is a B4A List. Click to expand... Will that allow a mixed list of variable types to be easily extracted in the B4A code? Or would I still have to convert the Boolean to a String in the Java code to make it easier? I read somewhere in the forum that Java's ArrayList is the equivalent of a B4A list. Is that not the case? Upvote 0
Informatix said: Instead of creating an ArrayList of strings, you should create a List: B4X: Expand Collapse Copy anywheresoftware.b4a.objects.collections.List mylist = new anywheresoftware.b4a.objects.collections.List(); mylist.Initialize(); So the object passed to the event is a B4A List. Click to expand... Will that allow a mixed list of variable types to be easily extracted in the B4A code? Or would I still have to convert the Boolean to a String in the Java code to make it easier? I read somewhere in the forum that Java's ArrayList is the equivalent of a B4A list. Is that not the case?
JordiCP Expert Licensed User Longtime User Jan 7, 2016 #11 This has worked for me (class fields need to be pulbic, otherwise you should work with getters) B4X: Expand Collapse Copy public class client { public String s1; public String s2; public Boolean b; public client(String s1_0,String s2_0, Boolean b_0) { s1=new String(s1_0); s2=new String(s2_0); b = b_0; } } public void test(){ ArrayList<client> clients = new ArrayList<client>(); clients.add( new client("Client1Name","Client1Surname",true)); clients.add( new client("Client2Name","Client2Surname",false)); clients.add( new client("Client3Name","Client3Surname",true)); processBA.raiseEvent(null, "prova_result", new Object[]{clients}); } In B4A B4X: Expand Collapse Copy Sub prova_result(clients As Object) Log("Result is:"&clients) Dim a As List a=clients For k=0 To a.Size-1 Dim J As JavaObject = a.Get(k) Log("Client:"&J.GetField("s1")&" "&J.GetField("s2")&" "&J.GetField("b")) Next End Sub Upvote 0
This has worked for me (class fields need to be pulbic, otherwise you should work with getters) B4X: Expand Collapse Copy public class client { public String s1; public String s2; public Boolean b; public client(String s1_0,String s2_0, Boolean b_0) { s1=new String(s1_0); s2=new String(s2_0); b = b_0; } } public void test(){ ArrayList<client> clients = new ArrayList<client>(); clients.add( new client("Client1Name","Client1Surname",true)); clients.add( new client("Client2Name","Client2Surname",false)); clients.add( new client("Client3Name","Client3Surname",true)); processBA.raiseEvent(null, "prova_result", new Object[]{clients}); } In B4A B4X: Expand Collapse Copy Sub prova_result(clients As Object) Log("Result is:"&clients) Dim a As List a=clients For k=0 To a.Size-1 Dim J As JavaObject = a.Get(k) Log("Client:"&J.GetField("s1")&" "&J.GetField("s2")&" "&J.GetField("b")) Next End Sub
Informatix Expert Licensed User Longtime User Jan 7, 2016 #12 Johan Schoeman said: Will that allow a mixed list of variable types to be easily extracted in the B4A code? Or would I still have to convert the Boolean to a String in the Java code to make it easier? I read somewhere in the forum that Java's ArrayList is the equivalent of a B4A list. Is that not the case? Click to expand... The primitive types do not need to be wrapped so if you have a string or a boolean in the original list, you can keep it as is. And the B4A list can contain mixed types. List wraps an ArrayList. If your ArrayList is an ArrayList<Object>, you can do: mylist.setObject(arrList); instead of adding (and thus copying) each item in a loop. Upvote 0
Johan Schoeman said: Will that allow a mixed list of variable types to be easily extracted in the B4A code? Or would I still have to convert the Boolean to a String in the Java code to make it easier? I read somewhere in the forum that Java's ArrayList is the equivalent of a B4A list. Is that not the case? Click to expand... The primitive types do not need to be wrapped so if you have a string or a boolean in the original list, you can keep it as is. And the B4A list can contain mixed types. List wraps an ArrayList. If your ArrayList is an ArrayList<Object>, you can do: mylist.setObject(arrList); instead of adding (and thus copying) each item in a loop.
Johan Schoeman Expert Licensed User Longtime User Jan 7, 2016 #13 JordiCP said: This has worked for me (class fields need to be pulbic, otherwise you should work with getters) B4X: Expand Collapse Copy public class client { public String s1; public String s2; public Boolean b; public client(String s1_0,String s2_0, Boolean b_0) { s1=new String(s1_0); s2=new String(s2_0); b = b_0; } } public void test(){ ArrayList<client> clients = new ArrayList<client>(); clients.add( new client("Client1Name","Client1Surname",true)); clients.add( new client("Client2Name","Client2Surname",false)); clients.add( new client("Client3Name","Client3Surname",true)); processBA.raiseEvent(null, "prova_result", new Object[]{clients}); } In B4A B4X: Expand Collapse Copy Sub prova_result(clients As Object) Log("Result is:"&clients) Dim a As List a=clients For k=0 To a.Size-1 Dim J As JavaObject = a.Get(k) Log("Client:"&J.GetField("s1")&" "&J.GetField("s2")&" "&J.GetField("b")) Next End Sub Click to expand... Jordi, I like what you have done above. I just don't understand the rationale behind the class variables having to be public when you are returning "clients" which is an ArrayList. Can you please elaborate on this? Upvote 0
JordiCP said: This has worked for me (class fields need to be pulbic, otherwise you should work with getters) B4X: Expand Collapse Copy public class client { public String s1; public String s2; public Boolean b; public client(String s1_0,String s2_0, Boolean b_0) { s1=new String(s1_0); s2=new String(s2_0); b = b_0; } } public void test(){ ArrayList<client> clients = new ArrayList<client>(); clients.add( new client("Client1Name","Client1Surname",true)); clients.add( new client("Client2Name","Client2Surname",false)); clients.add( new client("Client3Name","Client3Surname",true)); processBA.raiseEvent(null, "prova_result", new Object[]{clients}); } In B4A B4X: Expand Collapse Copy Sub prova_result(clients As Object) Log("Result is:"&clients) Dim a As List a=clients For k=0 To a.Size-1 Dim J As JavaObject = a.Get(k) Log("Client:"&J.GetField("s1")&" "&J.GetField("s2")&" "&J.GetField("b")) Next End Sub Click to expand... Jordi, I like what you have done above. I just don't understand the rationale behind the class variables having to be public when you are returning "clients" which is an ArrayList. Can you please elaborate on this?
Johan Schoeman Expert Licensed User Longtime User Jan 7, 2016 #14 Informatix said: The primitive types do not need to be wrapped so if you have a string or a boolean in the original list, you can keep it as is. And the B4A list can contain mixed types. List wraps an ArrayList. If your ArrayList is an ArrayList<Object>, you can do: mylist.setObject(arrList); instead of adding (and thus copying) each item in a loop. Click to expand... Thanks @Informatix. Will definateley give it a try! Upvote 0
Informatix said: The primitive types do not need to be wrapped so if you have a string or a boolean in the original list, you can keep it as is. And the B4A list can contain mixed types. List wraps an ArrayList. If your ArrayList is an ArrayList<Object>, you can do: mylist.setObject(arrList); instead of adding (and thus copying) each item in a loop. Click to expand... Thanks @Informatix. Will definateley give it a try!
JordiCP Expert Licensed User Longtime User Jan 7, 2016 #15 Johan Schoeman said: Jordi, I like what you have done above. I just don't understand the rationale behind the class variables having to be public when you are returning "clients" which is an ArrayList. Can you please elaborate on this? Click to expand... The arrayLists return the group of client instances, it is a "container". But as they are not primitive, you need a way to access its members in the B4A Sub. GetField will not work for instance if S2 is declared as private I have modified the example to reflect this. As S2 is private, for convenience a "GetS2" function has been declared to have access to it B4X: Expand Collapse Copy Sub prova_result(clients As Object) Log("Result is:"&clients) Dim a As List a=clients For k=0 To a.Size-1 Dim J As JavaObject = a.Get(k) 'Log("Client:"&J.GetField("s1")&" "&J.GetField("s2")&" "&J.GetField("b")) 'This will only work if all s1,s2,and b are publc members Dim s2 As String =J.RunMethod("getS2",Null) Log("Client:"&J.GetField("s1")&" "&s2&" "&J.GetField("b")) Next End Sub The java part B4X: Expand Collapse Copy public class client { public String s1; private String s2; //Now it is private public Boolean b; public client(String s1_0,String s2_0, Boolean b_0) { s1=new String(s1_0); s2=new String(s2_0); b = b_0; } public String getS2(){ return s2; } } public void test(){ ArrayList<client> clients = new ArrayList<client>(); clients.add( new client("Client1Name","Client1Surname",true)); clients.add( new client("Client2Name","Client2Surname",false)); clients.add( new client("Client3Name","Client3Surname",true)); processBA.raiseEvent(null, "prova_result", new Object[]{clients}); } Upvote 0
Johan Schoeman said: Jordi, I like what you have done above. I just don't understand the rationale behind the class variables having to be public when you are returning "clients" which is an ArrayList. Can you please elaborate on this? Click to expand... The arrayLists return the group of client instances, it is a "container". But as they are not primitive, you need a way to access its members in the B4A Sub. GetField will not work for instance if S2 is declared as private I have modified the example to reflect this. As S2 is private, for convenience a "GetS2" function has been declared to have access to it B4X: Expand Collapse Copy Sub prova_result(clients As Object) Log("Result is:"&clients) Dim a As List a=clients For k=0 To a.Size-1 Dim J As JavaObject = a.Get(k) 'Log("Client:"&J.GetField("s1")&" "&J.GetField("s2")&" "&J.GetField("b")) 'This will only work if all s1,s2,and b are publc members Dim s2 As String =J.RunMethod("getS2",Null) Log("Client:"&J.GetField("s1")&" "&s2&" "&J.GetField("b")) Next End Sub The java part B4X: Expand Collapse Copy public class client { public String s1; private String s2; //Now it is private public Boolean b; public client(String s1_0,String s2_0, Boolean b_0) { s1=new String(s1_0); s2=new String(s2_0); b = b_0; } public String getS2(){ return s2; } } public void test(){ ArrayList<client> clients = new ArrayList<client>(); clients.add( new client("Client1Name","Client1Surname",true)); clients.add( new client("Client2Name","Client2Surname",false)); clients.add( new client("Client3Name","Client3Surname",true)); processBA.raiseEvent(null, "prova_result", new Object[]{clients}); }
Informatix Expert Licensed User Longtime User Jan 7, 2016 #16 JordiCP said: But as they are not primitive, you need a way to access its members in the B4A Sub. Click to expand... It seems that the ClientScanResult class contains three strings and a boolean, so it's directly compatible with B4A. But, as a general rule of thumb, I prefer to create a wrapper as your client class so that all members can be accessed easily, with a significant name, from B4A. Another solution, as I suggested above, is to use a map with constant strings for the keys (to name the values). Upvote 0
JordiCP said: But as they are not primitive, you need a way to access its members in the B4A Sub. Click to expand... It seems that the ClientScanResult class contains three strings and a boolean, so it's directly compatible with B4A. But, as a general rule of thumb, I prefer to create a wrapper as your client class so that all members can be accessed easily, with a significant name, from B4A. Another solution, as I suggested above, is to use a map with constant strings for the keys (to name the values).
Johan Schoeman Expert Licensed User Longtime User Jan 7, 2016 #17 Informatix said: It seems that the ClientScanResult class contains three strings and a boolean, so it's directly compatible with B4A. But, as a general rule of thumb, I prefer to create a wrapper as your client class so that all members can be accessed easily, with a significant name, from B4A. Another solution, as I suggested above, is to use a map with constant strings for the keys (to name the values). Click to expand... So in all honesty, is the way I have solved it a "dumb" way of doing it? Upvote 0
Informatix said: It seems that the ClientScanResult class contains three strings and a boolean, so it's directly compatible with B4A. But, as a general rule of thumb, I prefer to create a wrapper as your client class so that all members can be accessed easily, with a significant name, from B4A. Another solution, as I suggested above, is to use a map with constant strings for the keys (to name the values). Click to expand... So in all honesty, is the way I have solved it a "dumb" way of doing it?
Informatix Expert Licensed User Longtime User Jan 8, 2016 #18 Johan Schoeman said: So in all honesty, is the way I have solved it a "dumb" way of doing it? Click to expand... No, there are multiple ways to do it. What I suggested in post #5 is just more convenient for the end user as he does not have to "decode" the result. It's a bit of extra work for you but very convenient for all your users. It's better to pass a B4A list to the event than a Java object, and better to access properties with their name (e.g. MyClientScanResultWrapper.IpAddr) than to get them with something like If (i+1) mod4 = 1 Then IpAddr = ml.Get(i). Upvote 0
Johan Schoeman said: So in all honesty, is the way I have solved it a "dumb" way of doing it? Click to expand... No, there are multiple ways to do it. What I suggested in post #5 is just more convenient for the end user as he does not have to "decode" the result. It's a bit of extra work for you but very convenient for all your users. It's better to pass a B4A list to the event than a Java object, and better to access properties with their name (e.g. MyClientScanResultWrapper.IpAddr) than to get them with something like If (i+1) mod4 = 1 Then IpAddr = ml.Get(i).