Tuesday, May 8, 2007

Relative paths for embedded images

I was having a lot of problems with embedding images into my classes which were in nested packages. After a lot of head breaking and googling, I found an elegant method to solve this issue. There is some discussion about this problem here. The solutions given there do not exactly solve the problem, but it definitely made me think in the right way.

Anyways, here is the problem and the solution:

If you want to embed images into your icons or for any other purposes, you use something like this:


Now, if you have a complex project structure like this:


Now, if your MyClass.cs uses an Embed tag, you have a few options.

1. Use an absolute path
Ex.: [Embed(source="C:/Documents and Settings/computername/My Documents/Flex Builder 2/projectname/assets/images/icon.jpg")]

Of course, this is not an elegant solution. And also, if you have a team of developers working with this project, each person has to change the path everytime they check out their code. This is definitely NOT acceptable.

2. Use a complex relative path
Ex. [Embed(source="../../../../../../../../icon.jpg")]

Does this work? Yes, but is it an elegant solution? Of course not. This is not readable at all.
And btw, what happens if you decide to refactor your project? You need to go and change the path in each and every instance of the Embed directive. Not such a good option.

3. Now, there is another option that works very well and is quite elegant too. i.e. use the forward slash(/) operator to indicate the root. But what is root in this project? Apparently, the Flex compiler considers the 'main source folder' to be the root. Hence when you say '/', you are actually referring to the 'Main source folder' (which you can set in Project>Properties>Flex Build Path>Main source folder), which in most cases would be set as the 'src' folder.

So, all you have to do then is this:

Here you are first accessing the root, i.e. the 'src' folder, go one level up, and then give the path of the image, that is assets/images/icon.jpg.

You can use the same exact path anywhere in your package hierarchy.