B4J Library [B4X] lmB4XComboBox

lmB4XComboBox is a b4x library (https://www.b4x.com/android/forum/threads/100383/#content).
It works with B4A, B4J and B4i.

It is a modified version of the Erel's original B4XComboBox and allows you to store in it a value for each text item.
Not rarely (mainly handling DB data) you need a ComboBox in which an Item is made of a display value and an associated value, i.e. a "description field" of a table and the relative primary key (usually the classic Integer ID).
Note that the type of the values associated is object, not just Int; this means that you can associate any type of value to each item.

Members added to the original View:

AddItem(Text As String)
- to add a single text item
AddItem2(Text As String, Value As Object) - to add a single item with text and value
GetItems - returns the full list of texts
GetItemText(Index As Int) - returns the text of an item
GetItemValue(Index As Int) - returns the value associated to an item
GetValues - returns all the values associated
RemoveItemByIndex(Index as Int) - removes an item
RemoveItemByText(Text As String) - removes an item
RemoveItemByValue(Value As Object) - removes an item
SetItems2(Texts As List, Values as List) - to set all items with values
SetItemsFromSQLite(...) - to fill the combo from a SQLite table
SetValue(Index as Int, Value as Object) - to set the value of a specific item


B4J Example (project attached):
1.gif


To run the example project, you need to download the Chinook_Sqlite.sqlite database from:
https://www.sqlitetutorial.net/sqlite-sample-database/
(and place it in the files folder, of course).

Version: 2.03 01/16/2023
Fixed: bug in RaiseEvent Sub

Version: 2.02 07/18/2022
Fixed: bugs related to B4I code (read from post #32)

Version: 2.01 06/15/2021
Added: Method SetItems3(Data As Map)

Version: 2.00 03/05/2021
Fixed: a bug in InsertAt (B4A version only).

Version: 1.06 02/11/2021
Changed: SetItemsFromSQLiteSorted method - Added CaseSensitive parameter.

Version: 1.05 02/06/2021
Added: SetItemsFromSQLiteSorted method.

[I was wrong to remove the previous versions of the library, now I don't know how many times it has been downloaded ??
However I see that so far the example has been downloaded 185 times, so I can guess that]


Version: 1.04 02/03/2021
Added: InsertItemAt and InsertItemAt2 methods.

Version: 1.03 02/03/2021
Fixed a (small) bug.

Version: 1.02 4/25/2020
Ammended B4i errors (reported by @Andrew (Digitwell) ; thanks)
 

Attachments

  • lmB4XComboBox_example.zip
    3.6 KB · Views: 1,019
  • lmB4XComboBox.b4xlib
    3.4 KB · Views: 657
  • lmB4XComboBox_202.zip
    3.6 KB · Views: 421
  • lmB4XComboBox_203.zip
    3.7 KB · Views: 381
Last edited:

behnam_tr

Active Member
Licensed User
Longtime User
thanks
can you add showitems method?
like showchoice in choicebox??
opening combobox list with code
 

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
Hi,
I'm trying to use this library with B4i and I run into some errors.
lmB4XComboBox - 99: Unknown member: getvalueat
lmB4XComboBox - 232: Undeclared variable 'm' is used before it was assigned any value.
lmB4XComboBox - 231: Undeclared variable 'text' is used before it was assigned any value.
lmB4XComboBox - 194: Undeclared variable 'm' is used before it was assigned any value.

Having a look at the code, it seems to be these 2 functions.
B4X:
' Adds a text item (its related value is automatically set to Null)
Public Sub AddItem(Text As String)
    #if B4J
    If cmbBox.Items.IndexOf(Text) = - 1 Then
        cmbBox.Items.Add(Text)
    End If
    #Else If B4A
        If cmbBox.IndexOf(Text) = - 1 Then
            cmbBox.Add(Text)
        End If
    #Else
        If mItems.IndexOf(Text) = - 1 Then
            m.Items.Add(Text)
        End If
    #End If
    mmapValues.Put(Text, Null)
End Sub


Public Sub RemoveItemByIndex(Index As Int)
    Dim Item As String = GetItemText(Index)
    #if B4J
    cmbBox.Items.RemoveAt(Index)
    #Else If B4A
        cmbBox.RemoveAt(Index)
    #Else
        If mItems.IndexOf(Text) = - 1 Then
            m.Items.Add(Text)
        End If
    #End If
    mmapValues.Remove(Item)
End Sub


' Gets the value of the selected index.
Public Sub getSelectedValue As Object
    Return mmapValues.GetValueAt(getSelectedIndex)
End Sub

Works great on B4a
Cheers
 

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
I have made some changes ("identified by Changes" in the code) and it now seems to work for iOS as well as B4a. Haven't tested on B4j.
 

Attachments

  • lmB4XComboBox.bas
    8.3 KB · Views: 495

LucaMs

Expert
Licensed User
Longtime User
Ok, mItems, in the original View is initialized only in AddItems, because it did not have methods like AddItem (and AddItem2).
m.Items was, of course, a "typing error", mItems is the list.

In SetItems, to this your code:
B4X:
'Change Here:
        mItems.AddAll(Texts)
        mSelectedIndex = -1
you have to prepend
mItems.Clear
because it is a SetItems, not an AddItems.
 
Last edited:

watesoft

Active Member
Licensed User
Longtime User
lmB4XComboBox is a b4x library (https://www.b4x.com/android/forum/threads/100383/#content).
It works with B4A, B4J and B4i.

It is a modified version of the Erel's original B4XComboBox and allows you to store in it a value for each text item.
Not rarely (mainly in DBs managements) you need a ComboBox in which an Item is made of a display value and an associated value, i.e. a "description field" of a table and the relative primary key (usually the classic Integer ID).
Note that the type of the values associated is object, not just Int.

Members added to the original View:

AddItem(Text As String)
- to add a single text item
AddItem2(Text As String, Value As Object) - to add a single item with text and value
GetItems - returns the full list of texts
GetItemText(Index As Int) - returns the text of an item
GetItemValue(Index As Int) - returns the value associated to an item
GetValues - returns all the values associated
RemoveItemByIndex(Index as Int) - removes an item
RemoveItemByText(Text As String) - removes an item
RemoveItemByValue(Value As Object) - removes an item
SetItems2(Texts As List, Values as List) - to set all items with values
SetItemsFromSQLite(...) - to fill the combo from a SQLite table
SetValue(Index as Int, Value as Object) - to set the value of a specific item


B4J Example (project attached):
View attachment 92483

To run the example project, you need to download the Chinook_Sqlite.sqlite database from:
https://www.sqlitetutorial.net/sqlite-sample-database/
(and place it in the files folder, of course).

Version: 1.02 4/25/2020
Ammended B4i errors (reported by @Andrew (Digitwell) ; thanks)

thanks LucaMs
can you add Hint Property? like FloatLabeledTextField.
 

Sergey_New

Well-Known Member
Licensed User
Longtime User
Please make an example for B4A.
 

Daniel44

Active Member
Licensed User
Hi everyone

LucaMs can you help me please? I'm trying to run the example but it doesn't work. I've changed the line DBFileName = "Chinook_Sqlite.sqlite" by DBFileName = "chinook.db"
and the app runs but when I clik on the combo it crashes:

Waiting for debugger to connect...
Program started.
Ha ocurrido un error en la línea: 161 (lmB4XComboBox)
java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database (no such table: Artist)
at org.sqlite.DB.newSQLException(DB.java:383)
at org.sqlite.DB.newSQLException(DB.java:387)
at org.sqlite.DB.throwex(DB.java:374)
at org.sqlite.NativeDB.prepare(Native Method)
at org.sqlite.DB.prepare(DB.java:123)
at org.sqlite.PrepStmt.<init>(PrepStmt.java:42)
at org.sqlite.Conn.prepareStatement(Conn.java:404)
at org.sqlite.Conn.prepareStatement(Conn.java:399)
at org.sqlite.Conn.prepareStatement(Conn.java:383)
at anywheresoftware.b4j.objects.SQL.ExecQuery2(SQL.java:365)
at anywheresoftware.b4j.objects.SQL.ExecQuery(SQL.java:353)
at b4j.example.lmb4xcombobox._setitemsfromsqlite(lmb4xcombobox.java:88)
at b4j.example.main._btnfillcombo_click(main.java:125)
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:498)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:632)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:234)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
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:498)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA$1.run(BA.java:216)
at com.sun.javafx.application.PlatformImpl.lambda$null$177(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$178(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$152(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)

I've already copied the chinook database to the file folder but it still not working I don't know what Im doing wrong. Thank you.
 

LucaMs

Expert
Licensed User
Longtime User
LucaMs can you help me please? I'm trying to run the example but it doesn't work. I've changed the line DBFileName = "Chinook_Sqlite.sqlite" by DBFileName = "chinook.db"
I have seen now that on that site the db is called chinook.db and I have both, this and Chinook_Sqlite.sqlite; I don't remember where I downloaded the second one from.

They are very similar but not the same. In the first one the table names are in the plural (but this also has some difference about the indices).

The example should also work, using your db version, simply by changing the table name from "Artist" to "artists" (also change the initial letter) in line 45 of the Main:
B4X:
' Change:
lmcbArtists.SetItemsFromSQLite(modDB.DB, "Artist", "Name", 15, "ArtistID", "Int")
' to:
lmcbArtists.SetItemsFromSQLite(modDB.DB, "artists", "Name", 15, "ArtistID", "Int")

and in modDB, line 21, from "Album" to "albums".
B4X:
' Change:
mQuery = $"SELECT Title FROM Album WHERE ArtistId = ${ArtistId}"$
' to:
mQuery = $"SELECT Title FROM albums WHERE ArtistId = ${ArtistId}"$

Or download Chinook_Sqlite.sqlite from here:
https://github.com/lerocha/chinook-...ookDatabase/DataSources/Chinook_Sqlite.sqlite
or:
https://github.com/JuliaDatabases/SQLite.jl/blob/master/test/Chinook_Sqlite.sqlite
 

Daniel44

Active Member
Licensed User
I have seen now that on that site the db is called chinook.db and I have both, this and Chinook_Sqlite.sqlite; I don't remember where I downloaded the second one from.

They are very similar but not the same. In the first one the table names are in the plural (but this also has some difference about the indices).

The example should also work, using your db version, simply by changing the table name from "Artist" to "artists" (also change the initial letter) in line 45 of the Main:
B4X:
' Change:
lmcbArtists.SetItemsFromSQLite(modDB.DB, "Artist", "Name", 15, "ArtistID", "Int")
' to:
lmcbArtists.SetItemsFromSQLite(modDB.DB, "artists", "Name", 15, "ArtistID", "Int")

and in modDB, line 21, from "Album" to "albums".
B4X:
' Change:
mQuery = $"SELECT Title FROM Album WHERE ArtistId = ${ArtistId}"$
' to:
mQuery = $"SELECT Title FROM albums WHERE ArtistId = ${ArtistId}"$

Or download Chinook_Sqlite.sqlite from here:
https://github.com/lerocha/chinook-...ookDatabase/DataSources/Chinook_Sqlite.sqlite
or:
https://github.com/JuliaDatabases/SQLite.jl/blob/master/test/Chinook_Sqlite.sqlite
Now It is working! thank you so much!
 
Top