B4J Question TableView cell alignment and color

BPak

Active Member
Licensed User
Longtime User
Have built a program and managed to center all the cells of the TableView.

.table-column .cell {
-fx-alignment: CENTER;
}
However, I would like to be able to set the columns to different alignment and colors.

My search has not found anything other than Cell Factories or something like that used in NetBeans??

Anyone have any CSS that might work out this problem for me?
 

Attachments

  • dpro.PNG
    65.9 KB · Views: 2,050

Erel

B4X founder
Staff member
Licensed User
Longtime User
TableView (like ListView) allows you to add Nodes instead of strings. This way you can fully customize it.

B4X:
Sub AppStart (Form1 As Form, Args() As String)
   MainForm = Form1
   'MainForm.RootPane.LoadLayout("1") 'Load the layout file.
   MainForm.Show
   tv.Initialize("tv")
   MainForm.RootPane.AddNode(tv, 0, 0, 250, 250)
   tv.SetColumns(Array As String("col1", "col2"))
   For i = 1 To 100
     Dim lbl1, lbl2 As Label
     lbl1.Initialize("")
     lbl2.Initialize("")
     lbl1.Text = i
     lbl2.Text = i
     lbl1.Font = fx.DefaultFont(Rnd(10, 20))
     lbl2.Font = fx.DefaultFont(Rnd(10, 20))
     lbl1.TextColor = fx.Colors.From32Bit(Rnd(0x80000000, -1))
     lbl2.TextColor = fx.Colors.From32Bit(Rnd(0x80000000, -1))
     tv.Items.Add(Array As Object(WrapLabel(lbl1, "CENTER") , _
       WrapLabel(lbl2, "CENTER_RIGHT")))
   Next
End Sub

Sub WrapLabel(lbl As Label, Alignment As String) As Pane
   Dim pn1 As AnchorPane
   pn1.Initialize("")
   pn1.AddNode(lbl, 0, 0, -1, -1)
   pn1.FillHorizontally(lbl, 0, 0)
   Dim jo1 = lbl As JavaObject
   jo1.RunMethod("setAlignment", Array As Object(Alignment))
   Return pn1
End Sub

 
Upvote 0

tcgoh

Active Member
Licensed User
Longtime User
Sorry I'm not familiar with node. Is there a way to change the color of a table cell or color of a row?
Thanks
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
There is probably a better solution using JavaObject and a custom style sheet.

By changing the label style you can achieve this result:


B4X:
Sub AppStart (Form1 As Form, Args() As String)
  MainForm = Form1
  'MainForm.RootPane.LoadLayout("1") 'Load the layout file.
  MainForm.Show
  tv.Initialize("tv")
  MainForm.RootPane.AddNode(tv, 0, 0, 250, 250)
  tv.SetColumns(Array As String("col1", "col2"))
  For i = 1 To 100
  Dim lbl1, lbl2 As Label
  lbl1.Initialize("")
  lbl2.Initialize("")
  lbl1.Text = i
  lbl2.Text = i
  lbl1.Font = fx.DefaultFont(Rnd(10, 20))
  lbl2.Font = lbl1.Font
    Dim color As String
    If i Mod 2 = 0 Then color = "palegreen" Else color = "skyblue"
    lbl1.Style = "-fx-background-color: " & color & ";"
    lbl2.Style = "-fx-background-color: " & color & ";"
  tv.Items.Add(Array As Object(WrapLabel(lbl1, "CENTER") , _
  WrapLabel(lbl2, "CENTER_RIGHT")))
  Next
End Sub
 
Upvote 0

Yafuhenk

Active Member
Licensed User
Longtime User
Hi

I added the wraplabel sub to DBUtils and this works. The thing that I can't figure out is what I should do when the number of columns are flexible (between 2 and 10) and the number of columns which should be aligned "CENTER_RIGHT" can vary from 1 to 4

Can some one give me a hint how to go on?

Thanks

B4X:
Public Sub ExecuteTableView(SQL As SQL, Query As String, StringArgs() As String, Limit As Int, TableView1 As TableView)
    TableView1.Items.Clear
    Dim cur As ResultSet
    If StringArgs = Null Then
        Dim StringArgs(0) As String
    End If
    cur = SQL.ExecQuery2(Query, StringArgs)
    Dim cols As List
    cols.Initialize
    For i = 0 To cur.ColumnCount - 1
        cols.Add(cur.GetColumnName(i))
    Next
    TableView1.SetColumns(cols)
    Do While cur.NextRow
        Dim values(cur.ColumnCount) As Label
        For col = 0 To cur.ColumnCount - 1
            values(col).Initialize("")
            values(col).Text = cur.GetString2(col)
        Next
        TableView1.Items.Add(Array As Object(values(0), WrapLabel(values(1), "CENTER_RIGHT")))
        If Limit > 0 AND TableView1.Items.Size >= Limit Then Exit
    Loop
    cur.Close
 
End Sub
 
Sub WrapLabel(lbl As Label, Alignment As String) As Pane
  Dim pn1 As AnchorPane
  pn1.Initialize("")
  pn1.AddNode(lbl, 0, 0, -1, -1)
  pn1.FillHorizontally(lbl, 0, 0)
  Dim jo1 = lbl As JavaObject
  jo1.RunMethod("setAlignment", Array As Object(Alignment))
  Return pn1
End Sub
 
Upvote 0

Yafuhenk

Active Member
Licensed User
Longtime User
Hi Erel,

Thanks for your hint.
If that would work I know how to continue. However when I use that code the tableview fills with text like this '(AnchorPane)AnchorPane@12ef89e40)'
- Log(lbl.Text) shows the correct values -

B4X:
Public Sub ExecuteTableView(SQL As SQL, Query As String, StringArgs() As String, Limit As Int, TableView1 As TableView)
    TableView1.Items.Clear
    Dim cur As ResultSet
    If StringArgs = Null Then
        Dim StringArgs(0) As String
    End If
    cur = SQL.ExecQuery2(Query, StringArgs)
    Dim cols As List
    cols.Initialize
    For i = 0 To cur.ColumnCount - 1
        cols.Add(cur.GetColumnName(i))
    Next
    TableView1.SetColumns(cols)
    Do While cur.NextRow
        Dim values(cur.ColumnCount) As Pane
        For col = 0 To cur.ColumnCount - 1
            Dim lbl As Label
            lbl.Initialize("")
            lbl.Text = cur.GetString2(col)
            Log(lbl.Text)
            values(col) = WrapLabel(lbl, "CENTER_RIGHT")
        Next
        TableView1.Items.Add(values)
        If Limit > 0 AND TableView1.Items.Size >= Limit Then Exit
    Loop
    cur.Close
End Sub
 
Sub WrapLabel(lbl As Label, Alignment As String) As Pane
  Dim pn1 As AnchorPane
  pn1.Initialize("")
  pn1.AddNode(lbl, 0, 0, -1, -1)
  pn1.FillHorizontally(lbl, 0, 0)
  Dim jo1 = lbl As JavaObject
  jo1.RunMethod("setAlignment", Array As Object(Alignment))
  Return pn1
End Sub
 

Attachments

  • 2014-01-07 22_04_33-Easy4Sales.png
    57.6 KB · Views: 1,143
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
I may be completely wrong but shouldn't

Dim jo1 = lbl As JavaObject

be

Dim jo1 As JavaObject = lbl
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I may be completely wrong but shouldn't

Dim jo1 = lbl As JavaObject

be

Dim jo1 As JavaObject = lbl
It doesn't matter. They are the same.

The first syntax is useful when you want to declare and assign multiple values:
B4X:
Dim i1 = 3, i2 = 443, i3 = 23 As Int

About the table issue, can you upload the project?
 
Upvote 0

Theera

Well-Known Member
Licensed User
Longtime User
Hi all,
In post #9 ,Please someone give me a full program,I don't understand. Thank you.
 
Upvote 0

Yafuhenk

Active Member
Licensed User
Longtime User
Hi Theera,

Can't post the whole project, sorry, but I can explain what works for me.
I create tables with Erel's DBUtils with the sub ExecuteTableview.
By adding some code and the sub wraplabel you can align the columns
Here is an example

B4X:
Public Sub ExecuteTableView(SQL As SQL, Query As String, StringArgs() As String, Limit As Int, TableView1 As TableView)
    TableView1.Items.Clear
    Dim cur As ResultSet
    If StringArgs = Null Then
        Dim StringArgs(0) As String
    End If
    cur = SQL.ExecQuery2(Query, StringArgs)
    Dim cols As List
    cols.Initialize
    For i = 0 To cur.ColumnCount - 1
        cols.Add(cur.GetColumnName(i))
    Next
    TableView1.SetColumns(cols)
    Do While cur.NextRow
        Dim values(cur.ColumnCount) As Object
        For col = 0 To cur.ColumnCount - 1
            Dim lbl As Label
            lbl.Initialize("")
            lbl.Text = cur.GetString2(col)
            If IsNumber(lbl.Text) Then
                values(col) = WrapLabel(lbl, "CENTER_RIGHT")
            Else
                values(col) = WrapLabel(lbl, "CENTER_LEFT")
            End If
        Next
        TableView1.Items.Add(values)
        If Limit > 0 AND TableView1.Items.Size >= Limit Then Exit
    Loop
    cur.Close
End Sub

Sub WrapLabel(lbl As Label, Alignment As String) As Pane
  Dim pn1 As AnchorPane
  pn1.Initialize("")
  pn1.AddNode(lbl, 0, 0, -1, -1)
  pn1.FillHorizontally(lbl, 0, 0)
  Dim jo1 = lbl As JavaObject
  jo1.RunMethod("setAlignment", Array As Object(Alignment))
  Return pn1
End Sub

Hope this helps

Regards
 
Upvote 0

fernando gibert

Member
Licensed User
Longtime User
Pls!

In Erel's example : how shall the log ""CENTER" or "CENTER_RIGHT" be avoid .

Wraplabel sub shows these constants for each shown line.

Thanks
 
Upvote 0

tsteward

Well-Known Member
Licensed User
Longtime User
if I use the above code to justify my labels in my tableview how to I retreive and set the label data.

Before i could
B4X:
Sub QuoteTV_SelectedRowChanged(Index As Int, Row() As Object)
    If Index > -1 Then
        Dim lbl1 As Label = Row(0)
        QtyText.Text = lbl1.Text
        Dim lbl2 As Label = Row(1)
        DescText.Text = lbl2.Text
        Dim lbl3 As Label = Row(2)
        PriceText.Text = lbl3.Text
    End If
End Sub

But this now fails
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…