One great thing about Flex 3 is the ability to assign multiple states (up, over, down, disabled) to a component using just one Flash asset. In Flex 2 you had to create separate symbols and assign them individually with CSS or in MXML.
Earlier this week I was converting an old project from Flex 2 to Flex 3 and I bumped into a problem: assigning stateful skins didn't work anymore. After playing around with the CSS I found out that when a class already has skin states assigned to it in the old way, assigning a "skin:" property to an instance of that class will have no effect. For example, if you had stylized your application's Button with this:
and you wanted a specific button to look different like this:
the myDifferentButton style will not show up unless you do this:
But the solution is really to get rid of all instances of the old way of skinning so that instance always override the default class styles.
I ran into an issue with a data grid and an item renderer. Hopefully this post will help some poor soul out there struggling with the same problem. So how did it all start?
I had a simple datagrid populated with data and specific selection and rollover colors. On mouse over the appropriate selection color and rollover color were displayed on that particular row of the datagrid. I needed to add an image next to the text of the first column. It turned out that after specifying an item renderer for the first datagrid column my text rollover and selection colors did not take effect any longer.
After some browsing around I found the solution was to create a custom item renderer that implements the IDropInListItemRenderer interface. This interface adds a getter and a setter for a property called listData. By overwriting the validateNow() method you can use the listData property to check if the current row is highlighted or selected, then set the correct color of the text.
Look at the example below. You can right click and select View Source to check out the source code. Also you could download the project from svn.
There's been some buzz lately about this new Flex framework called Mate.
But I already have a framework, you say. Why would I want to bother with a new one?
Well, I hear you, we're pretty settled in with PureMVC and happy with it. But Mate is still different enough to warrant checking out.
It's tag based so you create all your files in MXML. Basically all you need to create is an Event Map MXML file, dispatch an event, and add handlers in the Event Map to tell the app what you want it to do when that event is dispatched. Once you include the event map in your Application.mxml you're good to go.
Good documentation and examples too. Overall, it seems fairly simple and straightforward, definitely one to keep an eye on.
In the Build path in the flex_framework project properties set the "Main src folder" to "src"
Then in the same screen check off just the class FrameWorkClasses to be included in the library
Then you add this project to your current projects library path In project->properties->Flex Build Path->Library Path, click "Add Project" flex_framework should be an option.
Check that you can build.
Check that you can open a framework class and set a breakpoint. (ie, hit cmd-shift-r, type Container...put a breakpoint in the constructor)
For the real good stuff, you can start adding all the other projects in http://opensource.adobe.com/svn/opensource/flex/sdk/tags/184.108.40.2067/frameworks/projects . Just follow the above instructions, but replace "framework" with any of the projects. If you are using remoting, rpc is a must. I haven't played with any of the others yet.
Not uncommon for Flex super heros like ourselves, we haven't needed to occupy our time with the smaller details of web development. Databases you ask? That's the job for our side kick, backend dude. We've got interactivity and usability to deal with. But when Adobe Air arrived in our tool-belt, we had no choice but to suck it up and learn...SQL statements! Here' a tutorial on how to create a to-do list with AIR.
What we're going to build is a basic item list that looks like this:
Or if you just want the Air application, click here:
Please upgrade your Flash Player This is the content that would be shown if the user does not have Flash Player 9.0.115 or higher installed.
I do prefer and recommend the Firefox plugin. It has a Browse & Search functionality making it easier to display rows in a table. In contrast Admin-for-Air is less robust and will be harder to use for beginners. For example in order to browse a table, you write your own query (eg.: select * from myTable). Not hard, but intimidating for newbies.
Item List Tutorial
Opening the Database
The first thing we want our Application to do is open a SQLConnection with a database file.
If the file doesn't exist yet, it will be created with the name you specify. Otherwise if you have already run the application before, it will open the existing file.
Where is the .db file stored?
The recommended location to store the .db file is in your Application's storage directory. Its important to know where this location is on your local machine. We will be using it to point your SQLite browser to this file.
On a Mac: /Users/yourname/Library/Preferences/applicationName/Local Store/file.db
On a PC: C:\Documents_and_Settings\username\Application Data\yourAirAppName\Local Store\test.db
If you're having trouble finding the file, or for testing purposes, try storing the file on your desktop by changing the resolvePath call to:
Asynchronous vs Synchronous connection
You might have wondered about this line: sqlConnection.openAsync(dbFile);
Air gives your application two options to connect to SQLite.
Asychnronous means that your code will have an event listener on the SQLConnection and an event handler for the response.
Synchronous means that your application will make an "inline" call to SQLite where it performs the operation and then moves on as if it were any other line of actionscript code.
Synchronous uses less lines of code, but could potentially stall your application if its trying to process a large dataset. Asynchronous on the other hand will allow your application to continue running and SQLite will return operations when it has completed them.
For example compare the two trace statements below: ASynchrononous:
If one doesn't exist, the sql text will look like this:
(Don't forget, to see all the code checkout the project with SVN here)
Note on SQL statements for the unfamiliar:
Think of an SQLStatement as a string with directions on what you want SQLite to do. Air Documentation provides a list of supported SQL syntax. Most of this is useful for someone familiar with SQLite, but admittedly, I'm not one of those people. Below, I've written basic SQLStatements that get the job done.
If you need help, hopefully you have a backend dude to refer to. If he or she have questions about what SQLite supports, refer them to the link Otherwise, feel free to post a question in our comments.
Insert an Item Into our table
Our SQLStatement looks like this:
Note the ? mark in the INSERT statement. This is a sqlStatement parameter. Parameters are used to allow for typed substitution of values that are unknown at the time the SQL statement is constructed.
In this case it is our Date so that we can record when this item was added.
To read everything in your Table
You use the SELECT Command:
The listener then gets the results by calling the getResult() static method. This method returns a SQLResult object. The results are included in the data property.
When we add an item, we will also want to display it in our DataGrid. Although the new item isn't returned with the SqlResult, a rowID is. The rowID is the Primary Key we set when creating the Table. If you don't set a Primary Key or have multiple Primary Keys, Sqlite will create a rowID behind the scenes which relates to the affected row. With the rowID we can then make another SELECT call like so:
-execute(1) is a bit redundant but I'm using it show that if you want to control the number of rows returned, this is how it's done.
I recommend diving into the project and opening my SimpleConnection class. Run it along side your Sqlite browser and watch it go.
Congratulations Flashy Super hero, you are on your way to defeating the Mad SQLite Golem. I'd also like to thank John, our trusty Java-dude, without whom I would have never been able to write these SQL statements, as basic as they are.
Where to go next:
Ok, I've shown you how to Read and Create. How about Delete?
Look into Wrapper classes. I've tested a couple. Peter Elst has a nice blog post. I've also had limited success but am curious about the Air Active-Record code.