Adding an image to a table cell

I have read through this thread (as well as a couple of others), and it appears that although what I think should be pretty simple, is pretty dang difficult. I want a window with a table that has a column on the left of thumbnail images, and a corresponding column on the right with the filename of each image. Here is the code I have been working with:

on will open theObject
    set picture_table_List to {}
    set thumb_Path to (path to pictures folder as Unicode text) & "somethumbs:"
    tell application "Finder" to set all_thumb_Images to every file in folder thumb_Path
    repeat with an_Image in all_thumb_Images
        tell application "Finder" to set ai_Name to (an_Image's name)
        set end of picture_table_List to {(thumb_Path & ai_Name), ai_Name} --
    end repeat
    set contents of table view 1 of scroll view 1 of window "main" to picture_table_List
end will open

As you can see, I set up a {two item} list of {filepath, filename} referencing a folder full of thumbnail images, and tried to put that into the table view. I also tried building the list using the Finder reference to the file instead of the filepath, but that did not work either. The table I created in IB has two columns, and I dragged the NSImageCell into the leftmost column, which created a very cool looking column of little windows. I had hoped that by trying to install the path into the cell, it would load up the image. Clearly, that is not the case.

What is really interesting, and probably informative, is that when I Build/Run this code, this shows up in the Run Log:

[Session started at 2006-12-01 22:19:45 -0800.] 2006-12-01 22:19:46.316 iPhoto CD Cataglo[2836] An uncaught exception was raised 2006-12-01 22:19:46.321 iPhoto CD Cataglo[2836] NSImageCell's object value must be an NSImage. 2006-12-01 22:19:46.325 iPhoto CD Cataglo[2836] *** Uncaught exception: <NSInvalidArgumentException> NSImageCell's object value must be an NSImage.
So, I know I need to have an NSImage instead of a filepath, but how do I get it?

As far as I know, there’s no way to pass an image in a list to a table view using the “set contents of…” method. In fact, working with images in tables in ASStudio sucks… to put it bluntly. You pretty much always have to resort to some obj-c, and what technique you use depends on where exactly you’re getting your image data from. I’ve tried to work out how to set the image in the ‘cell value’ handler, but nothing seems to work. I either get errors, or no image is ever displayed in the view. I’ve pretty much given up on tables and outline views in ASStudio, and have gone to obj-c completely.

What I’ve found to work best in ASS is to use the ‘cell value’, ‘number of rows’, and ‘will display cell’ handlers. I’ve dispensed with all the calls to the finder (yuck!) and cleaned up the list that keeps track of the path/name of the image files. There’s no need to create a list with both the path and the name. The path contains the name, so just extract the name when you need it rather than making a big list of lists to hold both.

property tableView : null
property picture_table_List : {}

(* Initialization methods *)
on awake from nib theObject --> Connected to the Table View
	if name of theObject is "Table" then
		set tableView to theObject --> Save a reference to your table view for easy identification in your script
	end if
end awake from nib

on launched theObject --> Connected to the FIle's Owner
	show window "Window" --> Disable "Visible at launch time" for your window, in IB... then open it manually here
end launched

on will open theObject --> Connected to the window
end will open

(* Table view data source methods *)
on cell value theObject row theRow table column tableColumn
	if (name of tableColumn is "Text") then
		set thePath to ((item theRow of picture_table_List) as string)
		return (name of (info for alias thePath)) as string
	end if
end cell value

on number of rows theObject
	return (count picture_table_List)
end number of rows

on will display cell theObject table column tableColumn cell theCell row theRow
	if (name of tableColumn is "Icon") then
		set thePath to (POSIX path of (item theRow of picture_table_List)) as string
		call method "setImage:" of theCell with parameter (load image thePath)
	end if
end will display cell

(* Subroutines *)
to updateTableView()
	set picture_table_List to {}
	set thumb_Path to (path to pictures folder as Unicode text) & "Development:"
	set all_thumb_Images to (list folder thumb_Path without invisibles)
	repeat with an_Image in all_thumb_Images
		set an_Image to (thumb_Path & an_Image) as string
		if ((kind of (info for alias an_Image)) is not "Folder") then
			copy an_Image to the end of picture_table_List
		end if
	end repeat
	tell tableView to update
end updateTableView



Thanks for your effort. I copied over the code, and made all the changes you identified to the objects and File’s Owner portions. I inserted a couple of display dialogs to make sure that the proper folder was being accessed, and that the list of JPG files I wanted was found (they were) and I now get a window with a table view, but the table is empty of both images and text.

I did some more reading last night after my posting and as you say, it is clear that AS Studio’s image handling ability is poor. I do not mind learning something new, but as we novices often find, sources on subject details we are interested in are sparse, or just plain confusing.

I would be happy to consider another course of action entirely. My project is based on my avocation as an amateur photographer. I have stacks of CDs and DVDs of digital photos that I have archived over the years, but there remains no good method to catalog these images for later access, unless I go for a gigantic hard drive. Last year, I started an AS based project using an AppleWorks database to catalog all the images on the discs. After some serious effort (and a few helps from Jacques), I was able to finally load an image into the AW DB I had created using AS. Now, although AW was made by the same people who made FileMaker, it was clear after I loaded a few discs that this was not going to work; there was simply too much information, and the DB was bogged down.

I learned MySQL and put together a nice GUI for a friend who keeps a huge collection of music on DVDs, and it is lightning fast, even with my meager AS Studio abilities. I had hoped to do the same for my photo collection; set up a MySQL DB with the image information, and build a GUI to display the selected image thumbnails, and then direct the user to the proper disc for the desired file. I am not wanting to re-invent iPhoto; I just want a simple catalog of all my photos without a giant hard drive.

So, if you (or anyone else) have/has any other thoughts or ideas on how to proceed, I am completely open to suggestions. And yet, external drives are becoming less expensive all the time…

With respect to your problems using my code, the only reason I can see is that you have failed to connect all of the objects to there respective handlers, or that you’ve forgotten to name an object correctly in the code or in IB. If you want, I can send you the test project I used to create the code I posted. Send me an email with your address and I’ll mail it to you. Seeing the whole project may give you some insight into what you missed.

With respect to the overall concept behind your task… as I see it, you could take one or a combination of three approaches…
The first, and most obvious would be to simply have ALL of your images on your hard drive(s). The advantage to this is that you’ve got everything available to you at any given time. No need to index or create a database, you simply access them as needed for getting paths, previews/thumbnails, listing them, etc. The disadvantage is equally obvious… images take up space, so you’ll quickly reach the limits of your hard drive. As you’ve stated, an external drive that housed all of your images might solve this problem… but cost is obviously an issue for a hard drive of substantial size.

The second approach, would be to write an indexing application that would scan your image cd’s and dvd’s, and create a local directory tree that contained all of your thumbnails and supporting data. You could store a plist or database file which mirrored your disk contents and also stored references to all of your thumbnails and their corresponding paths on disk. When you fired up your app, you could then search your database, view the thumbnails saved on the hard drive, and then if you wanted to view the actual image it would prompt you to insert the disk saved in your reference file and then access the image once you inserted the disk.

The third approach, would be to create an app that served as a disk browser. While you would probably want to incorporate this into your app if you went with the second option above, this could also act as a standalone app. Insert a disk, and the app would read the disk and present it’s contents in a plain, directory-style structure. Using this technique would allow you to browse your disks in a custom interface instead of the finder, and would not store any substantial volume of data on your hard drive. I am using something like this in one of the features in my upcoming re-release of Chronicle, where users navigate through a folder of images and can preview them easily. I also have a home publishing app with extra cd’s that have images and clipart on them that employs this technique. You browse through a data file that lists the categories and summary of the images, and then if you select one of them, it asks you for the cd that the file resides on.

As I said, I’ve found that handling images in ASS is clumsy at best. Loading images through applescript is not very efficient, buggy, and is difficult to manage in terms of memory allocation. Making an image browser in ASS could lead to some pretty ugly stuff, and a huge mess of memory leaks if not implemented properly. While I understand that obj-c may not be your strong suit, it is certainly more adept at handling this sort of task than ASS is. Let me know if I can help you, either conceptually or with your code.


Thank you for your help. Is it possible to attach a sample project of your solution?
This would be very nice.

Greetings, hoschy07.