Re: Newbie Question: Best view for list of strings? (Addendum: weird horizontal scrollbar/resize issues)
Re: Newbie Question: Best view for list of strings? (Addendum: weird horizontal scrollbar/resize issues)
- Subject: Re: Newbie Question: Best view for list of strings? (Addendum: weird horizontal scrollbar/resize issues)
- From: James Farwell <email@hidden>
- Date: Thu, 3 Apr 2003 21:42:57 -0800
- Resent-date: Fri, 4 Apr 2003 01:21:42 -0800
- Resent-from: James Farwell <email@hidden>
- Resent-message-id: <email@hidden>
- Resent-to: email@hidden
Chris,
Sorry about the incredibly long delay in replying, I got sort of bogged
down in school work right after I sent out the question and haven't
really had a chance to get back to my project until now. I appreciate
your extensive comments, and I'm afraid I was rather ambiguous in my
original message, so let me be a little bit more detailed about what
I'm trying to do:
I am working on a batch file-renamer with quasi-live feedback
(textDidEndEditing). There is one tableview that shows the current
filename(s), and one tableview that shows the filenames that result
from the renaming actions. Here is a screenshot just to make it clear:
http://www.blindjimmy.com/namingway3.png
Anyway, the "after" table is essentially updated every time one of the
rules is changed, so caching lengths there is pretty much impossible
since they all change after every edit. At the moment, I am just
calculating widths on the fly, and in terms of the number of files
(rows in the table) I have been testing with... say 30 max... I have
not seen any performance issues, so I think I'm just going to leave it
like this for now. After I get all the kinks worked out I'll work on
getting a more optimal method, since I'm sure some of what you
suggested can be implemented pretty easily.
That being said, my method works pretty well EXCEPT in some odd cases,
mostly centered around resizing. If I add a file whose name is wider
than the table, and my code correctly identifies its width and sets the
table-column's width and maxWidth, then the horizontal scrollbar
appears just fine (actually I discovered that for some reason just the
width of the string isn't enough for it to display properly, I have to
pad it with a teeny bit of space, but that's not a huge deal).
However, the second I resize, even just a vertical resize with no
horizontal, it seems that the table column instantly snaps back to the
width of the visible table. I have column auto-resizing turned off in
IB, though from reading the archives of the list it looks like IB is
notoriously buggy with tableviews. The only progress I have been able
to make is if I select the actual table column in IB and disable
resizing (even though it is neither visible, nor is global resizing
option enabled in IB) then the column doesn't seem to resize to the
visible size any more, but it still exhibits bad behavior and does not
stay the same size as it initially was. Sorry if this is confusing,
it's a little difficult to describe.
Anyways, any further assistance you or anyone else could provide is
much appreciated. Thanks again for your help!
- James
On Sunday, February 23, 2003, at 10:46 PM, Chris Giordano wrote:
James,
Just a few ideas off the top of my head:
First, I have some code that does something very similar using an
approach very similar to the one you're starting with. It is a much
shorter list with fewer changes, so I don't have the same issues with
recalculating the lengths each time. However, I don't see any reason
why a simple NSTableView wouldn't be a fine way of handing the display
of the strings. What I think you need to focus on is making the
datasource as efficient as possible. In any case you're dealing with
the reality of having to reset the width on each change to the data.
How (and how often) you calculate the width is -- in my somewhat
uninformed opinion -- probably pretty central to getting it to be
efficient. You might be able to take advantage of the fact that
you're not always displaying the longest string so really you only
need to have your table as wide as the longest string that is being
displayed. I'd think that this would be at the very least a lot
messier than just doing it for the whole list -- at the very least,
you don't have to worry about things like scrolling and whatnot.
My first thought is that you only need to calculate the widths of
strings when they are added or changed since this information is
otherwise constant. (Take the obvious caveat that changes to the
attributes of the strings will clearly also cause sizes to change, but
I'll ignore that for now.) In order to reduce the calculations, you
need to store the sizes of the strings somehow.
A somewhat simple but not horribly efficient solution would be to
simply store the sizes along with the strings using a dictionary or
some other structure (class, struct, whatever) to group the size and
the string. Your choice here could depend on how you are storing the
strings -- i.e., if you have an NS(Mutable)Array, you'd clearly need
to do something compatible with that. Once the sizes are initially
calculated and stored, you'd then identify the largest size. Each
time a string changed, you'd calculate its size and then find the new
largest.
A somewhat more efficient method (after the initial setup) would be to
have a second array or other ordered collection of your string/size
structures that you would keep sorted by size -- essentially an index
based on the sizes of the strings. Each time you change or insert an
string you calculate the size and then insert it in/move it to the
correct place in the sorted array. Since it's sorted you just take
the greatest (first or last, depending on the sort order) element's
size and make sure your scrollers can accommodate that. Worst case
here would be using an array with an inefficient sorting algorithm in
which case you end up something that would be O(n) for inserting a new
item into/changing the location of an item in the list, which isn't
really any better than just scanning the array every time to find the
new largest item. A better sorting algorithm and/or a more
hierarchical structure (e.g., tree) can taken this down to O(log n),
which can be a big improvement.
As for how to approach this: if it were me, I'd probably start with
the general idea of building the size "index" and then work to make
that efficient. I'd start with an array and use the Foundation sort
methods. I'd write methods/functions to abstract the functionality as
much as possible -- don't interact with the index directly, but use
accessor functions to insert/change items and get the maximum size.
This will also make it easier to keep the primary data structure and
the index in sync.
As for storing the sizes with the strings, it is certainly easier to
package the two together since this makes it easier to keep the
changes in sync. However, with lots and lots of strings this can
cause your index to be spread over lots of memory, in which case it
would be faster to have the index only store the size and a pointer to
the string, which would let you keep more of the index together and
reduce the number of page swaps (and potential disk activity).
If this approach proved too slow, I'd then see about improving the
index by either using a more efficient data structure or sorting
algorithm. A balanced binary search tree would change this efficiency
in a big way. Or something like a B-tree would make the structure
even more shallow and the searches potentially more efficient.
One thing you could do in addition to the above is to pad the width a
bit each time you set it. Then, rather than set it every time, you
would check to see if the new greatest width was greater than the
padded value and only set it then. I assume (based on little more
than a guess) that the if statement likely takes less time than
changing the table column's width, so reducing the frequency of those
changes would reduce the amount time used for the changes overall.
Just a few ideas. Hope they help.
chris
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.