Author Archive for mike

Look ma, no upload! Remote debugging live SWFs with Charles Proxy

Have you ever wanted to be able to launch your live or staging site from Flash Builder, but still be able to debug your code in real time? With Charles, you can do just that! It doesn't take a whole lot of configuration, and is really useful when you need to run your app with real live data.

To clarify, let's just say your SWF's URL on your live server is:
     http://www.myapp.com/myapp.swf
Charles can re-route that request to a local file:
      /Users/Mike/Documents/Projects/myappp/bin-debug/myapp.swf
Combined with Flash Builder's debugger that allows you to launch HTML pages, you can launch your site at "http://www.myapp.com/index.html," and when your SWF is requested, Charles will serve up your local SWF, allowing Flash Builder to debug in real time. Pretty cool, huh? Here's how you do it:

To start, download Charles from here: http://www.charlesproxy.com, and install it. If you're using Firefox, also install the Charles Firefox Plugin.

With Charles open and running hit your live URL. For my test I'm using a simple SWF that just displays the loaderInfo's url. Find your SWF in Charles, it should look something like this:

Now, right click on that SWF file and click "Map Local." You should see a window that looks like this:

Now click the "Choose" button in the Map To section and select your local SWF that you would like to use to debug, then click OK. Next, open up Flash Builder and open the project this SWF belongs to, then right click the project in Package Explorer, select "Debug As," then "Debug Configurations." You'll see a window that looks like this:

Uncheck the "Use default" checkbox and replace the text with your live URL. This can be either the SWF file itself or the HTML page that the SWF resides on. I recommend using the HTML page route so that you're truly running in the context of your live site. Anyway, set a breakpoint somewhere in your code, then run your new debug configuration. It will launch your live site, but breakpoints will work! You can test your SWF with live data like this.

TIPS:

1. You can create multiple debug configurations for each project. I recommend having one for local and one for each of your remote environments you have to test on.
2. If you're doing this with a flex project you'll need to map a few more files. Flex splits the swf up into RSLs, so you're going to have to map each RSL for each project. This is kind of annoying but it only takes a couple minutes, and it's totally worth it.
3. To turn off/on the Map Local feature in Charles, go to Tools, then Map Local.
4. Charles is definitely worth the money if you do any professional development. Pay for it, help him out :-)

Happy debugging!

Comments

Flex 4: Skinning a Button, Spark Style

Some major changes have been implemented with the introduction of Flex 4. The new framework introduces new methods for skinning, states, layouts and declaring non-visual elements in MXML. There's also a new component set called Spark, which will change the way you think about developing modular components. For this article, we will be designing one of the simplest Flex components: a Button. Through this, I'll be implementing some of the major changes so that you can see how it's applied.

Beginning the Button

To start, pop open Flash Builder 4 and create a new Application, making sure you're using the new Flex 4.0 framework.  I named my project SparkButtonDemo.  Once the project has been created, you'll be presented with your Application's MXML file.  You may already notice some differences; Your main Application tag is no longer mx:Application, but s:Application, and there is a new child tag called fx:Declarations.  The simple change in namespace for the Application tag is to indicate that we're no longer using the mx component set, while the fx:Declarations tag is used for any non-visual children (data providers, FileReference objects, services...anything you cannot see).

To start creating our new Button, let's create a new MXML Component called SparkButton.  The component should extend spark.components.Button.

Skinning the Button

The new Spark component set was designed from the ground up to make skinning components easier and more modular.  To start skinning your button, you must create another MXML Component that extends from the spark Skin component (spark.skins.SparkSkin).  Once this class is created, you can start adding some skin elements to it.  The first thing that needs to be added to your skin is a metadata declaration describing the type of component we are skinning.  This looks a little something like this:

<fx:Metadata>
[HostComponent("spark.components.Button")]
</fx:Metadata>

After adding this code, you will see 4 errors pop up in your Problems window.  Flash Builder is trying to tell you that you haven't defined the required states for a Button.  So let's add 4 states: up, over, down, and disabled.  You should have something that looks like this so far:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx">
  <fx:Metadata>
    [HostComponent("spark.components.Button")]
  </fx:Metadata>
  <s:states>
    <s:State name="up"/>
    <s:State name="over"/>
    <s:State name="down"/>
    <s:State name="disabled"/>
  </s:states>
</s:SparkSkin>

Next, we will add some graphics to our Button.  For this example we're going to keep it simple, and add a rectangle with a 2 pixel border, and a label control for the button's text.  First, let's add the rectangle:

<s:Rect width="100%" height="100%">
	<s:stroke>
		<s:SolidColorStroke color="0x000000" weight="2"/>
	</s:stroke>
	<s:fill>
		<s:SolidColor color="0xCCCCCC"/>
	</s:fill>
</s:Rect>

Graphics are defined using the new FXG format.  It is similar to SVG, in that it is defined entirely in XML.  This new format is what allows the interchange between Flash Catalyst and Flash Builder 4 (and presumably Flash CS5).

Next, let's add the label control to display the Button's text.  The label must have an id of "labelDisplay" for this to work properly.  This is because the Button classes default skin expects a label control called labelDisplay (http://help.adobe.com/en_US/FlashPlatform//reference/actionscript/3/spark/skins/spark/ButtonSkin.html).  It should be noted that every skinnable component within the Spark framework has a default skin.  To replace this skin, you must implement all of the required properties.  Leaving the label control out, or not naming the label control correctly, does not cause any errors.  You simply won't see the text on the Button.  With that said, here's our label control:

<s:Label id="labelDisplay" width="100%" height="100%" textAlign="center" verticalAlign="middle" fontSize="12"/>

Assigning the label's width and height to 100%, while setting textAlign and verticalAlign both to their center values, will make sure the label is centered within our button.

Viewing the Button

In your Button's MXML code, you must define the skinClass it is going to use.  This looks something like this:

<?xml version="1.0" encoding="utf-8"?>
<s:Button xmlns:fx="http://ns.adobe.com/mxml/2009" 
		  xmlns:s="library://ns.adobe.com/flex/spark" 
		  xmlns:mx="library://ns.adobe.com/flex/mx"
		  skinClass="com.ninem.SparkButtonSkin">
</s:Button>

Place your newly created button on your main application, set the width/height and label properties, and hit go.  Your code should look something like this:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:ninem="com.ninem.*">
	<ninem:SparkButton width="100" height="50" label="Hello"/>
</s:Application>

You should see your label control in the upper left hand corner of your screen.  It works, but it has no states at the moment.  Let's work on that:

Reacting to Mouse Events

Let's define some simple styling to react to the mouse events a common button expects.  When we roll over, we'll make the text get a little larger.  And when the button's enabled property is set to false, let's make the whole button's alpha property drop to 0.5.

To make the text get a little larger when we rollover, it's as easy as adding one more property to our label in the skin.

<s:Label id="labelDisplay" width="100%" height="100%" textAlign="center" verticalAlign="middle" fontSize="12" fontSize.over="16"/>

You'll see that I added fontSize.over="16."  This will override the fontSize whenever the button is in it's over state.

To set the button's alpha to 0.5 when it's disabled, we add a property to the root of the skin tag.  "alpha.disabled" will set the alpha of the whole button when it enter it's disabled state.

At this point, your skin should look something like this:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" 
			 xmlns:s="library://ns.adobe.com/flex/spark" 
			 xmlns:mx="library://ns.adobe.com/flex/mx"
			 minWidth="60" minHeight="20" alpha.disabled="0.5">
	<fx:Metadata>
		[HostComponent("spark.components.Button")]
	</fx:Metadata>
	<s:states>		
		<s:State name="up"/>
		<s:State name="over"/>
		<s:State name="down"/>
		<s:State name="disabled"/>
	</s:states>
	<s:Rect width="100%" height="100%">
		<s:stroke>
			<s:SolidColorStroke color="0x000000" weight="2"/>
		</s:stroke>
		<s:fill>
			<s:SolidColor color="0xCCCCCC"/>
		</s:fill>
	</s:Rect>
	<s:Label id="labelDisplay" width="100%" height="100%" textAlign="center" verticalAlign="middle" fontSize="12" fontSize.over="16"/>
</s:SparkSkin>

So as you can see, skinning has drastically changed in Flex 4.  It may take some time getting used to, but it appears that the changes are for the better.  Your skins are now more modular, and more separated from your "business logic."

To get all of the code associated with this article, point your svn client here: https://code.9mmedia.com/svn/public/SparkButtonDemo/trunk/

Comments