B4J Question Sorting TreeTableView

Robert Valentino

Well-Known Member
Licensed User
I have a TreeTableView that has 1 column (but the column is actually a Label so the default sorting isn't working properly)

Is there a way I can trap the column header click and sort this manually?

Also I have (I guess it is a hidden column, can I sort on that)

When I create my TreeTableItem in the column array the first entry is the Label (that displays) and the second entry is just the data (but there is no actual column displayed to the user - ONLY 1 column created with designer)

B4X:
Dim Item as TreeTableItem
Item.Initialize("", Array As Object(CreateTextLabel("Hi There"), "Hi There")    '  <---- Second "Hi There" is just a string that doesn't show because I only want 1 column to show
Is there a way I can Sort on the hidden column (data)?

UPDATED:

Dumping the Children list it says:
B4X:
Entry:0  Data:TreeItem [ value: [Lanywheresoftware.b4j.objects.TreeTableViewWrapper$TreeTableColType;@565017ea ]
What are the field names in TreeTableColType (types have fields that can be sorted on?)


BobVal
 
Last edited:

Erel

Administrator
Staff member
Licensed User
You will need to sort the items yourself, by removing the items and adding them back in the correct order.

Intercepting the header click event:
B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private xui As XUI 
    Private Button1 As B4XView
    Private TreeTableView1 As TreeTableView
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.Show
    Dim parent As TreeTableItem = TreeTableView1.Root
    TreeTableView1.SetColumnSortable(0, False)
    TreeTableView1.SetColumnSortable(1, False)
    For i = 1 To 10
        Dim t As TreeTableItem
        t.Initialize("", Array(Rnd(1, 100), Rnd(1, 100), Rnd(1, 100)))
        parent.Children.Add(t)
    Next
    Dim r As Reflector 'jReflection library
    r.Target = TreeTableView1
    r.AddEventFilter("TreeTableView", "javafx.scene.input.MouseEvent.MOUSE_CLICKED")
End Sub
Sub TreeTableView_Filter(e As Event)
    Dim jo As JavaObject = e
    Dim target As B4XView = jo.RunMethod("getTarget", Null)
    Do While target.IsInitialized
        If GetType(target) = "javafx.scene.control.skin.TableColumnHeader" Then
            jo = target
            Dim children As List = jo.RunMethod("getChildrenUnmodifiable", Null)
            For Each c As B4XView In children
                If c Is Label Then
                    TreeHeaderClicked(c.Text)
                End If
            Next
            e.Consume
        End If
        target = target.Parent
    Loop
End Sub

Sub TreeHeaderClicked (ColumnTitle As String)
    Log("Click: " & ColumnTitle)
End Sub
 

Robert Valentino

Well-Known Member
Licensed User
Not sure why but my getTarget is returning:
B4X:
"com.sun.javafx.scene.control.skin.TableColumnHeader"
Instead of
B4X:
"javafx.scene.control.skin.TableColumnHeader"
Seems all my stuff starts with "com.sun."

But when I make that changes I do get the column click
 

stevel05

Expert
Licensed User
I presume you are using Java 8. Change the line to check for both:
B4X:
If GetType(target) = "javafx.scene.control.skin.TableColumnHeader" Or GetType(target) = "com.sun.javafx.scene.control.skin.TableColumnHeader" Then
Or
B4X:
If GetType(target).EndsWith("javafx.scene.control.skin.TableColumnHeader") Then
To work with Java 8 & Java 11+.
 

Robert Valentino

Well-Known Member
Licensed User
You are right. I am using 8 for this App

Because on 11 my data displays like this
1603413528037.png


On 8 it looks like it should.

1603413635066.png


I know different problem. Will look for that answer after I have the app running like I want
 
Top