B4J Question B4XTable FrozenColumns at right?

JohnJ

Member
Licensed User
Longtime User
Is there a simple way to set the FrozenColumns at the right side of B4XTable instead of left?
Can you load the columns in reverse order and freeze the left? Not all data would support this arrangement but just a thought.
 
Upvote 0

JohnJ

Member
Licensed User
Longtime User
I am not sure what you mean. A sample code would help.
Instead of loading the columns in order of 1,2,3...9 load them as 9,8,7...1. It depends on what your data looks like, it may not make sense to order it like that.
Just a thought.
 
Upvote 0

teddybear

Well-Known Member
Licensed User
He meant that you can arrange the columns at right to the left
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
s there a simple way to set the FrozenColumns at the right side of B4XTable instead of left?
Instead of loading the columns in order of 1,2,3...9 load them as 9,8,7...1
He meant that you can arrange the columns at right to the left
If John's and Ted's suggestion suits you and does not make things worse, here is the code you need to reverse the order of the columns and freeze:
B4X:
For i= B4XTable1.Columns.Size-1 To 0 Step -1
        Dim c As B4XTableColumn = B4XTable1.Columns.Get(i)
'        Log(c.Id)
        B4XTable1.VisibleColumns.RemoveAt(B4XTable1.VisibleColumns.IndexOf(c))
        B4XTable1.VisibleColumns.InsertAt(B4XTable1.Columns.Size-1, c)
    Next
    B4XTable1.Refresh
    B4XTable1.NumberOfFrozenColumns = 2
 
Upvote 0

JohnJ

Member
Licensed User
Longtime User
If John's and Ted's suggestion suits you and does not make things worse, here is the code you need to reverse the order of the columns and freeze:
B4X:
For i= B4XTable1.Columns.Size-1 To 0 Step -1
        Dim c As B4XTableColumn = B4XTable1.Columns.Get(i)
'        Log(c.Id)
        B4XTable1.VisibleColumns.RemoveAt(B4XTable1.VisibleColumns.IndexOf(c))
        B4XTable1.VisibleColumns.InsertAt(B4XTable1.Columns.Size-1, c)
    Next
    B4XTable1.Refresh
    B4XTable1.NumberOfFrozenColumns = 2
I think an easier way to do this would be to reverse the order of your sql statement.
Instead of saying select cola,colb,colc from sometable
say select colc,colb,cola from sometable
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
Any comment on post #6. It is uncharacteristic of you not to fully address your thread till the end. Otherwise, we like to see how you solved it.
Sorry, I was busy with other stuff.
I try to add your sample code but no success.
I don't really understand how to use the code. Is it added after I created the usual table?
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
As you can see from the illustration below, the Frozen Columns are still at the left side. I know I can show the columns by adding them in my preferred order but I want to freeze the last column so it cannot be scrolled.

1677779200681.png
 

Attachments

  • FrozenColumnsDemo.zip
    2.7 KB · Views: 107
Upvote 0

Mahares

Expert
Licensed User
Longtime User
As you can see from the illustration below, the Frozen Columns are still at the left side.
The code I inserted freezes the columns on the left only and it is placed after the table is loaded with the list data in the normal way: B4XTable1.SetData(data). You have added it correctly in your project. It appears that the code does not address what you want, if you want to freeze the right columns. I thought perhaps it is something you want as a temporary data view without having to create a new SQL select query to reverse the order of the columns. Please request that Erel sees this thread and he may have the solution you want. I am going to play with your project a little more anay way as it is interesting.

Instead of saying select cola,colb,colc from sometable
say select colc,colb,cola from sometable
The reason for my code is it runs faster than having to recreate the entire select query becayuse it only changes the visible page data at a time and you do not have to clear the table.
 
Last edited:
Upvote 0

JohnJ

Member
Licensed User
Longtime User
As you can see from the illustration below, the Frozen Columns are still at the left side. I know I can show the columns by adding them in my preferred order but I want to freeze the last column so it cannot be scrolled.

View attachment 139871

B4xTable is an internal library so I guess you would have to get into the code to change freezing columns from left to right. Or maybe add a parm to indicate left or right. But that's probably not going to happen.
So what I did is to add another table that contains columns D and E. Both tables are on a pane. I haven't figured how to remove the position arrows on table 2. If you click on a position arrow on table 1 table2 will change also in the dataupdated sub by using the currentpage parm from table 1.
Also I haven't figured the search function. The dataupdated sub fires here also.

1677791598050.png
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
add a parm to indicate left or right
Yes, this is what I am trying to do.
Without well understanding how the code works, it is not an easy task to modify the library.
Instead of counting from 0, I need to count from size of visible columns minus frozen columns.

B4X:
Public ShowFrozenColumnAtRight As Boolean

B4X:
If ShowFrozenColumnAtRight Then
    IsFrozen = ColumnIndex > VisibleColumns.Size - NumberOfFrozenColumns
Else
    IsFrozen = ColumnIndex < NumberOfFrozenColumns
End If

There are other logic such as RemoveColumnFromCLV, InsertAt and dealing with offset.

B4X:
RemoveColumnFromCLV(c)
clvData.InsertAt(CLVIndex, c.Panel, c)

B4X:
#if B4J
Dim offset As Float = 1
#else
Dim offset As Float = 0
#end if
c.Panel.SetLayoutAnimated(0, offset + FreezedWidth, clvData.AsView.Top + offset, c.ComputedWidth, clvData.AsView.Height)

This is a challenging task for me. The easiest or lazy way is to make a wish. 😅
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
It looks like the resize routine assumes the frozen columns are on the left.
B4X:
    Dim i As Int = NumberOfFrozenColumns
    Do While i < VisibleColumns.Size

You prob need something like
B4X:
Dim i As Int
Dim ColMax As Int
if (FreezeRight) then  ' some boolean to denote you freeze right cols
i = 0
ColMax = VisibleColumns.Size - NumberOfFrozenColumns
Else
i = NumberOfFrozenColumns
ColMax = VisibleColumns.Size
End If
Do While i < ColMax
...

Not tested Btw.
 
Last edited:
Upvote 0

PaulMeuris

Active Member
Licensed User
Starting from your FrozenColumnsDemo2.zip i managed to find a solution to your problem with the B4XTable frozen right column.
In the Main module i added this code:
B4J Main module:
Public Sub Main_Resize
    ' reposition the Edit column
    B4XTable1.GetColumn("Edit").Panel.Left = B4XTable1.clvData.AsView.Left + B4XTable1.clvData.AsView.Width
    ' adjust width of the last column when resizing to the right
    ' -3 => column1 removed, edit column, index start at 0
    B4XTable1.clvData.ResizeItem(B4XTable1.Columns.Size-3, B4XTable1.GetColumn("Column A").Panel.Width)
End Sub
I switched to the SQLite library that is on my computer:
B4X:
#AdditionalJar: sqlite-jdbc-3.7.2
And in the B4XTable class i added a call to the subroutine Main_Resize at the end of the subroutine ResizeAndReorderCLVItems:
B4X:
Private Sub ResizeAndReorderCLVItems
...
    Main.Main_Resize
End Sub
This is the result when resizing the form to the right:
1677924976944.png

And this is how it looks when resizing to the left:
1677925036633.png

Note: i have only tested this in B4J.
In the attached zip-file you can find my version based on your work (and the other contributors to this thread).
Happy coding!
P.S. you can block the resizing with this code (uncomment the line #5):
B4X:
Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("1")
    MainForm.Show
    'MainForm.Resizable = False
 

Attachments

  • FrozenColumnsDemo_paul.zip
    13.3 KB · Views: 96
Last edited:
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Really Good job @aeric and @PaulMeuris in modifying the class . That is what a team work leads to. I have carried out Paul's example a little further by resizing and spreading the views and spacing inside the Edit column depending on the width of the column. If there is interest in seeing it, I can post a code. Here iare below a screenshot with resizing views and one without for a column width of 230 dip instead of 130 dip

1677931368150.png


1677931811508.png
 
Upvote 0

JohnJ

Member
Licensed User
Longtime User
Starting from your FrozenColumnsDemo2.zip i managed to find a solution to your problem with the B4XTable frozen right column.
In the Main module i added this code:
B4J Main module:
Public Sub Main_Resize
    ' reposition the Edit column
    B4XTable1.GetColumn("Edit").Panel.Left = B4XTable1.clvData.AsView.Left + B4XTable1.clvData.AsView.Width
    ' adjust width of the last column when resizing to the right
    ' -3 => column1 removed, edit column, index start at 0
    B4XTable1.clvData.ResizeItem(B4XTable1.Columns.Size-3, B4XTable1.GetColumn("Column A").Panel.Width)
End Sub
I switched to the SQLite library that is on my computer:
B4X:
#AdditionalJar: sqlite-jdbc-3.7.2
And in the B4XTable class i added a call to the subroutine Main_Resize at the end of the subroutine ResizeAndReorderCLVItems:
B4X:
Private Sub ResizeAndReorderCLVItems
...
    Main.Main_Resize
End Sub
This is the result when resizing the form to the right:
View attachment 139921
And this is how it looks when resizing to the left:
View attachment 139922
Note: i have only tested this in B4J.
In the attached zip-file you can find my version based on your work (and the other contributors to this thread).
Happy coding!
P.S. you can block the resizing with this code (uncomment the line #5):
B4X:
Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("1")
    MainForm.Show
    'MainForm.Resizable = False
Nice, works great!
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
B4X:
Public Sub Main_Resize
    ' reposition the Edit column
    B4XTable1.GetColumn("Edit").Panel.Left = B4XTable1.clvData.AsView.Left + B4XTable1.clvData.AsView.Width
    ' adjust width of the last column when resizing to the right
    ' -3 => column1 removed, edit column, index start at 0
    B4XTable1.clvData.ResizeItem(B4XTable1.Columns.Size-3, B4XTable1.GetColumn("Column A").Panel.Width)
End Sub

As I used B4XTable1.NumberOfFrozenColumns = 1 in my demo, the code works but it is not supporting 2 and above columns.
 
Upvote 0
Top