B4J Question Data Entry

PatrikCavina

Active Member
Licensed User
Hi everyone, I'm trying to create a class that almost automatically produces a layout for entering data into a database. The AlternativeMap class creates a match between the name of the columns in the database and the name that you want to display, because the columns in the database do not use spaces and accents. In addition, this class creates a match between the database column name and the corresponding field.

This is AlternativeMap:
B4X:
'Decidi in che colonna tra 1 e 2 verranno contenuti gli header della atabella del db e quelle da visualizzare
Private Sub Class_Globals
    Private fx As JFX
    Type AlternativeKey(Key1 As Object, Key2 As Object)
    Private m As Map
End Sub

Public Sub Initialize
    m.Initialize
End Sub

Public Sub Put(Key As AlternativeKey, Value As Object)
    m.Put(Key,Value)
End Sub

'Vengono presi in considerazione solo i primi due elementi
Public Sub Put2(Key As List, Value As Object)
    Dim alt As AlternativeKey
    alt.Initialize
    alt.Key1 = Key.Get(0)
    alt.Key2 = Key.Get(1)
    Put(alt,Value)
End Sub

Public Sub Get(Key As AlternativeKey) As Object
    Return m.Get(Key)
End Sub

Public Sub Get2(Key As Object) As Object
    For i = 0 To m.Size-1
        Dim alt As AlternativeKey = m.GetKeyAt(i)
        If alt.Key1 = Key Or alt.Key2 = Key Then
            Return m.GetValueAt(i)
        End If
    Next
    Return Null
End Sub

Public Sub GetAlternativeKey(Key As Object) As Object
    For i = 0 To m.Size-1
        Dim alt As AlternativeKey = m.GetKeyAt(i)
        If alt.Key1 = Key Then
            Return alt.Key2
        Else If alt.Key2 = Key Then
            Return alt.Key1
        End If
    Next
    Return Null
End Sub

Public Sub GetFirstColumnKey As List
    Dim l As List
    l.Initialize
    For Each alt As AlternativeKey In m.Keys
        l.Add(alt.Key1)
    Next
    Return l
End Sub

Public Sub GetSecondColumn As List
    Dim l As List
    l.Initialize
    For Each alt As AlternativeKey In m.Keys
        l.Add(alt.Key2)
    Next
    Return l
End Sub

Sub getSize As Int
    Return m.Size
End Sub

Initializing in this way:

B4X:
dim VhDhTn as AlternativeMap
VhDhTn.Initialize

VhDhTn.Put2(Array("ID","ID"),                                            "NULL")
VhDhTn.Put2(Array("Codice","Codice"),                                     "TEXTFIELD" )
VhDhTn.Put2(Array("Descrizione","Descrizione"),                         "TEXTFIELD" )
VhDhTn.Put2(Array("Legante","Legante"),                                    "COMBOBOX" )
VhDhTn.Put2(Array("Volume","Volume"),                                     "TEXTFIELD" )
VhDhTn.Put2(Array("Area","Area"),                                         "TEXTFIELD" )
VhDhTn.Put2(Array("Concentrazione","Concentrazione"),                     "TEXTFIELD" )
VhDhTn.Put2(Array("Densità","Densita"),                                 "TEXTFIELD" )
VhDhTn.Put2(Array("Disegno","Disegno"),                                 "TEXTFIELD" )
VhDhTn.Put2(Array("Note","Note"),                                         "TEXTAREA" )
VhDhTn.Put2(Array("Corpo","Corpo"),                                     "TEXTFIELD" )
VhDhTn.Put2(Array("Stampo","Stampo"),                                     "TEXTFIELD" )
VhDhTn.Put2(Array("Tappi","Tappi"),                                     "TEXTFIELD" )
VhDhTn.Put2(Array("°C Forno","C_Forno"),                                 "TEXTFIELD" )
VhDhTn.Put2(Array("°C Stampo","C_Stampo"),                                 "TEXTFIELD" )
VhDhTn.Put2(Array("Tempo Cottura (min)","Tempo_Cottura"),                 "TEXTFIELD" )
VhDhTn.Put2(Array("Tempo Cottura Sing. (min)","Tempo_Cottura_Sing."),     "TEXTFIELD" )
VhDhTn.Put2(Array("Pressione Caldo (Kg/cm^2)","Pressione_Caldo"),         "TEXTFIELD" )
VhDhTn.Put2(Array("Pressione Freddo (Kg/cm^2)","Pressione_Freddo"),     "TEXTFIELD" )
VhDhTn.Put2(Array("Carati Totali (Kt)","Carati_Totali"),                 "TEXTFIELD" )
VhDhTn.Put2(Array("Diamante Totale (Kt)","Diamante_Totale"),             "TEXTFIELD" )
VhDhTn.Put2(Array("Tipo Diamante","Tipo_Diamante"),                     "TEXTFIELD" )
VhDhTn.Put2(Array("Grana","Grana"),                                     "TEXTFIELD" )
VhDhTn.Put2(Array("Grafite","Grafite"),                                 "TEXTFIELD" )

To convert this into a layout I created this code:
B4X:
Private Sub SetNode
    Dim ap As AlternativeMap = CurrentSettings.VhDhTn
    Dim fieldsName As List = ap.GetFirstColumnKey
    For i = 0 To fieldsName.Size-1
        Dim field As String = fieldsName.Get(i)
        Dim typeNode As Node = ConvertTextToNode(ap.Get2(field),field)
       
        Dim top As Double = 30 'Start top
        Dim height As Double = 20

        If Not(typeNode.IsInitialized) Then Continue
       
        If Nodes.Size <> 0 Then
            Dim lastNode As Node = Nodes.GetValueAt(Nodes.Size-1)
            Dim lastHeight As Double = lastNode.PrefHeight
            top = top + lastNode.Top + lastHeight
        End If
               
        Nodes.Put(field,typeNode)
       
        If typeNode Is TextArea Then
            height = 600
        End If
       
        Dim lb As Label
        lb.Initialize("")
        lb.Text = field
       
        masterPane.AddNode(lb,20,top,LargerLabelWidth,30)
        masterPane.AddNode(typeNode,LargerLabelWidth+30,top,1200,height)
    Next
    masterPane.PrefHeight = top + 50
    masterPane.PrefWidth = lastNode.PrefWidth + lastNode.Left
    Dim jo As JavaObject = scrollPane
    jo.RunMethod("setContent",Array(masterPane))
End Sub

Private Sub ConvertTextToNode(TextNode As String, Tag As String) As Node
    Dim nResult As Node
    If TextNode = "TEXTFIELD" Then
        Dim txf As TextField
        txf.Initialize("TextField")
        txf.Tag = Tag
        nResult = txf
    Else If TextNode = "COMBOBOX" Then
        Dim cmbx As ComboBox
        cmbx.Initialize("ComboBox")
        cmbx.Tag = Tag
        If Tag = "Legante" Then
            Dim legantiList As List = SQLUtils.SingleColumnResults(Main.SetLeganti.DbTableName,"Nome",True)
            cmbx.Items.AddAll(legantiList)
               
        Else If Tag = "Elementi" Then
            Dim elementiList As List = SQLUtils.SingleColumnResults(Main.SetElementi.DbTableName,"Nome",True)
            cmbx.Items.AddAll(elementiList)
               
        End If
        nResult = cmbx
    Else If TextNode = "TEXTAREA" Then
        Dim txa As TextArea
        txa.Initialize("TextArea")
        txa.Tag = Tag       
        nResult = txa
    Else If TextNode = "LABEL" Then
        Dim lb As Label
        lb.Initialize("")
        If Tag = "Data Inserimento" Or Tag = "Data Ultima Modifica" Then
            DateTime.DateFormat = "dd/MM/yyyy"
            lb.Text = DateTime.Date(DateTime.Now)
        End If
        nResult = lb
    End If
    Return nResult
End Sub

I would like to know if this method I'm using is potentially useful or just a waste of time and so if there are better methods.
I also tried using PropertySheet but the I do not like idea of writing an object in the database and the method of initialization
 

jerry07

Member
Licensed User
Longtime User
Hi Patrik,
Thank you for posting this, I do find this example interesting. Is it possibile to post complete projects even if its for first 4-5 columns?
Thank you.
 
Upvote 0

PatrikCavina

Active Member
Licensed User
Hi @jerry07,
After some tips from other users, i found a better solution.
Using Type you can made a sort of class that can own all information that you need.
I update my project creating type like:

B4X:
Type ImpostazioniCampoLayout(FiledType As String, SearchVisible As Boolean, ObligatoryInsert As Boolean, Width As Double, Height As Double, DbColumnCorrespond As String)

And put "ImpostazioniCampoLayout" in a map where key is name of field in Layout. So after if you want access to the correspond name in database you should call
DbColumnCorrespond. In layout field where there isn't corresponde to column of table, you pass null.
Attached is an example of the project I'm creating.

Open to any criticism and suggestion
 

Attachments

  • 1.zip
    18.6 KB · Views: 216
Upvote 0
Top