B4A Library [Class] Flexible Table

Mike Olmsted

Member
Licensed User
Longtime User
Set them both up in panels, then Table2_Cellclick does the job..
B4X:
pnlTable.Initialize("")
    Activity.AddView(pnlTable, 0%x, 60dip, 90%x, 70%y-60dip)   
    Table1.Initialize(Me, "Table1", 5)
    Table1.AddToActivity(pnlTable, 0, 0, pnlTable.Width, pnlTable.Height)   
   
    pnlTable2.Initialize("")
    Activity.AddView(pnlTable2, 0%x, 70%y, 90%x, 30%y)   
    Table2.Initialize(Me, "Table2", 5)
    Table2.AddToActivity(pnlTable2, 0, 0, pnlTable2.Width, 80%y)   
   
    query = "SELECT * FROM " & DBTableName
    Table1.LoadSQLiteDB(DBFileDir, DBFileName, sql1, query)
    Table1.SetColumnsWidths(Array As Int(10%x, 20%x, 20%x, 20%x, 20%x))

    query = "SELECT * FROM " & DBTableName
    Table2.LoadSQLiteDB(DBFileDir, DBFileName, sql1, query)
    Table2.SetColumnsWidths(Array As Int(10%x, 20%x, 20%x, 20%x, 0%x))
   '=================================================
Sub Table2_cellclick (Col As Int, Row As Int)
pnlTable.visible = False
pnlTable2.Top = 60dip
pnlTable2.Height = 80%y
End Sub
 

lhbrito

Member
Licensed User
Longtime User

Almost it .. I thought to use within a panel as well, but it did not work:

Scrolling the second table only works properly when it is "maximized". (In your example, after CellClick)

Comparing with Delphi: if the table has the property "Align: = alClient" work place it inside the Panel and change the size / position of the panels.

But thanks, I'll do some other tests.
 

lhbrito

Member
Licensed User
Longtime User
Not in the current version, it would need to these properties in the Class code.

Ok

I made some changes in the class and in my tests it worked.

Added methods: SetLeft, SetTop, SetWidth, SetHeight, GetLeft, GetTop, GetWidth and GetHeight

If useful, feel free to add in a future version.

Thank you!

B4X:
Public Sub GetLeft As Int
   Return pnlTable.Left
End Sub

Public Sub GetTop As Int
   Return pnlTable.Top
End Sub

Public Sub GetWidth As Int
   Return pnlTable.Width
End Sub

Public Sub GetHeight As Int
   Return pnlTable.Height
End Sub

Public Sub SetLeft(Left As Int)
   pnlTable.Left = Left
End Sub

Public Sub SetTop(Top As Int)
   pnlTable.Top = Top
End Sub

Public Sub SetWidth(Width As Int)
   pnlTable.Width = Width
   SV.Width = Width
   internalPanel.Width = Width
   updateIPLocation
End Sub   

Public Sub SetHeight(Height As Int)
   pnlTable.Height = Height
   If (showStatusLine = True) Then
     SV.Height = Height - (cRowHeight * 2)
   Else
     SV.Height = Height - (cRowHeight)   
   End If
   lblStatusLine.Top = SV.Top + SV.Height
   updateIPLocation
End Sub
 

enrico

Active Member
Licensed User
Longtime User
To me Table1.29 example stops in line 153 -> bmp.InitializeMutable(1dip, 1dip)

with error ->
java.lang.IllegalArgumentException: width and height must be > 0

But it happens in Android 2.2 emulator and not in Android 2.3.3 where it works ok
 
Last edited:

enrico

Active Member
Licensed User
Longtime User
String sorting is not good for numeric fields.
I think we need to specify in some way which fields are numeric and sort them in a different and right mode.
 

enrico

Active Member
Licensed User
Longtime User
Ansewer to post #85
Strange.
I tried it with an Android 2.2 Emulator and it works without any error.
My Android Manager is version 22.3

I don't know but I was trying my modified project with Android 2.2 emulator and couldn't understand the problem.
So after lots of tests I tried the example and I got the same error.

Trying now with Android 4.0.3 and it works.
 

enrico

Active Member
Licensed User
Longtime User
Can you help me in sorting columns populated by numbers ?
Do you think this class could be implemented for it or I have to try in other way ?
 

enrico

Active Member
Licensed User
Longtime User
I modified headers to have the text in two rows separated by a CR and it works.
But how can I adjust columns width, calculating only the longer of the two rows (now it considers all the text of the header).
I think I have to alter SetHeader Sub, but I don't know how to achieve it (and if it's possible).
 

klaus

Expert
Licensed User
Longtime User
I suppose you are using AutomaticWidths.
In the SetHeader routine replace
B4X:
If cAutomaticWidths = True Then
    HeaderWidths(i) = Max(HeaderWidths(i),cvs.MeasureStringWidth(str(j), l.Typeface, cTextSize)  + 8dip)
by this
B4X:
If cAutomaticWidths = True Then
    If Values(i).Contains(CRLF) Then
        Dim str() As String
        Dim j As Int
        str = Regex.Split(CRLF, Values(i))
        HeaderWidths(i) = cvs.MeasureStringWidth(str(0), l.Typeface, cTextSize)  + 8dip
        For j = 1 To str.Length - 1
            HeaderWidths(i) = Max(HeaderWidths(i),cvs.MeasureStringWidth(str(j), l.Typeface, cTextSize)  + 8dip)
        Next
    Else
        HeaderWidths(i) = cvs.MeasureStringWidth(Values(i), l.Typeface, cTextSize)  + 8dip 
    End If
Do you change the row height ?
 

enrico

Active Member
Licensed User
Longtime User
Wonderful ! Thanks.

(Row height changed to 40dip to fit the two rows)

Another thing I think it would make it better is to set all cell labels at least 1 pixel far from cell margins.
 
Last edited:

enrico

Active Member
Licensed User
Longtime User
I modified sorting routine to manage columns with numbers :

B4X:
Public Sub SelectionSort (col As Int,dir As Boolean)
    Dim minIndex As Int
    For i = 0 To Data.Size - 1
        minIndex = i
        For j = i + 1 To Data.Size - 1
            Dim values1() As String = Data.get(j)
            Dim values2() As String = Data.get(minIndex)
            If col=0 OR col=25 OR col=27 Then        'These are columns with strings
                Dim s1 As String = values1(col)
                Dim s2 As String = values2(col)
                If (dir) Then
                    If s1.CompareTo(s2) < 0 Then minIndex = j
                Else
                    If s1.CompareTo(s2) > 0 Then minIndex = j
                End If
            Else                                        'Numeric Sorting
                Dim n1 As Float
                Dim n2 As Float
                If IsNumber(values1(col).Replace(",","")) Then n1 = values1(col).Replace(",","") Else n1 = 0
                If IsNumber(values2(col).Replace(",","")) Then n2 = values2(col).Replace(",","") Else n2 = 0
                If (dir) Then
                    If n1 < n2 Then minIndex = j
                Else
                    If n1 > n2 Then minIndex = j
                End If
            End If
        Next
        SwapList(i, minIndex)
    Next
End Sub

Unfortunately the process is very much slower then with strings
 

enrico

Active Member
Licensed User
Longtime User
I was wondering if it can be possible to fix the first column of the table, like in Excel for example
 

vecino

Well-Known Member
Licensed User
Longtime User
Hello, to sort numeric columns would need to do something similar to the alignment and width each column: indicate if the column is string or numeric

Regards.
 

enrico

Active Member
Licensed User
Longtime User
I have a strange problem.

Only on a tablet with Android 4.1.2 I get this error :
An error has occurred in sub:table_initialize (java line: 845)
java.lang.IllegalArgumentException: width and height must be > 0

Continuing with "Yes" I get this :
An error has occurred in sub:table_updateiplocation (java line: 2540)
java.lang.NullPointerException

On all other devices I tried, it works without errors.
 

slugger

Member
Licensed User
Longtime User
Hello,

I am triyng to use the library, specifically the LoadTableFromCSV/SaveTableToCSV.

I have a csv file with no headers so I use FALSE as the HeaderExist parameter.

The problem is the SaveTableToCSV counterpart always adds the headers to the csv file on disc, this way each time I save the file a new record is added at the beginning of the csv file containing "Col1","Col2", and so on.

After 5 SaveTableToCSV commands I have 5 new records all with "Col1","Col2", and so on.

Can you please add a way to save to csv without the headers?
 

slugger

Member
Licensed User
Longtime User
I modified your source code by myself, I changed the

StringUtils1.SaveCSV2(Dir, Filename, ",", Data, headers)

to

StringUtils1.SaveCSV(Dir, Filename, ",", Data)
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…