Text Color in Table View's Cell; Part II

As we discussed in a former topic how to coloring text in a table’s cell the delegate tableView_willDisplayCell_forTableColumn_row_ works well.
Exept the count of data cells is not to much. Then the app hangs every time the user makes a key stroke.
An unsatisfactorily situation.

So I’m going to coloring the cells myself by a button (or menu item).
That led to a surprising result: I can read out the content of every cell but can’t set the individual text color.


on bTableColor_(sender)
        set rowCount to numberOfRowsInTableView_(aTableView)
        set theColumn to aTableView's columnWithIdentifier_("myIdentifier")
        aTableView's beginUpdates()
        repeat with i from 1 to rowCount
            set theCell to aTableView's preparedCellAtColumn_row_(theColumn,i-1)
            set cellContent to theCell's stringValue()
            if cellContent is in {"4", "3", "2", "1"} then
                set aColor to myGreenColor --colorClass's greenColor
            else                
                set aColor to colorClass's redColor
            end if
            log theCell -- always the same cell
            log cellContent -- correct content
            log aColor -- set correctly 
            theCell's setTextColor_(aColor)
        end repeat
        aTableView's endUpdates()
    end bTableColor_
    

The result: the whole column is set to the color who is set at the end of the script.

Heiner

Hi,

maybe reloadDataForRowIndexes:columnIndexes: of NSTableView could be a solution,
the method updates (redraws) only the specified rows/columns

Hi Stefan,

reloadDataForRowIndexes:columnIndexes: reloads the data as it says, so aTableView’s reloadData() should do the same, but it doesn’t. Only the whole column ist colored in the same color.
It’s a pity!

Thanks,

Heiner

Of course I mean reloadDataForRowIndexes:columnIndexes: in conjunction with tableView:willDisplayCell:forTableColumn:row:

I don’t know how it should work.
tableView:willDisplayCell:forTableColumn:row: is bound by the table as a delegate. The handler checks all cells in every column and every row in every table view (in my case there are three and ca. 400 cells for every table); that lasts for a very long time, even the handler is empty (only on and end).

normally you send a reloadData() message to the table view which causes the whole table to be redrawn.
The reloadDataForRowIndexes:columnIndexes: method calls tableView:willDisplayCell:forTableColumn:row: only for the specified rows / columns which is much faster than redrawing the whole table

Sorry Stefan,
maybe I’m behind the moon.

In tableView_willDisplayCell_forTableColumn_row_(aTableView, acell, aColumn, aRow) is no need to reload the table. The ‘system’ do it permanently by itself. How can I have an Influence to that?

Would it be possible to use a completely different approach – that is to have your data be NSAttributedStrings, so that the color would be an intrinsic part of the data instead of using the table view methods to provide the color. This would depend on how you are getting the data into your table, and how you are using the data. I’m sure it’s possible this way, I’ve done it with a 50,000 row table, but it might not be the most efficient way depending on what you need to do with the data.

Ric

Oh god!! My script has more than 5000 lines, the tables are communicating to each other and compare values. As I read in Doc’s NSAttributedStrings in rush comparison is not easy. My tables are handled via data sources and I think the new approach would strech my possibilities too far.
And: Coloring the cells in a different way would only be an additional feature in my app. It is not really necessary.

There are things between heaven and earth…

Thank you to both of you.

Heiner

Heiner,

You might want to look up “field editor” in the documentation, to see why you see what you see.

Another solution would be to use an NSValueTransformer. In fact, there’s a project here homepage.mac.com/mmalc/CocoaExamples/controllers.html that shows how to do this in Objective-C (see the ToDos project).

If your requirements are simple, you should be able to edit the sample Objective-C code, rather than rewriting it in AS. That would help with speed significantly.

I tried out a transformer written in ASOC, and at least with my example (which converts numbers to attributed strings with colors that depend on the value of the number), and using bindings, the value transformer did not seem to take any time at all. I created a half million member array of random numbers (that part I did do in Objective-C), that was used as the content for my table, and it only took 2 seconds to populate the table whether or not the value transformer was present.

Ric

Interesting. That suggests a transformer is definitely worth investigating.