Recent

Author Topic: Overwriting a line in a sorted ListBox  (Read 1077 times)

jeff

  • New Member
  • *
  • Posts: 18
Overwriting a line in a sorted ListBox
« on: April 23, 2019, 08:24:53 pm »
Hi,
I am writing a small utility that receives text data from usb and displays them in a listbox. Every line consits of an id and some data bytes, and my program displays the lines sorted based on their id. If a line arrives with an id that has not been received earlier, the program adds it to the list with "ListBox1.Items.Add(buf);". If there is such an id in the list, my program simply overwrites it with "ListBox1.Items:=buf;" but here comes the problem. The ListBox is sorted, and an exception comes up because it is not allowed to do this on a sorted list. As a workaround I have commented out the part "if Sorted then Error(SSortedListError,0);" in the file c:\codetyphon\typhon\lcl\interfaces\win32\win32listsl.inc. Although it is working, I don't like this solution. So my question is, is there any other method for avoiding the exception when the program is overwriting a line?

ASerge

  • Hero Member
  • *****
  • Posts: 2242
Re: Overwriting a line in a sorted ListBox
« Reply #1 on: April 23, 2019, 09:29:41 pm »
Code: Pascal  [Select][+][-]
  1. procedure AddToListBox(ListBox: TListBox; const S: string; AObject: TObject = nil);
  2. var
  3.   NewItemIndex: Integer;
  4.   LItems: TStrings;
  5. begin
  6.   LItems := ListBox.Items;
  7.   NewItemIndex := LItems.IndexOf(S);
  8.   if NewItemIndex < 0 then
  9.     NewItemIndex := LItems.AddObject(S, AObject)
  10.   else
  11.     LItems.Objects[NewItemIndex] := AObject;
  12.   ListBox.ItemIndex := NewItemIndex;
  13. end;

jeff

  • New Member
  • *
  • Posts: 18
Re: Overwriting a line in a sorted ListBox
« Reply #2 on: April 24, 2019, 09:20:33 am »
Thanks for taking the time to reply, but I don't understand your code. How this could help in my question?

Anyway, I came up with a solution, but I'm still not statisfied because it is much slower than it was.
Instead of
Code: Pascal  [Select][+][-]
  1. ListBox1.Items[i]:=buf2;
I'm using now
Code: Pascal  [Select][+][-]
  1. ListBox1.Items.Delete(i);
  2. ListBox1.Items.Insert(i,buf2);
It is working but it is slow because Insert calls a windows sort function, which is unnecessary because I insert the new data at the correct place.

ASerge

  • Hero Member
  • *****
  • Posts: 2242
Re: Overwriting a line in a sorted ListBox
« Reply #3 on: April 24, 2019, 10:25:50 am »
Thanks for taking the time to reply, but I don't understand your code. How this could help in my question?
Code: Pascal  [Select][+][-]
  1. AddToListBox(ListBox1, buf2);

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Overwriting a line in a sorted ListBox
« Reply #4 on: April 24, 2019, 02:50:10 pm »
Thanks for taking the time to reply, but I don't understand your code. How this could help in my question?

ASerge's code tests whether the item's string (id?) is already there and, if so, replaces the object. If not, then just adds the item. All you have to do is call
AddToListBox(ListBox1, Id, Buff);

Quote
Anyway, I came up with a solution, but I'm still not statisfied because it is much slower than it was.
Instead of
Code: Pascal  [Select][+][-]
  1. ListBox1.Items[i]:=buf2;
I'm using now
Code: Pascal  [Select][+][-]
  1. ListBox1.Items.Delete(i);
  2. ListBox1.Items.Insert(i,buf2);
It is working but it is slow because Insert calls a windows sort function, which is unnecessary because I insert the new data at the correct place.

When the items are sorted Insert() behaves like Add() because it has to keep the list sorted. The only way to avoid it is to make ListBox.Sorted := False before you perform the operation ... but then you'd have to set it to True after, which would trigger the sorting.

One thing: you're using Insert and Add, which only treat with the string part of the items: ASerge's solution then won't work for you unless you separate the ID from the rest of the data. The ID then would go to the string and the other data to the object. Otherwise, your own solution is the only one I can think of.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

 

TinyPortal © 2005-2018