return undefined;


Solid HRule/VRule in Flex

Posted in Flex by Ben Clinkinbeard on the May 1st, 2008

This was completely non-obvious to me so figured I would blog it. To create a rule more than one pixel thick of a solid color use this format:

Actionscript:
  1. <mx:HRule width="500"
  2.     strokeWidth="4"
  3.     strokeColor="#1278A7"
  4.     shadowColor="#1278A7"
  5.     opaqueBackground="#1278A7" />

opaqueBackground is the key attribute since by default (and counter intuitively) rules are actually borders around a transparent rectangle.

flexmdi sans MXML

Posted in AS3, Flex, flexmdi by Ben Clinkinbeard on the March 11th, 2008

Update: I have slightly modified the code below to correct a mistake in the original post. Thanks to Brindy for pointing it out.

Every now and then I come across a request of how to use FlexMDI using only ActionScript. Its completely straightforward but I have finally gotten around to getting an example up. The first code snippet shows how to do this while still utilizing MDICanvas for some of the convenience it provides.

Actionscript:
  1. import flexmdi.containers.MDICanvas;
  2. import flexmdi.containers.MDIWindow;
  3. import flexmdi.effects.effectsLib.MDIVistaEffects;
  4.  
  5. private function init():void
  6. {
  7.     var mdic:MDICanvas = new MDICanvas();
  8.     mdic.percentWidth = mdic.percentHeight = 100;
  9.     mdic.effects = new MDIVistaEffects();
  10.    
  11.     var win1:MDIWindow = new MDIWindow();
  12.     win1.title = "First Window";
  13.     win1.width = 300;
  14.     win1.height = 200;
  15.     mdic.windowManager.add( win1 );
  16.    
  17.     var win2:MDIWindow = new MDIWindow();
  18.     win2.title = "Second Window";
  19.     win2.width = 300;
  20.     win2.height = 200;
  21.     win2.x = 325;
  22.     win2.y = 50;
  23.     mdic.windowManager.add( win2 );
  24.  
  25.     var btn:Button = new Button();
  26.     btn.label = "Awesome Button";
  27.     win2.addChild( btn );
  28.    
  29.     addChild( mdic );
  30. }

This next example shows how to turn a basic Canvas component into the container for an MDI implementation.

Actionscript:
  1. import flexmdi.containers.MDICanvas;
  2. import flexmdi.containers.MDIWindow;
  3. import flexmdi.effects.effectsLib.MDIVistaEffects;
  4. import flexmdi.managers.MDIManager;
  5.  
  6. import mx.containers.Canvas;
  7.  
  8. private function init():void
  9. {
  10.     var canvas:Canvas = new Canvas()
  11.     canvas.percentWidth = canvas.percentHeight = 100;
  12.    
  13.     var mgr:MDIManager = new MDIManager( canvas, new MDIVistaEffects() );
  14.    
  15.     var win1:MDIWindow = new MDIWindow();
  16.     mgr.add( win1 );
  17.     win1.title = "First Window";
  18.     win1.width = 300;
  19.     win1.height = 200;
  20.     win1.x = win1.y = 10;
  21.    
  22.     var win2:MDIWindow = new MDIWindow();
  23.     mgr.add( win2 );
  24.     win2.title = "Second Window";
  25.     win2.width = 300;
  26.     win2.height = 200;
  27.     win2.x = 350;
  28.     win2.y = 100;
  29.  
  30.     var btn:Button = new Button();
  31.     btn.label = "Awesome Button";
  32.     win2.addChild( btn );
  33.    
  34.     addChild( canvas );
  35. }

Hopefully this clears up some of the uncertainty around how to use FlexMDI without our good friend MXML but feel free to ask questions in the comments.

flexmdi is now part of flexlib

Posted in Flex by Ben Clinkinbeard on the March 8th, 2008

This announcement got a bit lost in the shuffle at 360|Flex so I wanted to officially get it on the record. flexmdi is now part of the most popular Flex component library around and can be found in the flexlib.mdi package. We considered offering the library to flexlib when we first created it but decided to release independently and gauge feedback first. We thought maybe we'd get an invite to join flexlib and about 3 days after launch that's exactly what happened. Yea, yea, that was about 6 months ago, I know. Well, we finally got around to it and flexlib.mdi is our new home. While flexmdi has done very well on its own and its been downloaded about 8,000 times, joining flexlib will give the library even more exposure and chances to be seen and used. I think all told flexlib has been downloaded about 30,000 60,000 times.

So thats about it, just wanted to make sure those who haven't heard did and know what is going on. All future development will happen in the flexlib repository and any future bug and/or enhan cement requests should be submitted on that site. We will be porting the existing isues list over, eventually. :)

Creating bindable, calculated read-only properties in Flex

Posted in AS3, Flex by Ben Clinkinbeard on the March 7th, 2008

Binding to read-only properties in Flex takes a bit more work than one might think at first glance. There are two basic types of read-only properties in Flex: "variable backed" and "calculated". Can you guess which one we're going to discuss here?

Lets start by clarifying exactly what we mean by read-only property. The most basic description is when you have a getter but no setter:

Actionscript:
  1. public function get someValue():Number {...}

The variable backed version is when the getter is just a gatekeeper for a private variable:

Actionscript:
  1. private var _someValue:Number;
  2.  
  3. public function get someValue():Number
  4. {
  5.    return _someValue;
  6. }

The calculated version is a bit more complex and is generally either a combination of values like first name and last name or a value that requires calculation. The example we'll use here is a totalTime property of a Playlist. The totalTime is calculated by adding together the duration of all songs in the playlist at any given time.

OK, how?

By default you will get a warning telling you that the binding on a read-only property will be ignored (and whatever you've bound to it will indeed not receive any updates). The first part of enabling the bindings involves using metadata. Everybody knows [Bindable], but what we're looking for is [Bindable(event="eventName")]. That will essentially tell the compiler to dispatch a PropertyChangeEvent for the property (which is how binding works) any time an event of type "eventName" is fired. That brings us to the next step of firing the event. In our scenario of a calculated read-only property this needs to happen when one/any of our inputs changes.

Going back to the playlist example, a good time to let everyone know totalTime has changed is when a song is added. For the sake of simplicity that is the only scenario this example covers. I won't bother talking through the code in the example because it is very straightforward.

View the example and view the source and you'll see this is all very simple. I have included the classes generated by the compiler as well in case anyone wants to dig around. The magic seems to be injected from _CalculatedBindableReadOnlyWatcherSetupUtil.as but I won't claim to have a very solid understanding of how that all works.

I hope this will shed some light for somebody out there and maybe even come in handy if you're stuck. Binding to variable backed read-only properties has been covered by numerous other people and I would recommend learning about that as well. Enjoy!

Feedback from my session at 360|Flex Atlanta

Posted in 360|Flex, Flex, flexmdi, pointless blather by Ben Clinkinbeard on the March 5th, 2008

Following Adam's lead, again, I thought I would post the link to the feedback provided by people who attended my session last week in Atlanta. Tom and John rock the transparency vibe pretty hard so I figure its fitting for the speakers to do the same. This was my first time presenting at a conference and overall I was pretty happy with the outcome. I think the feedback stating it focused on FlexMDI a bit too much is probably valid and I apologize for that. My intention was simply to use it as a vehicle to illustrate the concepts I was discussing, I didn't mean to showcase it in any way. I'd also like to repeat that I was/am not the only developer of FlexMDI. It was a joint effort between myself, Brian Holmes and Brendan Meutzner.

View the feedback

Thanks to everyone who attended, even if you didn't provide feedback! Though I really like those of you who did :)

My slides from 360|Flex Atlanta

Posted in 360|Flex, Flex, flexmdi by Ben Clinkinbeard on the February 26th, 2008

I have posted a PDF of the slides from my presentation earlier today. The topic was Creating Flexible Components for Reuse and Distribution and we covered some things to keep in mind when creating components that you want to use across different projects and/or release to the public. There was a really good turnout and the material seemed well received. These slides aren't very detailed because I am a big believer in minimal amounts of text on slides but I think there is enough to make them worth posting. I settled for PDF because the rest of Keynote's export options kind of suck and its late. I'm tired. If anyone wants to add them to something like SlideShare feel free to do so and send me the link.

Panel on open source community projects at 360|Flex tomorrow

Posted in Flex by Ben Clinkinbeard on the February 25th, 2008

If you're at 360|Flex in Atlanta this week, we'll be doing a panel discussion of a bunch of different Flex Open Source projects in the hands on room tomorrow at 10am. I'll be there talking a bit about FlexMDI, there'll be folks representing other projects such as Degrafa, OpenFlux, FlexLib, Merapi etc... This will be a very open panel / birds of a feather style session. So, if you want to hear about an OS project or get some questions answered, come on over for the session.

(Description lifted from Adam Flater. I'm tired.)

Hope to see you there!

flexmdi 1.1 release - Enhancements and bug fixes

Posted in Flex, flexmdi by Ben Clinkinbeard on the February 12th, 2008

I just uploaded a new ZIP file to the flexmdi site. This release contains both bug fixes and enhancements, though the additions may be somewhat transparent to a lot of users. I did a pretty bad job of tracking which issues I fixed and closed during this update, but I think there were at least 20 of them. There were a few issues around focus and z-order that were fixed, support for basic truncation of window titles was added, did some general refactoring and MDIManager has a new enforceBoundaries property that when set to false will allow windows to be dragged partially outside of their container. The default value is true and MDICanvas has the same property which just acts as a pass through for convenience.

Window Controls

The biggest changes, however, are around styling and the layout of window controls in the title bar. The MDIWindowControlsContainer class is now the default class responsible for laying out things like minimize, maximize and close buttons. You can create subclasses of this class and then assign them to windows via the windowControls property to give your windows a different appearance. To do basic modifications you simply override the updateDisplayList() method like in any other component and flexmdi handles the rest. You can also override createChildren() if you want a set of controls that differ from the defaults. MDIWindowControlsContainer extends LayoutContainer, so you can set the layout property to achieve either absolute, horizontal or vertical layouts. The default is a horizontal layout like HBox that positions itself on the right side of the titleBar. You can easily implement different layouts though and we've included a couple of them in the examples.

Check out the updated explorer and use the styles dropdown on the top right to see examples what kind of different layouts are now possible. The Windows XP style just uses a different horizontalGap than the default layout but the Mac OS 9 style is significantly different. To lend more power to the layout containers, I also exposed the titleTextField of the windows (via MDIWindow.getTitleTextField()) which is protected by default and the titleIconObject (via MDIWindow.getTitleIconObject()) which is mx_internal by default.

Styling

The other significant work was related to default styling of the windows and implementing a system to allow easy overriding of styles. MDIWindow now has a windowStyleName property that allows you to point it to a master style that will be applied to that window. That style then points to substyles to allow fine grained control over individual aspects of window styling. You can of course also override styles by setting values inline via MXML attributes. A master style might look something like this:

Actionscript:
  1. .customWindowStyle
  2. {
  3.     styleNameFocus: "myWindowFocus";
  4.     styleNameNoFocus: "myWindowNoFocus";
  5.    
  6.     titleStyleName: "myTitleStyle";
  7.    
  8.     minimizeBtnStyleName: "myMinimizeBtn";
  9.     maximizeBtnStyleName: "myMaximizeBtn";
  10.     restoreBtnStyleName: "myRestoreBtn";               
  11.     closeBtnStyleName: "myCloseBtn";
  12.    
  13.     windowControlsClass: ClassReference("somePackage.MyCustomControlsContainer");
  14. }

I am planning on doing a post specifically about the new styling options but there are a couple of things to note here. styleNameFocus and styleNameNoFocus are just what they sound like. The styles they point to will be applied to the window depending on whether or not it has focus. (Which reminds me, there is now a hasFocus property on MDIWindow.) The other significant piece of the style declaration is the windowControlsClass style which, as you can see points to a ClassReference. This class will be detected and applied when the windowStyleName property is set, if necessary, allowing full control over window styling at runtime.

Default behaviors

The process for preventing/delaying default behaviors has also changed slightly. We have implemented the behavior described by Darron Schall here as it really is more proper than our initial implementation. The gist is that you now use event.preventDefault() instead of event.stopImmediatePropagation() and instead of storing the event for later execution you store a copy of it by using event.clone(). Darron's post is worth reading though so if you have time I would recommend getting the full scoop.

I think those are all of the major changes in 1.1 but I plan on taking a closer look at some of the topics in dedicated posts in the future. I've got a crazy couple of weeks ahead of me but I will do my best to get them up soon. If you have requests or suggestions for particular topics you'd like to see covered let me know in the comments. You can also find the full documentation here and as always, let us know what you think!

Universal-er Mind

Posted in Flex, Universal Mind, pointless blather by Ben Clinkinbeard on the February 11th, 2008

Today marks the beginning of my final week as a Fidelity Investments employee. I have accepted an offer to join Universal Mind, where I will get to focus on using Adobe Flex to build great software for their impressive client list. I am super excited and extremely honored that I will get to work alongside Darron Schall, Doug McCune, Adam Flater and a host of other wickedly smart people. I didn't even realize Darron worked for UM so imagine my surprise when I saw his name on the invite list for my Technical Interview. The dude has written a freakin' Commodore 64 emulator and a VNC client in AS3. I mean come on. He thankfully didn't ask me any questions about emulators though and I must have done alright since I officially start on February 19th. I can't wait to get started and begin contributing to the amazing team Universal Mind has assembled.

Note: The rest of this post is a fairly detailed explanation on my reasoning behind this move. I began writing it simply for posterity and my own benefit but after reading Ryan and Chuck's posts I suppose it can serve as another perspective/response to their discussions as well. If you could give a rat's bleep about my thought process (99.9999% of you by my estimation), you can stop reading now.

Leaving Fidelity was not an easy decision. In addition to the fact that I have made some very good friends and enjoyed the two years I spent there, its a very stable company with amazing benefits and they treat their employees extremely well. The company has also historically been very forward thinking when it comes to technology and continues to devote considerable attention and resources to IT, including a pretty significant adoption of Flex in several areas of the company. They were one of the first, if not the first, financial firms to use things like account management via automated telephone systems, the Web and data centers. Their web site(s) is/are still very good and are consistently rated the best in their industry. If you're like me and prefer to do just about everything online, (people still writes checks and mail them in envelopes?) I would highly recommend using Fidelity. The rare times you do have to call them you receive top notch customer service from knowledgeable reps. I can also say they are genuinely focused on making their customers successful and prosperous. So why am I leaving a company I obviously hold in such high regard? The department I work in has recently gone through a restructuring to more closely align with overall company goals, and as a result our Flex work has dried up. There is a lot of Flex work going on in other parts of the company, but that doesn't help me much. If I had stayed I would be doing primarily ASP.NET work for at least the next year, which is not something I am interested in doing full-time.

I decided to use that upheaval as a reason to look into the consulting world everyone has been raving about. As a husband and father I can only consider jobs that provide full benefits, and as a result have been watching the Flex consulting circus from afar for some time now with a mixture of jealousy and curiosity. Before the changes in my department, however, I couldn't justify leaving the position I was already in. I was working on cool projects that people actually use to do their jobs, was the go to guy for Flash and Flex in my department and I live less than 3 miles from work. I had also casually discussed jobs with a couple of consulting firms in the past, but for various reasons didn't feel like they were a good fit for me. Having heard good things about UM and seeing they had hired some real all-stars I decided to look into them a bit further. After sending my resume in I had an initial interview and then a second. The second was the Technical Interview I mentioned above and I have to say it was a blast. It was Thomas Burleson, Darron and Doug drilling me with questions for 90 minutes. Very cool, especially since I knew most of the answers. :) Throughout the entire process with UM, the people I dealt with were smart, passionate about their jobs and simply seemed like good people. What more can you really ask for?

I guess what it essentially comes down to is that I want to spend my working hours building killer Flex apps. When I finally started playing with Flex almost two years ago (Flex 2 Beta 2) it renewed a passion for learning and improving my skills that I hadn't experienced since first discovering Flash and programming in college. When you find something you enjoy this much, you want to do it as much as possible, alongside the best possible people, on the biggest possible stage. For me right now that is UM. My position at Fidelity is definitely what Chuck refers to as a "career job" in that I could work there for another 30 years and retire somewhat early and be very comfortable financially. In the end though I felt like I am young enough and its early enough in my career that I want to take on a new challenge. Out of college I worked in a very small design agency (I was employee #5 when I started) and then moved on to Fidelity where last I heard there are about 46,000 employees. I feel like consulting via UM will allow me to experience a lot of the shades of gray between those two extremes while retaining the relative security of full-time employee status. It also gives me an opportunity to work alongside people I can learn (a lot) from. Don't get me wrong, I worked with a lot of smart people at Fidelity who could teach me volumes on a variety of topics, but when I hit a brick wall with a Flex problem there weren't a lot of internal resources to turn to. Not so at Universal Mind. Their existing team reads like a virtual who's who of the Flex community. Now my problem won't be getting an answer, it will be trying to not look like an idiot in the process. :)

So to everyone at Fidelity, best of luck and thank you for the past two years. I thoroughly enjoyed and genuinely appreciate everything I experienced there. Hopefully our paths will cross again at some point down the road.

To everyone at UM I can't wait to get settled, meet those of you I haven't, and start building first class Flex applications with you. The industry is on fire, lets get our gas cans.

I guess donating code isn’t enough anymore

Posted in Flex, flexmdi, pointless blather by Ben Clinkinbeard on the February 4th, 2008

The following is an unedited email thread I have had with a reader over the past week or so. I helped him learn how to add a SWC to a Flex project but apparently that (and FlexMDI) wasn't good enough. The quotes next to the green bars are mine.

Update: I have decided to remove Keith's identifying information from this post. While I haven't received any kind of apology from him, as one commenter pointed out some employers could deem his behavior enough to warrant termination from a job or perhaps prevent the acquisition of a future job. Nothing of that magnitude was what I intended by publishing this. I was simply trying to point out two things. One, don't be ungrateful, especially when getting something at no cost. Two, just because you're communicating "on the internet" doesn't mean its OK to be a jerk, and your actions may very well become public knowledge. I think this post still accomplishes its goals without his info. So you're welcome Keith, again.

Hey Ben,

Thanks again for all the help in getting the demos to work. As I mentioned in my last post the only problem I am having now is trying to get the maximize and minimize events to work. When I add one of them to a I get "Event type 'mdi.events:MDIWindowEvent' is unavailable"

Any ideas??

Thanks,

Keith

Not sure what you mean exactly, can you show some code?

sure
... code snippet ...

When I compile that I get "Event type 'mdi.events:MDIWindowEvent' is
unavailable" on the MDIWindow code. If I remove
the "maximize" event parameter it compiles and runs fine.

Sorry, I dunno. Maybe try importing MDIWindowEvent?

Ben

Sadly it already is. I just took the sample code and added the maximize parameter.

So its just the explorer with one attribute added?

Any idea ?

Sorry, I don't really have time to investigate right now. I would suggest posting your issue on flexcoders.

Ben

Lol. Ok. I didn't realize they would comment on 3rd party code. I apologize -- I thought you were one of the developers of this component.

No problem, I am, I just have a lot going on right now. Sorry.

You knoiw what never mind. Pisses me off to no end when a developer won't take the time to troubleshoot his own code. I'd fire you if you worked for me. Guess now that its published and the articles have been written and your presentations made you don't give a flip.
There is a another component someone else wrote. I'll just check it out instead.
Maybe I will post to flexcoders and explain that the person who helped write it wouldn't take the time to help out. Yeah that should look good.
Thanks for ummm.. Well nothing I guess. Enjoy

Wow, you're amazing you know it? I have a family, a full-time job and other shit going on, I've spent countless hours writing the code, written articles, answered several questions on my blog (including yours) and on flexcoders, and because I don't have time to investigate your question right now that makes me a bad person/developer? You've been given a very good library for zero cost and you throw a temper tantrum because I can't personally investigate your issue? Why can't you post to flexcoders? Shit man, put forth some effort! The code has been downloaded over 6000 times and nobody has ever reported this issue. Doesn't mean its not a valid problem, but asking you to do a little bit more than flood my inbox whining that it doesn't work is a reasonable request. Please do post your complaint to flexcoders. Please.

Jeez man, you couldn't be more unappreciative. What exactly makes you feel entitled to free code plus support? Tell you what, send me $100 and I will be glad to investigate your issue personally. After all, I am sure you're getting paid for the project you're using our code in, so lets be fair and share the wealth. Right?

Unbelievable.

Ben

« Previous PageNext Page »