TextArea, managing buffer size, scrolling

Post your Gambas programming questions here.
Post Reply
User avatar
Godzilla
Posts: 63
Joined: Wednesday 26th September 2018 11:20am

TextArea, managing buffer size, scrolling

Post by Godzilla »

Hello everyone,

I use a TextArea in one of my Gambas applications (QT). As my program operates, it periodically adds lines of status updates to the bottom of the TextArea. These updates contain various information such results of tests, sizes of files, the time operations have taken. etc.

As the program cycles through its tasks, repeating forever, it periodically adds another line of text at the bottom of the TextArea. I'm able to scroll up, if needed, to compare the current block of statuses to what happened 10 minutes ago, 30 minutes ago, etc. Because the data its crunching is always changing and never the same.

The problem is: over time, the program's GUI becomes sluggish, eventually non-responsive, due to the TextArea buffer size inevitably becoming filled.

I've worked around this by using the following example code in Timer1 (1000 ms). It removes all but the more recent status updates from TextArea1.:
Dim TempString as String

If TextArea1.Length > 5000 Then
  TempString = TextArea1.Text
  TextArea1.Text = Null
  TextArea1.Text = Right(TempString, 1000)
  TextArea1.Pos = TextArea1.Length
  TextArea1.EnsureVisible
  TempString = Null
EndIf
I'm also using this code in the TextArea's change event
Public Sub TextArea1_Change()
  TextArea1.Pos = TextArea1.Length
  TextArea1.EnsureVisible
End
This solves the problem of the program's GUI becoming sluggish over time, due to an ever-growing buffer.

However, as for keeping the TextArea scrolled to the bottom, as the latest line of text is added, sometimes it works and sometimes it doesn't. When it doesn't work, the TextArea will be scrolled to the very top, instead of the bottom. And then, when a new line of text is added, the TextArea jumps to the bottom and instantaneously jumps back to the top.

This has got me completely stumped. I don't recall ever having this problem before Gambas 3.15. But I'm not saying its a Gambas bug. Its much more likely a peculiarity of this particular program I've created.

I know you guys are the best of the best. And I have no doubt some of you have much better and cleaner methods of handling both the TextArea buffer issue and the scrolling issue. Thanks for any help or suggestions.

Gambas 3.15.2
Linux Mint 20 Ulyana 64-bit
Kernel Linux 5.4.0-52-generic x86_64
MATE 1.24.0
User avatar
BruceSteers
Posts: 1565
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: TextArea, managing buffer size, scrolling

Post by BruceSteers »

funny ole TextArea.
I was having a layout problem the other day.
Look at this snippet..
TextArea1.Line = IIf(EntryRow > lastselected, prfitemendLN + 5, prfitemstartLN - 5)
TextArea1.EnsureVisible
Wait 0.2
TextArea1.Line = prfitemstartLN
TextArea1.Select(TextArea1.ToPos(TextArea1.Line, 0), TextArea1.ToPos(prfitemendLN, 0) - TextArea1.ToPos(prfitemstartLN, 0))
that gets a portion of the TexxtArea text and selects it (Visibly)
Before I added the Wait 0.2 part it didn't work.
It was like the actual text in the display moved slower than my code did , without the Wait command the selected text was too low and had not had time to move up.
Not sure if your issue is the same but that helped for me.

As for the buffer and the lag i don't think it's buffer size that will change anything, if anything it's the cause of the issue.
the problem is the sheer amount of data in the buffer you are trying to scroll/process in one go.

One suggestion i'd say is, rather than a text area maybe try a ListBox
Then you could work on the text line by line instead of dealing with all the text data in the buffer each time.
Ie simply removing the top ListBox lines (once your desired max line count is reached) and appending them to a log file.
that would be quicker for the code rather than dealing with a huge text buffer.

BruceS
If at first you don't succeed , try doing something differently.
BruceS
User avatar
cogier
Site Admin
Posts: 1125
Joined: Wednesday 21st September 2016 2:22pm
Location: Guernsey, Channel Islands

Re: TextArea, managing buffer size, scrolling

Post by cogier »

Like Bruce, I wondered if the TextArea was the correct tool. Could you post a sample of your TextArea output, so we could see if there is another way.
User avatar
Godzilla
Posts: 63
Joined: Wednesday 26th September 2018 11:20am

Re: TextArea, managing buffer size, scrolling

Post by Godzilla »

Bruce and Cogier, thank you both for your replies.

I tried Bruce's suggestion of including Wait 0.2. This didn't fix my scrolling problem. But it did unexpectedly make the TextArea flicker or flash, as status updates were added.

On closer examination, I discovered that the flicker/flash was the TextArea being completely erased, then completely refilled in rapid succession. This happened every time a new line of text was added to the TextArea. The lines being added are nothing complicated. Time/date: xxx, cycle time: xxx, zip file size: xxx, server response time: xxx. Any of dozens of different little factoids like that. They just pile up over time.

Anywyas, the rapid clearing and refilling of the TextArea was obviously unintended. And obviously the root cause of the scrolling problem. So I understood what was going wrong. I just couldn't understand why it was going wrong. I didn't code it to work that way (I don't think).

Here's the code I was originally using to add text to a TextArea that already contains text:
TextArea1.Text &= "Current time: " & Format$(Cdate(Now), "mmm d, yyy, hh:nn:AM/PM") & gb.CrLF
This is how I've always added text into a TextArea. Its basic Gambas 101. You do it, it works, you use it from that point onward, and don't think about it anymore. I've never had a problem with a line of code like that, ever. But for whatever reason, all lines of code similar to the above, whose function is simply add text at the bottom of the text already contained in a TextArea,, would cause the above-described problem for me, in this particular program of mine.

I experimented by using gb.LF instead, which is actually more appropriate for Linux anyway. Exact same issue, no change.

Then I experimented by trying a different approach to the concatenation:
TextArea1.Text = TextArea1.Text &  "Current time: " & Format$(Cdate(Now), "mmm d, yyy, hh:nn:AM/PM") & gb.LF
Exact same issue, no change.

So I tried a different method that I found in the mailing list from 2009. Benoit recommended the Insert method as being an overall better and faster way of TextArea concatenation. And so, what the heck, I'm out of options. I'll give it a shot.
TextArea1.Insert("Current time: " & Format$(Cdate(Now), "mmm d, yyy, hh:nn:AM/PM") & gb.LF)
This solved the problem! The TextArea now happily scrolls to the bottom whenever a new line of text is added. No flickering. No erase/refilling. No hassles at all.

I couldn't even begin to tell you why &= and $=$&$ doesn't function as expected for me anymore, in this particular program. But its good that we have this perfectly-functioning alternate method. I'm guessing there was perhaps some change or addition in Gambas 3.15 that I'm not aware of. I mean it could possibly be a bug introduced in 3.15. But there was also a lot of changes in 3.15 as well, which could have made the first two code example in this post obsolete, for all I know.

In any case, thank you for reading.
User avatar
BruceSteers
Posts: 1565
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: TextArea, managing buffer size, scrolling

Post by BruceSteers »

Godzilla wrote: Saturday 24th October 2020 4:27am Bruce and Cogier, thank you both for your replies.
On closer examination, I discovered that the flicker/flash was the TextArea being completely erased, then completely refilled in rapid succession. This happened every time a new line of text was added to the TextArea. The lines being added are nothing complicated. Time/date: xxx, cycle time: xxx, zip file size: xxx, server response time: xxx. Any of dozens of different little factoids like that. They just pile up over time.

In any case, thank you for reading.
Aah , i feel i have both taught something and learned something here , thank you. :)
I was having a similar issue that i'd tracked down to the problem being the textarea was completely erasing and refilling again.
Will look into the Insert() way instead.

You're welcome and thank you :)
BruceS
If at first you don't succeed , try doing something differently.
BruceS
User avatar
Godzilla
Posts: 63
Joined: Wednesday 26th September 2018 11:20am

Re: TextArea, managing buffer size, scrolling

Post by Godzilla »

BruceSteers wrote: Saturday 24th October 2020 12:13pm Aah , i feel i have both taught something and learned something here , thank you. :)
I was having a similar issue that i'd tracked down to the problem being the textarea was completely erasing and refilling again.
Will look into the Insert() way instead.

You're welcome and thank you :)
BruceS
Hey Bruce, glad that we're helping each other. And its a relief to know that I'm not the only one affected by this issue (I thought I must have really screwed something up).

The Insert( ) method will insert text wherever in the TextArea that the cursor is currently placed, which is always present even when the control doesn't have focus.

The cursor should in theory always be at the end position of the TextArea. Unless it gets clicked on by mistake. So to ensure it always stays where we want it to be (for the sake of the Inser( ) method), I've found it useful to have the following code in the TextArea's Change event:

Public Sub TextArea1_Change()

  TextArea1.Pos = TextArea1.Length  'places the cursor at the very end of the text currently in the control
  TextArea1.EnsureVisible           'this keeps the control scrolled to the cursor's current position 
  Wait                              'allows scrolling regardless of CPU load, and when no # is specified, uses only the amount of time needed for the operation, freeing CPU

End
Best of luck,
Godzilla
Post Reply