June 2005 Archives

Off to get hitched...

| 10 Comments | No TrackBacks

Somehow it turned out that Grant and I are getting married a week a part. This week it's my turn...

Saturday Jen and I will be getting married, then we're off to prance around Jamaica for our honeymoon. I'll be as unplugged as I can possibly be, and won't be checking email at all. I'll also be shutting down the comments and trackbacks for my weblog to avoid the spam bots.

I'll be back sometime after the 4th of July. Have a good one, try not to miss me too much. ;-)

Using Shared Fonts in Flex

| 5 Comments | No TrackBacks

It turns out you can't directly embed a font into a Remote Shared Library (RSL) using Flex. Here's a handy little trick to get around that...

First, some background. I have a Flex application that consists of a main .swf that loads and manages several other "load on demand" .swf files. A user of the application doesn't necessarily need to use all parts of the application, so this modular approach allows them to only download the parts they'll be using. I'm using shared libraries to solve the problem of downloading the same information more than one time when using multiple .swfs in one application. For more information on RSLs in general, check out Roger Gonzalez's great article on the subject.

So I wanted to add a font to an RSL for a few reasons. The font should be able to be changed in only one place, it should only have to be downloaded one time, and all of the loaded .swf files should use the same font. I tried just using the embed tag to add it to an RSL, like this:

<embed source="../fonts/Arial.ttf" newSymbol="mainFont" />

When I went to compile though I was getting a failed to load resource error. Apparently you can't add .ttf files to shared libraries.

I then tried to embed the font directly into the main .swf file. The css for that looks like this:

@font-face {
src: url("../fonts/Arial.ttf");
fontFamily: mainFont;
}

Application {
fontFamily: mainFont;
}

The problem with the css approach is that the font was only appearing in the main .swf file. All of the other .swf files were attempting to use the font, but the font couldn't be found (as demonstrated by all of the text being a small serif font). So, I needed a way to reference the font from the loaded .swfs so that they would use it correctly.

The workaround for this problem, suggested by Roger, is so simple that it's perfect. Create a component that embeds the font via css, stuff that component into a shared library, and then reference the component from every .swf that needs the font. By taking this approach if I ever wanted to update the font I would simple update the shared library, and all of the application would use it.

So, I made a simple component, in Fonts.mxml:

<mx:Canvas xmlns:mx="http://www.macromedia.com/2003/mxml">
	
	<mx:Style>
		<![CDATA[
		@font-face { 
			src: url("../fonts/Arial.ttf");
			fontFamily: mainFont;
		}
		]]>
	</mx:Style>
	
</mx:Canvas>

...added that component to one of my shared libraries:

// inside the "library" tags:
<component name="Fonts" uri="*" />

... added some css for the main .swf file:

global {
fontFamily: mainFont;
}

... and then referenced the shared Fonts component inside every .swf file:

<local:Fonts width="0" height="0" />

I'm using width and height of 0 so that it doesn't actually draw anything (which would affect the layout). I suppose visible="false" would work just as well. But, by using the Fonts component, every single .swf will link to the font from the shared library, and because the global font family specifies that as the font to use, all of the text will be displayed with that font.

Good stuff... Flex handles shared libraries a million times easier than Flash does. I was pleasantly surprised to see this work, to say the least, especially thinking back to how much tweaking the Flash version of the same approach took. Go Flex go!

It seems that ASDT has been picking up some steam lately.

ASDT now has an update site that be used in the Software Configuration Manager in Eclipse. This make it easier to update the plugin because Eclipse can handle the download/install for you and let you know if a new version is available. To set up the update site, use the following steps:

  • Open the Help menu, and select Software Updates -> Find and Install
  • Select "Search for new features to install" and select Next
  • Click the "New Remote Site" button. Use "ASDT" as the name, and "http://aseclipseplugin.sourceforge.net/updates/" as the URL (minus the quotes, of course)
  • Expand the ASDT node that was added to the tree, and select Actionscript Development Tool
  • Click Next to go through the update process

The update site was just added and is just a teaser right now. A new version has not been released yet. The latest is still 0.0.7.1 available on sourceforge.

If you don't have line numbers with .as files yet you can get this functionality currently through a bit of a workaround. Go to Window -> Preferences. Expand Workbench (the top item on the left) -> Editors and select "Text Editor." Check the box for "Show line numbers." Now all of your .as files will have line numbers (and all other text files as well). This is a temporary solution until line numbers are added to ASDT itself.

Finally, there is some code in CVS right now for code folding that should be available in the next version. Things are really coming along nicely!

Currently the project is undergoing a bit of a rewrite / refactoring to clean some things up and make it easier to develop going forward. I'm hoping to have some more time to help in the future, but with a wedding coming up and some other projects going on, I've been extremely busy (excuses, excuses, right?). It's nice to see this kind of progress though! Great work everyone.

Flex is pimp

| 9 Comments | No TrackBacks

I've been chillin' with Flex for 2 weeks now, and I'm come to the only logical conclusion there is: Flex is pimp.

If you build RIAs and haven't looked at Flex yet, do yourself a favor and start playing with it. Here's some of the things I've noticed in the past 2 weeks:

  • It's very easy to get up to speed with Flex if you're already a Flash Developer. Once you get used to the tag based format, you can use your existing AS2 skills to hit the ground running. I've only been using Flex for 2 weeks, but because I've been developing with Flash so long I'd qualify myself as a pretty good Flex developer already. I'm not a pro with the Flex server side configuration, but I've been using Flex as a client-side compiler, so it's cool. I'll leave the server side for people who enjoy that kind of thing. By the way, my business / server side logic is all in ColdFusion, and I'm using good ol' Flash Remoting for the data transfers.
  • You'll love the components. The Flex component set is solid. The drag and drop features that come out of the box are sweet and easy to use. The charts are powerful and the effects provide some nice eye candy. Transitions help people visually in RIAs since there's no "refresh" concept, and Flex makes this simple. As a Flash Developer you're probably already an expert at these types of "RIA things". Flex lets you take your interaction design talent to the next level.
  • It's easy to integrate Flash content. Life is not just either Flash or Flex, you can successfully use both in the same project. Just loadMovie your Flash-created .swf into a Flex-created .swf, and you can do all of the stuff on the timeline that you normally would. Flex makes for a good container.
  • Shared libraries are very simple to use. I've rebuilt my shared library application architecture in a fraction of the time in Flex. In Flash it took me a long time to get it to work, required the use of some dummy "force share" movieclips, and just felt unstable overall. I cringed every time I had to add something to one of my shared libraries. In Flex, you just point your .mxml to a .sws definition and you're good to go. Solid, stable, reliable, quick, easy. There's no more _exclude.xml either - if a class is in a shared library it's excluded from the .swf automatically. This makes maintenance a lot easier (some of my exclude files were hundreds of lines long).
  • You'll drool over the layout classes. I hope I never have to write another line of layout code again. Using Flex, I don't think I ever will.
  • You can actually diff .mxml files in your source control solution. No more binary check-ins and wondering what changed if the comment in the changelog is "synching with repository."
  • Did I mention it speeds up development time and is easy to use overall?

I'm building a large Flash application at work, and I've been investigating using Flex as an alternative. It's an RIA, and I'm fully capable of completing it in Flash, but using Flex really makes a lot of sense after going through some of the motions. I can't believe I've waited this long to get into the technology.

I'm already pretty far along with the Flash app, but I've found that I can reuse about 95% of the code I've already written in the Flex conversion. Essentially, all I need to do is replace the separate .fla files, and the movieclip forms inside of them, with .mxml files. I'd say I could re-use 100% of my code, but I find that using Flex allows me to actually cut out large portions of the UI logic. Data binding makes things more readable which means less I have to write and wade through. I'll show an example of how Data Binding can improve code tomorrow.

Plus, as another bonus I can still use Eclipse to develop in. Add in a good XML plugin and you can get code hinting for .mxml files after pointing it to the schema.

Oh, and I've been talking with Jesse too much lately. We have something cool up our sleves re: Flex, which will hopefully be announced soon.

What are you waiting for? Go get the trial, and start playing. A word of warning though, once the Flex bug bites you it doesn't let go.

How to use Flex without a server

| 17 Comments | No TrackBacks

Flex is great, but it isn't a server technology. There, I said it.

I was very stubborn when it came to using Flex. There were a variety of reasons that I've never tried to build anything substantial with the technology. One of them was the apparent disrespect to Flash Developers. The other was the idea that I had to run Flex on a server. The last was the price tag. There were some others, but those were the major three for me personally.

As a long time Flash Developer I've seen the birth and rapid growth of "Rich Internet Applications." From smart clips came components, then the v2 architecture, and now Macromedia has an entire RIA framework available through Flex, but somehow along the way the Flash Developers got left behind. Maybe not officially, but it seems that way. In a way, we were the ones that drove the creation of Flex in the first place.. but so what? It wasn't long ago that Flash MX 2004 Professional was touted as the tool for developing Rich Itnernet Applications. Then Flex came along with an improved workflow and upgraded component set, and now Flash has gone the way of designers.

So where does that leave the Flash Developers? Jesse had an interesting take on this a few months ago. Times change, and it looks as though Flex is going to be the future of RIA development. Is it inevitable? Who knows, but for Flash Developers, I suppose we'll just "keep on keepin' on," as they say. There are still a ton of things I would favor Flash for, but for applications I don't think Flex can be beat. Aral would agree, I'm sure. Flex is worth learning because it really does improve how RIAs are built, but I'm still partially stuck on the pricing. The time saved should pay for the price tag, but you have to make a long term commitment to it for it to pay for itself.

Anyway, I'm not trying to get philosophical or anything. I've avoided Flex long enough, and now that I've started to use it there was a major problem I needed to solve right out of the starting gate. Flex should not be server-side technology. Period.

In my eyes, Flex is and should be just a compiler. The MXML markup is converted to ActionScript, run through some magic, and *poof* we get a .swf file. We all know that .swf files run in the Flash Player which is all client side technology. So why is a server necessary? It was probably a strategic move on Macromedia's part, like how Generator was Enterprise as well. After all, no one would pay then of thousands of dollars for a compiler.. but when it's bundled as a server and labeled Enterprise, the wool is pulled over the eyes. Needless to say I disagree with the Flex pricing model / server strategy, but I've already mentioned that.

Anyway, on to the good stuff. If you're like me then you don't think Flex should be running on the server at all, and it's actually not that hard to get around this. In the installation directory there are two jar files, mxmlc.jar and compc.jar, our compilers. The former produces .swf files form .mxml files. The later produces .swc files. We can invoke these compilers directly giving them appropriate input, and deploy the .swf output to our server.

This technique is similar to what Ted posted about in scaling Flex, but goes one step further in that it doesn't require flex running at all, not even on localhost.

Below is my ant build.xml file for automated precompiling of Flex applications. You'll need to have version 1.6+ of ant to use it since I'm using the new "macrodef" tag. If you want to build everything, you can run "ant all", otherwise just configure your modules / libraries and you can build them one at a time or in groups ("ant library1", "ant module1", "ant libraries", "ant modules" etc).

This is probably not just a copy and paste solution - you'll at least need to configure the libary / module sections, but also note the path for the Flex installation directory and also the path for the WEB-INF stuff. I just copied the WEB-INF directory into /etc of my project directory and went from there. Make sure your flex-config.xml file has the right paths as well. Watch out for "webroot" in the maskeswf macro as well, and also careful of the path where rsl's will be located on the server (currently I just use "libs"). Make sure the library destination jives with the url in your .sws files.

Anyway, here's the script. Comments are appreciated..

<project default="all">

	<property name="flex.dist.lib" value="C:\Program Files\Macromedia\Flex\lib" />
	<property name="flex.compc.jar" value="${flex.dist.lib}\compc.jar" />
	<property name="flex.mxmlc.jar" value="${flex.dist.lib}\mxmlc.jar" />
	<property name="app.dir" value="." />
	<property name="config.xml" value="${app.dir}/etc/WEB-INF/flex/flex-config.xml" />
	<property name="src.dir" value="${app.dir}/src" />
	<property name="dest.dir" value="${app.dir}/bin" />
	<property name="library.dest.dir" value="${dest.dir}/libs" />
	
	<target name="init">
		<!-- create directories -->		
		<mkdir dir="${dest.dir}" />
		<mkdir dir="${library.dest.dir}" />
	</target>
	
	
	<!-- macro to easily create an rsl -->
	<macrodef name="makelibrary">
	    <attribute name="library" />
		<sequential>
			<!-- compile the shared library -->
			<java jar="${flex.compc.jar}" dir="${app.dir}" fork="true" failonerror="true">
				<arg line="-flexlib '${flex.dist.lib}' -configuration 
	${config.xml} -webroot . -o ${src.dir}/@{library}.swc ${src.dir}/@{library}.sws" />
			</java>
			
			<!-- extract the .swf from the .swc for the library -->
			<unzip src="${src.dir}/@{library}.swc" dest="${src.dir}">
				<patternset>
					<include name="**/*.swf" />
				</patternset>
			</unzip>
			
			<!-- delete the .swc -->
			<delete file="${src.dir}/@{library}.swc" />
			
			<!-- rename and move the extracted library.swf to the name of the library -->
			<move file="${src.dir}/library.swf" tofile="${library.dest.dir}/@{library}.swf" />
		</sequential>
	</macrodef>
	
	<!-- macro to convert .mxml into .swf -->
	<macrodef name="makeswf">
	    <attribute name="module" />
		<sequential>
			<!-- might need to watch out for webroot here... -->
			<java jar="${flex.mxmlc.jar}" dir="${app.dir}" fork="true" failonerror="true">
				<arg line="-flexlib '${flex.dist.lib}' -configuration 
		${config.xml} -webroot . -o ${dest.dir}/@{module}.swf ${src.dir}/@{module}.mxml" />
			</java>
		</sequential>
	</macrodef>
	
	<!-- individual library targets to build one at a time -->
	<target name="library1" depends="init">
		<makelibrary library="Library1" />
	</target>
	
	<target name="library2" depends="init">
		<makelibrary library="Library2" />
	</target>
	
	<!-- group libraries target to build all rsls used -->
	<target name="libraries" depends="library1,library2">
	</target>
	
	
	<!-- individual module target to build one at a time -->
	<target name="module1" depends="init">
		<makeswf module="Module1" />
	</target>
	
	<target name="module2" depends="init">
		<makeswf module="Module2" />
	</target>
	
	<!-- group modules target to build all .swf files in an app -->
	<target name="modules" depends="module1,module2">
	</target>
	
	<!-- group target to build all parts of an app -->
	<target name="all" depends="libraries,modules">
	</target>
	
</project>


About this Archive

This page is an archive of entries from June 2005 listed from newest to oldest.

May 2005 is the previous archive.

July 2005 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Archives

OpenID accepted here Learn more about OpenID
Powered by Movable Type 5.02