B4J Question How to show progress with class

derez

Expert
Licensed User
Longtime User
I want to add a progress indicator to the treeview class. This application has a mainform and two classes - treepane and treenode.
When I want a tree to be drawn I press a button on main, this creates a treepane object and that one calls the treenode to populate the tree.
With the method OpenAll the process may take few seconds, so I wanted to add a progress indicator (or just a label) to let the user know that the app is running.
What you see in this process is the main form until the tree is completed. I added the progress indicator to the main, not visible until the tree button is pressed and then visible but it does not show at all.
I tried to bring it to the front after adding the tree object but still it does not show until the tree is completed (and this is too late of course).
Advice ?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You cannot show (or update) anything while the main thread is busy with opening the tree nodes.

A possible solution is to split the task into smaller tasks and use CallSubDelayed to start the first task and later when it completes start the next task (with CallSubDelayed again).
This will allow the main thread to process the message queue and keep the app responsive.
 
Upvote 0

derez

Expert
Licensed User
Longtime User
It is so simple when you know the right direction...
Thank you !
B4X:
Sub tree_Action
waitlbl.Visible = True 
CallSubDelayed(Me,"tree_continue") 
End Sub

Sub tree_continue
(build the tree)
waitlbl.visible = false
end sub

BUT: it works in debug, not in release (works but not showing the label...)
making the first line as sub and calldelayed it does not change it.
 
Last edited:
Upvote 0

derez

Expert
Licensed User
Longtime User
Solved by using a timer of 10 msec (2 were not enough):
B4X:
Sub tree_Action
waitlbl.Visible = True   
tree_timer.Enabled = True
End Sub

Sub tree_timer_tick
tree_timer.Enabled = False
...  (build the tree)
waitlbl.visible = false
End sub
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
You could just change the cursor for the application to the 'busy' one, then when all loaded reset to default cursor.
This will show the user the application is still working.
eg
B4X:
 MainForm.RootPane.MouseCursor = fx.Cursors.WAIT
' start loading the treeview
...
' after loading finished
 MainForm.RootPane.MouseCursor = fx.Cursors.DEFAULT
 
Last edited:
Upvote 0

derez

Expert
Licensed User
Longtime User
You could just change the cursor for the application to the 'busy' one, then when all loaded reset to default cursor.
This will show the user the application is still working.
eg
B4X:
MainForm.RootPane.MouseCursor = fx.Cursors.WAIT
' start loading the treeview
...
' after loading finished
MainForm.RootPane.MouseCursor = fx.Cursors.DEFAULT
Thanks but the behavior is the same, it works only when I use the timer.
 
Upvote 0
Top