B4J Question Tableview Frustration

GuyBooth

Active Member
Licensed User
Longtime User
I am trying to use a tableview for updating a small amount of data. To do this, I need to "mark" the rows with different colors, and "grey out" some of them when changes have been completed.

I have installed TableViewExtended, and after reading everything I can find in the forums and documentation have found out how to do everything I need provided I click on the rows that have to be changed - but I need to change some rows programmatically.

Is there any way at all to address an individual row, or cell, without clicking on it? I want to write something like:
B4X:
tblview.Row(x).Style = "-fx-background-color: Cyan;"
But this isn't legitimate. Cellfactory in the TableViewExtension would also work except the only way I can find to address a cell is by clicking on it. I need to address it programmatically.
Any help appreciated!
 

Teech

Member
Licensed User
Longtime User
A TableView is a List of Array: every ListItem is a row and every ArrayItem is a Cell in the row.
In the Array you can insert object, so you are very free.

I attach an example to manage a Tableview

For convenience I use a simple class
B4X:
Sub Class_Globals
    Private fx As JFX

    'Property
    Private mCode As Int=0
End Sub

#Region "Properties"
Public Sub Code As Int
    Return mCode
End Sub

Public Sub Description As String
    Return $"Description${mCode}"$
End Sub

#End Region

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(id As Int)
    mCode=id
End Sub

Here a simple to draw a TableView
B4X:
Sub AppStart (Form1 As Form, Args() As String)
    mList.Initialize
    mRows.Initialize
    For i=1 To 20
        Dim c As Component
        c.Initialize(i)
        mList.Add(c)
    Next

    MainForm = Form1
    MainForm.RootPane.LoadLayout("1") 'Load the layout file.
    MainForm.Show
   
    DrawTablaView
End Sub

'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub

Private Sub DrawTablaView
    'Columns Tableview
    Dim columns() As String=Array As String("Code","Description")
    Dim columnsSize As Map
    columnsSize.Initialize
    columnsSize.Put(0,100) 'Code
    columnsSize.Put(1,tv.PrefWidth-100) 'Description
       
    'Draw Columns
    tv.Items.Clear
    mRows.Clear
    tv.SetColumns(columns)
    For Each col In columnsSize.Keys
        tv.SetColumnSortable(col,False)
        tv.SetColumnWidth(col,columnsSize.Get(col))
    Next

    For Each c As Component In mList
        Dim row(columns.Length) As Object
        RowBuilder(row,c)
        tv.Items.Add(row)
    Next
End Sub

Private Sub RowBuilder(row() As Object, c As Component)
    For i=0 To row.Length-1
        Select Case i
            Case 0 'Code
                Dim lb As Label
                lb.Initialize("lbCode")
                lb.Text=NumberFormat(c.Code,1,0)
                lb.Tag=c
                row(i)=WrapControl(lb)
                If (c.Code Mod 3)=0 Then CSSUtils.SetBackgroundColor(lb,fx.Colors.Green) 'Change backgroundcolor programmatically
            Case 1
                Dim tf As TextField
                tf.Initialize("tfDescription")
                tf.Text=c.Description
                tf.Tag=c
                row(i)=WrapControl(tf)
                If (c.Code Mod 3)=0 Then CSSUtils.SetBackgroundColor(tf,fx.Colors.Green) 'Change backgroundcolor programmatically
        End Select
    Next
    mRows.Put(c,row)
End Sub

Sub WrapControl(control As Object) As Pane
    Dim pn As AnchorPane
    pn.Initialize("")
    pn.AddNode(control, 0, 0, -1, -1)
    pn.FillHorizontally(control, 0, 0)
    pn.FillVertically(control,0,0)
    Return pn
End Sub

Private Sub tfDescription_FocusChanged (HasFocus As Boolean)
    If HasFocus Then
        Dim tf As TextField=Sender
        tv.SelectedRow=RowIndexFromComponent(tf.tag)
    End If
End Sub

Private Sub RowIndexFromComponent(c As Component) As Int
    Dim ret As Int=-1
    ret=tv.Items.IndexOf(mRows.Get(c))
    Return ret
End Sub
 
Upvote 0

GuyBooth

Active Member
Licensed User
Longtime User
Unfortunately, this approach still doesn't allow me to change the background color of the rows in the tableview itself. Even though the panes are anchor panes they leave gaps - the result (attached) is not particularly attractive.

Is there some way to make the panes completely fill the rows of the tableview? Am I missing something?
 

Attachments

  • TableView.PNG
    TableView.PNG
    76.5 KB · Views: 136
Upvote 0

GuyBooth

Active Member
Licensed User
Longtime User
It might be possible with a CSS file. Can you upload a small program with the code that creates the table?
I think I found a way to do it by creating my own index of cells in a map while the data is being added, adding the Cells created in CellFactory events of the TableViewExtension library. There are complications when the table is scrolled beyond the cells that are recycled, but I think I could get there … except in working through this I'm not sure that I need to get that complicated. I'm opening another couple of threads to discuss changing the selection bar/colors, which may be all I need, and multiple selection via programming which would be nice to see.
 
Upvote 0
Top