Android Question add new object to array?

ilan

Expert
Licensed User
Longtime User
hi

when i create an array of objects i have to set the length of the array at the beginning but what if i would like to add a new object to this array? is it possible?

in java it is:

B4X:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits[4] = "Lemon";
 

ilan

Expert
Licensed User
Longtime User
when i try this:

B4X:
    Dim fruits() As String
    fruits = Array As String ("banna", "mango", "apple", "lemon")
    fruits(4) = "orange"
   
    For i = 0 To fruits.Length - 1
        Log(fruits(i))
    Next

i am getting:

Program started.
main._appstart (java line: 69)
java.lang.ArrayIndexOutOfBoundsException: 4
at b4j.example.main._appstart(main.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:84)
at b4j.example.main.start(main.java:36)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$163(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$176(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$174(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$175(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$149(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
To create a chain body in box2d you need to use an array with all vectors in it

So i need to use an array.
I want to add new points (vec2) to the array and create a different chain body on runtime

I can create a bunch of arrays but i would like to use the same array and only add new points to it.
 
Upvote 0

eurojam

Well-Known Member
Licensed User
Longtime User
what you can do anyway is
B4X:
    fruits = Array As String ("banna", "mango", "apple", "lemon")
   ' fruits(4) = "orange"
   fruits = Array As String ("banna", "mango", "apple", "lemon","orange")
    For i = 0 To fruits.Length - 1
        Log(fruits(i))
    Next
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
what you can do anyway is
B4X:
    fruits = Array As String ("banna", "mango", "apple", "lemon")
   ' fruits(4) = "orange"
   fruits = Array As String ("banna", "mango", "apple", "lemon","orange")
    For i = 0 To fruits.Length - 1
        Log(fruits(i))
    Next

I cannot do this because i am editing the array on runtime and to start adding items in a loop from a list or map is not a nice solution.

It should be possible to do it simpler since java provide this option.

You can also write fruit.add in java and like this add a new object to the end of the array.

If this is not possible in b4x then it could be a nice addition to the next version.

I hope @Erel can answer this question
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
ok i have created a simple function but i think it should be possible also like it is possible in java

B4X:
Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.SetFormStyle("UNIFIED")
'    MainForm.RootPane.LoadLayout("1") 'Load the layout file.
    MainForm.Show

    Dim fruits() As Object
    fruits = Array As String ("banna", "mango", "apple", "lemon")
    fruits = Array_Add(fruits, "mango")
    fruits = Array_Add(fruits, "orange")
    fruits = Array_Add(fruits, "apricot")
   
    For i = 0 To fruits.Length - 1
        Log(fruits(i))
    Next
End Sub

Sub Array_Add(arr() As Object, newitem As Object) As Object
    Dim new_array(arr.Length+1) As Object
    For i = 0 To arr.Length - 1
        new_array(i) = arr(i)
    Next
    new_array(new_array.Length-1) = newitem
    Return new_array
End Sub
 
Last edited:
Upvote 0

Mahares

Expert
Licensed User
Longtime User
If you insist on using an array here is a solution that starts with a list and converts the list to an array on the fly:
B4X:
Dim Mylist As List :Mylist.Initialize
    Mylist.AddAll (Array As String("Banana", "Orange", "Apple", "Mango"))
    Log(ConvertlistToArray(Mylist)(2))  'prints Apple

    Mylist.Add("Lemon")
    Log(ConvertlistToArray(Mylist)(4))  'prints lemon
         
    Mylist.Add("Pear")
    Log(ConvertlistToArray(Mylist)(5))  'prints Pear

Private Sub ConvertlistToArray (lstFrom As List) As Object()
     Dim JO As JavaObject = lstFrom
      Dim arrString() As Object = JO.RunMethod("toArray", Null)
      Return arrString
End Sub
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
everything is working fine @Erel
even if i use different object types

B4X:
#Region  Project Attributes
    #MainFormWidth: 600
    #MainFormHeight: 400
#End Region

Sub Process_Globals
    Type Custom_Item(a As Int, b As String, c As TextField, d As Pane, e As Float)
    Private fx As JFX
    Private MainForm As Form
    Private TextField1 As TextField
    Dim img As ImageView
    Dim b As Button
    Dim C_Item As Custom_Item
    Dim pnl1 As Pane
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.SetFormStyle("UNIFIED")
'    MainForm.RootPane.LoadLayout("1") 'Load the layout file.
    MainForm.Show

    b.Initialize("b")
    img.Initialize("img")
    pnl1.Initialize("pnl1")
    TextField1.Initialize("txtfl")
       
    C_Item.a = 5
    C_Item.b = "b"
    C_Item.c = TextField1
    C_Item.d = pnl1
    C_Item.e = 120052120.2263254633

    Dim fruits() As Object
    fruits = Array As String ("banna", "mango", "apple", "lemon")
    fruits = Array_Add(fruits, "mango")
    fruits = Array_Add(fruits, "orange")
    fruits = Array_Add(fruits, "apricot")
    fruits = Array_Add(fruits, 10)
    fruits = Array_Add(fruits, img)
    fruits = Array_Add(fruits, b)
    fruits = Array_Add(fruits, C_Item)
   
    For i = 0 To fruits.Length - 1
        Log(fruits(i))
    Next
End Sub

Sub Array_Add(arr() As Object, newitem As Object) As Object
    Dim new_array(arr.Length+1) As Object
    For i = 0 To arr.Length - 1
        new_array(i) = arr(i)
    Next
    new_array(new_array.Length-1) = newitem
    Return new_array
End Sub

log:

Program started.
banna
mango
apple
lemon
mango
orange
apricot
10
ImageView@40887fe6[styleClass=image-view]
Button@29574d9f[styleClass=button]''
[IsInitialized=false, a=5, b=b
, c=(TextField) TextField@4fb17c56[styleClass=text-input text-field], Text: , , d=(NonResizePane) PaneWrapper$ConcretePaneWrapper$NonResizePane@4cc54d09, e=1.2005212E8
]
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
The problem with your code is that it makes a new copy of the complete array whenever you add an item. If you are dealing with small arrays then it is insignificant. For non-small arrays it will be too slow.

A better solution (only if you must have an array) is to use the code Mahares posted.
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
The problem with your code is that it makes a new copy of the complete array whenever you add an item. If you are dealing with small arrays then it is insignificant. For non-small arrays it will be too slow.

A better solution (only if you must have an array) is to use the code Mahares posted.

So what you are saying is that converting everytime a list to an array when i add a new item to a list will be faster then copy an array and add an item to it?
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
If yes then you can create a large array (1000+ items) and use this array without any copying.

This will only work if i store the "real" array size (my on runtime added items and not the in advamce setted array length) as an int to know where to add (edit) the new item. (This was my first solution but it has his disadvantages)

An array of 200 items is a small array. Your code will probably work good enoug

Thank you erel. :)

Btw (for learning purpose) what is the different between a java Arraylist and b4a list? Or is it the same ?
 
Upvote 0
Top