Angus Robertson 574 Posted September 11, 2019 Looking for a visual component similar to TEdit (but read only) that adds new lines at the top of the window, and pushes them down, reverse scrolling. Ideally forward or reverse scrolling should be an option. Angus Share this post Link to post
Cristian Peța 103 Posted September 11, 2019 If I understand right, this should do the job: ListBox1.Items.Insert(0, 'New string'); or ListBox1.Items.Add('New string'); Share this post Link to post
Angus Robertson 574 Posted September 11, 2019 Yes, inserting a line at the top works, but is it efficient to push 100,000 lines lower? Particularly when adding 100 lines. There must be a better way. Angus Share this post Link to post
Attila Kovacs 629 Posted September 11, 2019 The last time I did something similar I was using some kind of virtual table reverse ordered and bound to some db-control, like dblist or dbgrid. Share this post Link to post
Cristian Peța 103 Posted September 11, 2019 (edited) I was curious... Using a dataset is faster but this takes about 4 sec. on my machine. Second try about 14 sec. ListBox1.Items.BeginUpdate; for i := 1 to 100000 do ListBox1.Items.Insert(0, 'New string ' + i.ToString); ListBox1.Items.EndUpdate; But with TClientDataSet first 3 sec., second 8 sec.: if not ClientDataSet1.Active then begin ClientDataSet1.FieldDefs.Clear; ClientDataSet1.FieldDefs.Add('Time', ftDateTime); ClientDataSet1.FieldDefs.Add('Str', ftWideString, 100); ClientDataSet1.CreateDataSet; ClientDataSet1.AddIndex('Index1', 'Time', [], 'Time'); ClientDataSet1.IndexName := 'Index1'; end; ClientDataSet1.DisableControls; for i := 1 to 100000 do ClientDataSet1.AppendRecord([Now, 'New string ' + i.ToString]); ClientDataSet1.EnableControls; P.S. Second try adding more 100,000 lines to first. Edited September 11, 2019 by Cristian Peța Share this post Link to post
Angus Robertson 574 Posted September 11, 2019 Of course I meant TMemo in the subject... A virtual TListView is very useful for rapid sorting for columnar data, but I'm displaying random textual information, might be raw data from 50 GPS locators, router syslogs, or alarms from remote monitoring of transmitters or properties, and it's the latter low traffic where people ask for latest at top of window rather than bottom. Angus Share this post Link to post
timfrost 78 Posted September 11, 2019 While I was typing a message which essentially said, "why not a TMemo", a notification of the first answer here popped up, so I did not bother. And it turns out your real question was as much about organising large numbers of additions as about the component to view them. I have an application which uses a VirtualTreeView for this purpose. This allows you to optimise the loading and updating of the list completely separately from the viewing of it. The VTV handles all the scrolling for you, and you simply insert nodes. Inserting takes much the same time if you insert at the top. bottom, or middle, and the items just appear on the screen, which only has to redisplay the currently visible nodes, wherever you do the insertion. It can be made extremely fast and efficiemt. especially if loading/updating the data is done in a background thread and notified to your inserter code. Share this post Link to post
Angus Robertson 574 Posted September 11, 2019 The problem with ListView or VirtualTreeView is I'd have to write a code to parse text file lines into an array of lines as the data source. Mind I guess that is what TMemo is doing when I load a TStringList into it, worth a little test code. Angus Share this post Link to post
timfrost 78 Posted September 11, 2019 It is not clear whether you actually need to keep them somewhere structured and ordered, like a stringlist. For a VTV, I would create a nodedata structure for each one containing either the string or a pointer to it, then just insert the node. If you do want an ordered list later, you can just walk the tree; if not, you are done when you have created the node structure and inserted it. Share this post Link to post
Angus Robertson 574 Posted September 11, 2019 The purpose is to display the content of one of up to 999 text files selected from a tab control, no columns or sortable data, just random lines of text up to 2K long. So each time the tab is clicked to change a source file, the TMemo is reloaded with lines. I don't need the complexity of VTV, no headers, footers, columns, nodes, etc. TListView will handle virtual data quite adequately, if I can remove the header. But I really would prefer a TMemo that reverses the TStringList loaded into it, top latest. Angus Share this post Link to post
Angus Robertson 574 Posted September 11, 2019 The GUI looks like this and it's the left window that show data. Angus. Share this post Link to post
Bill Meyer 337 Posted September 11, 2019 3 hours ago, Angus Robertson said: But I really would prefer a TMemo that reverses the TStringList loaded into it, top latest. That aspect you should be able to resolve easily enough with a TStringList as a buffer, and just iterate through the source stringlist from bottom to top, copying lines to the destination. Share this post Link to post
Attila Kovacs 629 Posted September 11, 2019 you could also just do a Memo1.Lines.Insert(0, s); instead of Lines.Add(); (which is actually Insert(GetCount, s);) and you do not have to change much Share this post Link to post
Angus Robertson 574 Posted September 12, 2019 Yes, best to test the quickest solution first and only do something harder if it's too slow. Reverse scrolling is only wanted by people with slow data updates like alarms who actually watch the screen, no-one watches syslogs rushing past at 10 lines per second, except to see something is arriving. \ Angus Share this post Link to post
Guest Posted September 12, 2019 From having put "logwindows" in a multitude of application, i'd go for something "virtual" from start. Logs grow. Demand on readability will come. Just my .05€. Share this post Link to post