« August 2007 | Main | October 2007 »

September 2007

September 28, 2007

Programmatically Set Skin

This was such a simple solution but it took me an half hour to figure out. I thought others might struggle with it as well. Actually I’m kinda hoping others do too, so I don’t have to be alone with my utter ignorance. I created a custom class and wanted to provide it with a custom borderSkin.

I’d love to hear it if there’s a much better way. Always setting the borderSkin in the constructor is probably not the best way to go about it. But I’ll use it till somebody much smarter than I comes along and tells me how it is.

 

public function MyCustomClass():void

{

this.setStyle("borderSkin", MyCustomBorderSkin );

}

September 25, 2007

The need for smarter flex controls.

If you saw some of the junk I have to deal with in our database you’d probably laugh, and if you didn’t it’d because you’re in the same boat as me. I constantly have to deal relational mapping or database compatiblity issues. It seems over the years, whether out of need or some sort of creative insight I apparently lack, my database forefathers have come up with the following list of things that represent a boolean.

True : 1,”A”,”YES”,”Y”,”Active”

False: 0,”I”,”No”,”N”,”Inactive”

Now, of course all those strings are not case sensitive, and are stored as such things as “Active” and “active” depending on which way the wind was blowing when the developer wrote it those many years ago. Almost always I display a boolean value as a checkbox. And so I’d like my checkbox to take all of those values, display it as either checked or unchecked and then spit out a corresponding value when I submit a form. So, if the value went in as “Y” and the user unchecked the box, I should get a “N” when I inspect the value.

 

1. I extended CheckBox

2. Created a variable called values that will house the two options that get returned  

3. Because I want to pass in something other than a boolean, I can’t override the public selected setter found in the mx.controls.checkbox. ( overloaded methods would be nice ). Instead I created a setter called checked that takes type Object, does a switch on the value and sets whether it’s selected or not and also the values array.

4. Finally I create a getter called value from which i can read the correct type. It reads from the values array, where the first index is returned on true else the second index is returned.

 

Overall, the code is fairly simple and extensible. The only reason I’m blogging about this is because I’d like this kind of functionality out of the box from the flex framework. We do alot of bait n’ switch with data. We support a huge legacy Oracle database and we don’t have much of a choice. Flex is all about the ui, should that include making it easier on the developer to create the ui.

 

I’d love to see how other people are handling these types of situations. Just as a note, before this I was running my values through a function.

 

 

// default to use 1,0

public var values : Array = [1,0];

public function set checked(value:Object):void

{

switch(value)

{

case "Y":

case "N":

this.values = ["Y","N"];

this.selected = (value == "Y") ? this.selected = true : this.selected = false;

break;

case "A":

case "I":

this.values = ["A","I"];

this.selected = (value == "A") ? this.selected = true : this.selected = false;

break;

case "Yes":

case "No":

this.values = ["Y","N"];

this.selected = (value == "Yes") ? this.selected = true : this.selected = false;

break;

case "Active":

case "InActive":

this.values = ["Active","InActive"];

this.selected = (value == "Active") ? this.selected = true : this.selected = false;

break;

case "true":

case "false":

this.values = ["true","false"];

this.selected = (value == "true") ? this.selected = true : this.selected = false;

break;

default:

this.values = [1,0];

this.selected = (value == "1") ? this.selected = true : this.selected = false;

break

}

}

public function get value():*

{

if( this.selected == true)

return values[0];

return values[1];

}

 

September 18, 2007

moxie killed the flexmdi star

Just to let everyone know, we compiled the flexmdi lib with moxie ( actually I did it, so you can send hate mail my way ) so it’s throwing erros with flex 2.01. This will be fixed shortly and we’re going to compile it with flex 2.01 till 3 is released.

 

Tags:

Sweet Flex Translations 2 ( or meet flexlingo)

After having spent alot of time over the course of the last month working within the confines of the flex ResourceManager I decided to throw my hat into the language localization ring, toss out my never ending supply of property files and @ResourceManager(bundle=’hacked’, key=’up’) looking mxml code and try to come up with something more practical for application translation.

I know I blogged earlier on this, but I might’ve jumped the gun a bit with that post so this is an attempt to steer a bit back onto course with what I’m looking for. First, I want to point out that I’m not looking to replace the Resource Manager. I’m much more interested in just managing the language and formatting without having to actually do anything and so to define my practical implmentation I came up with the following ordered list:

1. Components should know what properties they show that can be translated.

2. Developers shouldn’t have to worry about implementing anything to actually perform the translation. ie. knowing what bundle and key they need for a label field. Nor should they have to compile different swf’s to implement different languages.

3. There needs to be a common way to collect, display, translate and save phrases that are a part of the interface. Which includes auto generating a key for the phrase. If you’ve ever dealt with localization you know that there’s just no good way to do this and that translations are usually done somewhere between dev and test.

4. Translation’s should be able to be saved within a database, xml, text, property files or whatever throws your hair back and floats your boat.

 

Now, this all sounds very simple. And indeed it should be, ultimately with language and formatting we’re just talking about strings. A compile time option to output these into a file that could be then imported into a database would be sweet. But doing the translation at runtime will work just as well. And I was slightly amazed at what I was able to get working.

So, meet flexlingo , ( srcview ). There’s no ResourceManager to deal with. You don’t have to know what key outputs what string. Look at the source code and you’ll see only clean looking mxml. I’ve identifed strings that host phrases that can be translateable and have my flexlingo manager collecting them. Anyways, I have more to work on before I release the code. I need to build some admin screens that developers can give translators acces to allow to translate the phrases within the app and allow devs to send it back to the db for storage. I also need to incorporate more components into it as well to make sure everything’s getting picked up properly.

 

p.s. And I apologize if my demo translations doesn’t actually make sense when translated. I used an online translator to get those phrases so I don’t actually know what the actual translations are.

 

 

September 17, 2007

Using Cold Fusion onRequest and flex remoting

If you want to use the Application.cfc onRequest method for processing .cfm pages and at the same time want to have sub directories for .cfc’s that serve as web services or methods for flex remoting it is possible.

I know there are a bunch of posts that show how to do this and so I thought I’d point out that my work around takes the reverse approach than what I’ve seen on other blogs. It basically adds those methods into the variables scope to be called if it doesn’t find a .cfc in the page name. You could obviously look for whatever you needed in that <cfif> statement, and I actually use it to look up the word “api” in the CGI.HOST_NAME variable which is where I route my flex remoting calls.

 

 <cfif not findNoCase("cfc",SCRIPT_NAME)>
   <cfset variables["onRequestStart"] = variables["onRequestStartHandler"] />
   <cfset variables["onRequest"] = variables["onRequestHandler"] />
   <cfset variables["onRequestEnd"] = variables["onRequestEndHandler"] />
 </cfif>

 <cffunction name="onRequestStartHandler" access="public" returntype="boolean">
 
  <cfreturn true>
 </cffunction>
 
 
 <cffunction name="onRequestHandler" access="public" returntype="boolean">
 
  <cfreturn true>
 </cffunction>
 
 
 <cffunction name="onRequestEndHandler" access="public" returntype="boolean">

  <cfreturn true>
 </cffunction>

Tags:

September 14, 2007

Sweet Flex Translations

So, imho, the flex Resource Manager is cool, I mean that with all do respect, that is if you’re down with doing a lot more work than is necessary. Who besides Java purists save thier language translations in a  (.) properties file? And why would I want to even do that? I then have to make sure I keep a common naming convention with underscores and names and also not to mention the @Resource tag. It seems like twice as much work as is needed to be done.

I think there is a need for the ResoureManager, but it’s responsibilites should only include resources such as images and sound clips. Languages should be split up. At the very least there should be an option in the flex compiler to output .properties files.

So I took the liberty of creating my components that support rutime language translation. They are not complete but if I can work them out I’ll release them along with examples and translation forms that allow translators to do thier thang. At least as a good starting point for other developers who are facing the same problem.  In fact, if anybody out there wants to start a business up that caters to translating flex applications shoot me an email and let me know.

 So here is a link to my example.

http://www.mxmvc.com/translations/SweetTranslations.html#

(right click to view source)

The logic is that there are a certain number of components such as Button, Label, Panel (as in the title) that need translations done on thier labels or titles or other fields. The components themselves know this and add thier respective property fields to a LangManager that removes all special characters and creates a key with underscores (_). Phrases without translations default to whatever was put in the property so the label=”submit” would still be a “submit” if there wasn’t a “Someta” and the language was Spanish. Translations can then be done on these phrases. This can happen at runtime, the translations should be able to be stored in a properties file, or an xml file or where it seems just about everyone stores everything: a database. There also should be a caching mechanism on the client that stores common translations so that they are readily available.

There are alot of questions to answer about this however, like what if you don’t want it managed for translations. And how much overhead will this cause when dealing with very large applications?

 

Yes I know that that the grid headers don’t translate, but they should and if anybody can help me understand why it’d greatly be apprecated. I also had to turn the creationPolicy=”all” on the tabnavigator to get them to translate. I purposedly left out the components that are doing all the work because they aren’t finished and also because I wanted you to focus on what might be: and by that I mean that if you look at the source which can be found here youll notice that the mxml implemenation of the components are in no way modified or decorated with @Resource tags. They shouldn’t have to be.

 I’m lagoing to blog more on this latter when I have more to show and maybe a better understanding of what needs to be done to make runtime dynamic translations as dynamic and feasible as possible.

flexmdi Taskbar Proof of Concept

So this is just a proof of concept that I threw together. It’s a rough implementation of the taskbar concept. This functionality is something we’ve talked about implementing although no word on a time frame yet. But if someone can grab the concept and incorporate it into the library be sure to send it our way and we’ll give credit where credit is due. What needs to be done is seamless implementation into the flexmdi library that doesn’t require all the hoops I'll now jump through for you. Not that there are alot of hoops, it’s actually quite simple.

I didn’t touch anything in the flexmdi library to create this btw. In a nutshell the logic goes as follows.

1. when a window is minimized we want to remove it from the screen and add it to the taskbar after any effect has played.

2. when a taskbar item is clicked we want to remove it from the taskbar and add it back to the screen.

To do this I'm simply capturing the window minimize event, setting visible to false, then creating a taskbar item which i then add to an array collection bound to the dataProvider of a horizontal list.

When the task bar item is clicked, I'd simply setting visible to true, then broadcasting the MDIWindow restore event.

See It In Action

View Source

 

We’re going to be working on this more in the future, so any requests and/or help is greatly appreciated. And yes I know the buttons don’t show up on restore, but since our launch of the flexmdi library we’ve got a considerable amount of requests for this to be implemented by default. So I thought I’d throw this out there for now while we work on incorporating it.

 

you can get the flexmdi framework at http://code.google.com/p/flexmdi/

 

Happy Ctrl+B

 

 

September 11, 2007

creating custom buttons for flexmdi

Currently the flexmdi MDIWindow class does not have a way to completely override the default buttons and behaviours in one fell swoop. This should be changing by the release of flexmdi 2 which is scheduled for Adobe MAX 2007 in Chicago.

For most developers adding one or two different buttons is all that will be needed. And this is done quite simply.

You will need to to:

1. create your own Window class that extends MDIWindow

2. override protected function createChildren()

3. create your button and add any listeners you want on it

4. add it to the button contols by calling the addControl(btn,index) of the MDIWindow class.

 An example can be found here :

http://mxmvc.com/flexmdi/explorer/MDIExampleAddButtons.html

flexmdi Effects

The flexmdi framework provides extensibility to customize the effects on your windows. To implement your own custom effects you will use the following two classes:

flexmdi.effects.IMDIEffectsDescriptor which is the interface used to describe the contract between MDIManager and the effects it applies on windows in relation to events that take place such as minimize(), maximize(), tile() and cascase().

flexmdi.effects.MDIEffectsDescriptorBase is a base class that is defined that you can extend so that you only have to implement the effects for the MDI events you want to without having to implement the entire interface.


As the name implies effects are implemented as descriptor classes, which allows you to describe the effects you wish to take place when a certain event takes place. For example the FlexMDI framework broadcasts a minimize event which takes place when a window is minimized. To implement an effect on minimize you would  use the getWindowMinimizeEffect() which can be implemented like:

public function getWindowMinimizeEffect(window:MDIWindow, manager:MDIManager, moveTo:Point = null):Effect
{
    var parallel:Parallel = new Parallel(window);
    // add effects to parallel here
    return parallel;
}

Look to the interface to  provide information on what kind of data is getting passed from the manager. Not all scenarios are the same and in fact the effects are broken down into two groups. Window Effects which get  passed a window instance and relevant information such as where you need to move the window and Group Effects which get  passed an array of GroupEffectItems  that hold a window instance and resize and move to data. The difference is that a window effect gets applied to one window like minimize() or close()  as where a group effect gets applied to all windows as is the case when you tile() or cascade().

Our goal was to have the manager do the math and the effects to make things look pretty. We've tried to make it as extensible as possible and we have covered a lot of scenarios. Ben Clinkinbeard wrote a good article about how to override default behavior that can be found here  which will allow you to do things as stop effects before being played so you can implement custom business logic.

We're just getting started posting examples so if you're unsure about how to implement something be sure to let us know so we can make things more clear and easy for developers to use.

An example of the flex mdi explorer can be found here .

The flexmdi framework can be found at http://flexmdi.googlecode.com/ 

Tags:

Brief intro of MDIManager

The flexmdi MDIManager is at the heart of managing the mdi windows. It's responsible for adding, removing, tiling, cascading, whipping, selecting, announcing, berating, belittling, restoring and the all-in-all keeper of the watchtower so to speak. Apart from a little math, it doesn't do much besides route windows through the appropriate processes. But when looking to extend functionality of the flexmdi framework it should be in the back of your mind. Knowing how to use it will open a lot of possibilities up.

Events and Scope

Always look to the manager when you want to manage all windows at once, or set global or instance level handlers. If you wanted all your windows to display a confirmation box upon close you could set this once on the manager. If you wanted to set default positions for your windows when added or apply an effect to certain types of events such as minimize or restore you could set this on the manager. The manager is also responsible for applying group events. A group event takes place at the manager level and applies to all windows such as cascade and tile. The manager is also the place to intercept window events  to change default behavior. You can apply a context menu for the container on the manager as well.


Infinite Managers For The Price of One

The managers is the master of context. As a convenience it has a global application manager that can be accessed with MDIManager.global which uses the Application.application as it's container and adds windows via the PopUpManager so graciously provided by the flex framework. But the manager can also be confined to manage windows in any type of container. As an example, if you were to create a viewstack you could have a manager for each parent level container in the view stack which would allow you to hide,show,maximize,restore,tile,cascade, etc.., windows at the viewstack level and  allow your  users to  switch back and forth for some free stylin' window management. To create a local instance of the manager you just need a to have a container for it to manage:

public var manager:MDIManager = new MDIManager(myContainer);

From this point any windows you add to manager will be managed within the confines of myContainer. You can also pass an effectsLib class to the manager as well. (more on that in a later post).

Summary

Personally I think of the manager as the name describes as the man in charge of the action. Managing windows on a more global or container level allows you to only write the code for the special short bus windows when you have to. Less code to write is good. As always look in the docs to find the details.


and example of flexmdi can be seen here .

you can find the flexmdi framework at http://flexmdi.googlecode.com/