Posts in Category "Uncategorized"

Drag and Droop

The database has been created and an interface class (DAO) has been created.  Now I need to get some data into the system. To do that I need some kind of data input screen that will take in text and multimedia files (images, videos, etc.)  In the interests of making things easy on the user I didn’t want to use an open file dialog.  I find that they are unpleasant to use, especially for non-technical users.  Drag and drop is much more intuitive.

According to the hype, it’s very easy to drag and drop files from a user’s desktop into an AIR application. I figured a five minute Google would give me a dozen or so examples of how to do it.  Well, yes and no.  There were many examples (875,000 returns on AIR drag and drop), but most were written for the Beta versions of AIR.  It seemed like every sample I found used the DragManager object which (I found out later) was transformed into the NativeDragManager object when AIR was released.  Other samples were so complicated that peeling back the layers to a simple sample took more time that it was worth.

What I need to do is really quite simple.  Have an image field onto which a user can drag and drop an image file.  Once the file was dropped onto the field I want the image to change to the new one and the file contents to be available in binary form.  The last requirement is so the file can be uploaded to the database.

Step 1 – Create a target for the operation – an image field:

<mx:Image x="10" y="10" id="displayImage" source="DropHere.jpg"/>

Step 2 – Add a listener for both the drag and the drop operations. This was done by adding a simple function that is called on the createComplete event of the canvas:

public function initDrop():void{
//Listeners to manage the drop of files on the first panel
 displayImage.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER,acceptDrag);
 displayImage.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP,dragDrop);
}

Step 3 – Add some code to allow the drag operation. Nothing too complicated here; its just a function that allows the drag operation into the image field:

//Accept drag and drop on the first panel
public function acceptDrag(event:NativeDragEvent):void{
        NativeDragManager.acceptDragDrop(displayImage);
}

Step 4 – Add some code to handle the drop operation.  Here I want to change the image to the new file and to put the contents of the file into a byte array.  To prove to myself that it was working, I echoed the file size to the screen.  This will be replaced later with a call to the DAO for a database update:

import flash.filesystem.File;
private var imageBytes:ByteArray = new ByteArray();  //the byte array can not be null!!!

…..

//On drop collect the files
public function dragDrop(event:NativeDragEvent):void{
        var imageList:Array = event.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
        var droppedFile:File = imageList[0];

         //load the file into the image
        displayImage.source= droppedFile.url;                             

        //get the byte array for the image
        var fileStream:FileStream = new FileStream();
        fileStream.open(droppedFile, FileMode.READ);                         

        fileStream.readBytes(imageBytes);
        fileSize.text = imageBytes.length.toString();             

   }

There are a couple of things to note about the dragDrop function.  First the result of the drag and drop is always an array of the files.  This is because the system allows you to drag more than one file at a time (very useful in some circumstances).  I took the cheap and cheesy route of just using the first element in the array.

Second I’m not using a Loader object to change the image contents as is suggested on many web pages.  I tried this at first and the image was not replaced, but instead the second image was overlaid on top.  I fiddled around a bit with the image layers but I couldn’t quite get it to work properly.  Simply re-setting the image source was a simple solution to the problem.

There you go.  Not much to it, but it works well and functions properly with the 1.0 release of AIR.

I split this bit of the application into a separate app so you can download it without all of the rest of the overhead.  You can find it here.

Feed the Beast

Working with the local database can be a bit of a challenge.  If the db is not well organized and if your application structures are not well thought out then you can end up with a real mess.  As I said before, sitting down and thinking the data layout all the way through and performing a few simple normalization exercises goes a long way to making the db construction a lot easier.

Knowing how AIR interacts with the local SQLite database helps as well. Essentially there are three parts to an AIR database setup:

  • The SQLite database
  • A class to interact with the database
  • Classes to hold the results of a database query

The SQLite database

AIR uses SQLite for a local/offline database.  SQLite is a very easy db to work with, but its pretty Mickey Mouse in a lot of respects.  For example there is no true auto-increment feature so the developer has to handle record id generation him/herself.  Also there are no foreign keys which means that most relationships between tables must be handled by the calling application.  How can you call yourself a relational database when the major function for controlling relationships does not exist?!

One tool that anyone working with SQLite databases must have is a database management tool. Sometimes you just need to have a look at what is going on inside the database itself.   There are a few out there for SQLite, but one of the most useful is a simple plugin for Firefox.  SQLite Manager has many useful features including a simple SQL execution tool, that will make your SQLite development much easier.  Go get it!

The nice thing about using the built in SQLite database is that you don’t need to mess around with a lot of connection properties.  You just point to a .db file (or create one) and away you go. You can concentrate on working with your data instead of trying to find the database.

Database Interaction Class

To make life easier I re-used a standard J2EE pattern for database connectivity – the Data Access Object (DAO).  A DAO is nothing more complicated than a class that acts as an interface between the AIR app and the database.  This way all db interactions (connection, queries, inserts, etc.) can be centralized and the rest of the AIR application doesn’t need to deal with the db trivialities.  The db structure can also be changed without having to rewrite the entire application.

The first thing that I needed to do was to connect to the database – actually before that I needed to check if the database exists and if not then create it.   I did this in the constructor for the DAO class as it only needs to be done once.

//private vars
private var _dbExists:Boolean;
private var _dbConnection:SQLConnection;
private var _createFlyTypeTableStmt:SQLStatement = new SQLStatement();

……..

public function LocalDAO(){
   _dbConnection = new SQLConnection();

  
// Add event listeners to react when database connection is opened.

  
_dbConnection.addEventListener(SQLEvent.OPEN, openSuccessHandler);
  
//_dbConnection.addEventListener(SQLErrorEvent.ERROR, openErrorHandler);

  // The database file is to be stored in the user’s application (UserData) folder.
  
var dbFile:File = File.applicationStorageDirectory.resolvePath("FlyData.db");
  
trace("Database file location is: " + dbFile.nativePath);

  
//Check if the database has already been created.

  
_dbExists = dbFile.exists;

  //Open the connection.
  
_dbConnection.open(dbFile);
}

The nice thing is that if the FlyData.db database file does not exist then one will be created for me. 

The openSuccessHandler listener will wait until the db is opened (or created and opened).  If it is newly created then I want to create the tables in the database as well.  The listener will then call a method called initDatabase that will fire a bunch of CREATE SQL statements. Most interactions with the database happen via a SQLStatement, through which you pass standard SQL queries as strings.  The SQLStatement is pointed to the correct database using a SQLConnection object.  

/**
* Success handler for _dbConnection
**/

private function openSuccessHandler(event:SQLEvent):void
{
    //We have an open handle to the database file.
    //Next, we need to create the tables if this is a new database

    if(_dbExists){
          trace("Application Database already exists.");
    }else{
         trace("New Application Database, must generate tables");
         initDatabase();
    }
}

private function initDatabase():void{
    _createFlyTypeTableStmt.sqlConnection = _dbConnection;

   
//Create the database tables

   
var sql:String = "CREATE TABLE `Material` (`MaterialID` INTEGER UNSIGNED NOT NULL, `MaterialName` VARCHAR(45) NOT NULL,`Color` VARCHAR(45) NOT NULL, `Size` VARCHAR(45) NOT NULL, PRIMARY KEY (`MaterialID`))";
   
_createFlyTypeTableStmt.text = sql;
   
_createFlyTypeTableStmt.execute();

//more create statements follow …..

Great, now the database exists, has been connected and I know for sure that I have a table structure.  Next I need to be able to select and insert records.

Query Results Classes

You need to have a place to put the results of a search.  In Java you have a result set that you can parse for specific db columns.  In AIR the execution of an SQLStatement returns an array of objects.  The objects must match the structure of the query exactly (and I do mean exactly).  Therefore, for all practical purposes, you need to have a class for each database search – one for each table (or one that matches multiple tables in the case of a join).

The next thing to do then is to create classes for each of the possible searches.  In my case this means that each table will need a corresponding class.  For example I have a table called Material that has a MaterialID, MaterialName, Color and Size.  I therefore need a class that has all of those elements:

package components.dataStructures
{
   public class Material    {
      public var MaterialID:int;
      public var MaterialName:String;
      public var Color:String;
      public var Size:String;

   public function Material(){
   }

  }
}

When I perform a query against the Material database the result will be mapped into an array of the class Material:

public function getMaterials():void{

    _dbMaterialStatement.sqlConnection = _dbConnection;
    var sqlQuery:String = "SELECT * FROM Material";
    _dbMaterialStatement.itemClass = Material;
    _dbMaterialStatement.text = sqlQuery;
   //SQL calls are asynchronous so a listener for the results is required
    _dbMaterialStatement.removeEventListener(SQLEvent.RESULT,onDBMaterialSelectResult);
    _dbMaterialStatement.addEventListener(SQLEvent.RESULT, onDBMaterialSelectResult);
    _dbMaterialStatement.execute();

}

In AIR, database calls are asynchronous.  This means most calls to the db will involve the setup of a listener.  This can be a bit of a pain because its difficult to just setup a method to make a call and return a value, you have to setup a listener to wait for the call to be executed.  This leads to many, many listeners floating around and , take my advice, you need to make sure you remove the listeners when they are not needed.

private function onDBMaterialSelectResult(event:SQLEvent):void{
   var result:SQLResult = _dbMaterialStatement.getResult();
   if (result != null){
       MaterialData = result.data;
   }
}

Guess What Class I Am

As I said earlier, because SQLite does not implement a proper auto-increment feature, you must do it yourself.  Shouldn’t be too hard – get the MAX of a column, add one and Bob’s your Uncle.   Something like:
"SELECT MAX(MaterialID) FROM Material"
should work fine. That works, but there is an important little trick.  AIR returns the result of all db queries as an array of objects, you must specify what those objects are, usually by setting the SQLStatement’s itemClass property.  Unfortunately this doesn’t seem to work too well for the MAX function.  I thought that MAX should return an integer, or at best a long – but it doesn’t. Setting the code to:
_dbMaxStatement.itemClass = int;
didn’t work.  With much use of the Flex Builder’s debugging tool, I determined that the MAX statement was returning an "id" class.  Okay, what the heck is an id class?  I can’t just set
_dbMaxStatement.itemClass = id;
because I don’t have the class "id" anywhere in my code – and I couldn’t figure out its package designation. I tried recasting the result to an integer and it didn’t work either. This all got very frustrating until a colleague pointed out that you can set the returned class type in the SQLStatement text itself. This lead to the following code:

_dbMaxStatement.sqlConnection = _dbConnection;
var sqlQuery:String = "SELECT MAX(MaterialID) AS id FROM Material";
_dbMaxStatement.text = sqlQuery;
_dbMaxStatement.execute();

var result:SQLResult = _dbMaxStatement.getResult();
var myint:int = result.data[0].id;
MaterialMax = myint;
trace ("***** MaterialMax: " + MaterialMax);

That little "AS id" makes all the difference in the world.

Prepared Statement

The one other thing that I wanted to mention is the use of variables inside a SQLStatement.  Since the statement is essentially a string, you could write it like:
var sqlQuery:String = "INSERT into Material (MaterialID, MaterialName, Color, Size) VALUES(‘" + material.MaterialID + "‘,’" + material.MaterialName + "‘,’" + material.Color + "‘,’" + material.Size + "‘)"; The problem is that keeping track of the quotes and commas quickly becomes a nightmare.  Fortunately there is an easier way.

In Java there is the concept of a "prepared statement" in which a question mark is substituted for a variable entry in an SQL statement.  ActionScript has the same concept although it uses an @ symbol and a variable name instead of a question mark.  Using this method the same SQL command can be written as:

var sqlQuery:String = "INSERT into Material (MaterialID, MaterialName, Color, Size) VALUES(@MatID, @MatName, @MatColor, @MatSize)";
_dbMaterialStatement.text = sqlQuery;
_dbMaterialStatement.parameters["@MatID"] = material.MaterialID;
_dbMaterialStatement.parameters["@MatName"] = material.MaterialName;
_dbMaterialStatement.parameters["@MatColor"] = material.Color;
_dbMaterialStatement.parameters["@MatSize"] = material.Size;

This makes the code much easier to read and maintain.

Conclusion

Using the above methods I created the other tables, classes for holding results and DAO methods for querying and updating the database.  The next step will be to wire the database stuff back into the display objects that I created earlier.  As you may recall I had setup some temporary data sources that were hard coded.  I now want to use the real objects as returned from the database.


My god…its full of stars

Its time to start making things look nice.

Last time I started with the central user focused object – the pattern – and started creating MXML components that corresponded to the object’s parts.  This, along with some temporary data structures gave me a rough working prototype of the pattern object.  It did look quite ugly however.

This time I spent moving objects around, changing layout and playing a bit with color schemes.  Since most of the pattern is data driven, allowances need to be made for different lengths of data.  This means that objects holding text and images needs to expand to fit the required screen area.  Other objects need to flow properly so text doesn’t end up running on top of other paragraphs

In AIR this means that things need to be placed in the appropriate UI containers. I had already used the Canvas container to hold sub parts of the pattern (such as the Instructions and the Recipe), but there are others that came into use such as the HBox, VBox and Tiles.  The Canvas is great, you can place any object where ever you want and it doesn’t care.  Unfortunately it doesn’t care about flow or object collisions either.  With dynamic data the Canvas can look like a real mess.  The HBox and VBox on the other hand, will only place one object in one place at a time.  Depending on which box you choose it will place objects side by side or stack them.  Either way it does take care of flow.  Tiles are another really useful container – depending on the direction, it will place things side by side (as with an HBox) until it reaches its maximum width, then it starts a new row.  By nesting the containers you can pretty much get the screen to flow any way you want.

To decide what objects went in what container, I started by drawing all the objects on a piece of paper.  I then drew an arrow next to each object to indicate the direction I wanted it to flow.

I then drew boxes around objects on the same plane.  By looking at the flow lines I can determine what container was required.  For example the entire Pattern screen needs to flow down – I want it to get longer if there is a lot of information (not wider).  This means that the Pattern Screen can be wrapped in a VBox. One of the consequences of this is that all of the objects would be stacked on top of one another as that is all that a VBox allows.  When I look at the Name, Tier and Species fields I want them to be on the same line. This means that they must be grouped in an HBox.  By continuing this process I eventually had a layout that would flow correctly as different lengths of data were added. Another thing I found was that by omitting the height and width attributes of certain HBox and VBox elements the boxes will inherit the height and width of the elements inside them (they would flow correctly).  I.e. the VBox that contains the picture and recipe will expand to fit all of the Recipe because it does not have a set height.

Another concern that I had was making the right part of the screen scroll.  Even though I have a few sections that I did want to scroll – such as the Instructions.  I had to tinker with things a log, but I eventually got just the Instructions section to scroll and not the entire page.  This was a bit of a PITA and took a lot of fiddling with the width and height values of the various containers.  At some points I had scroll bars on top of other scroll bars.  If anyone knows of an easier way to this (besides trial and error), please let me know.

Once I had things laid out nicely and flowing correctly, I started looking at themes and colors.  Eventually I will use a style sheet, but I’m still playing with things too much for that right now.  As far as colors go, I’m no Graphic Designer.  I can tell when something looks wrong, but what it takes to make it right is beyond my current skill level.  Fortunately there are some really nice tools out there to help. On of my new favorites is Kuler (yes I am Adobe biased).  There are tons of user defined color schemes available, some better than others.  My favorite feature is the Create From an Image feature.  I uploaded a picture (in this case a picture that included my parka and waders) that had the right "feeling" and it picked out the color theme from that picture – way cool.  With some minor adjustments I can use those five colors for all my objects and still have something that looks nice.

One other thing that I did was to add a new component for the Species field.  I decided that icons looked better than text and it was just a matter of doing a similar repeater setup that I used in the Recipe and Instructions components.

One complaint – As I have stated before, I am a coder by training.  I love the rich IDE environments that are provided in tools such as Eclipse.  Since Flex Builder is based on Eclipse, I believe that it should have the same rich development environment.  Missing features such as source formatting (pretty printing) and variable highlighting annoy me to no end. If someone on the Flex Builder team is listening – please add these feature in as they are in the Java developing mode.

Staring at a blank page

I launched Eclipse, created a new Flex project and got a shiny new application started. I then found myself staring at the clean grey page with no idea of where to start – call it programmer’s block. Okay, time to regroup.  In the past, with larger code based development projects (Java, .Net, etc.) I would have fallen back to the design document and started with either the main data structure/function, or some of the well defined supporting classes.  Really building with AIR is no different.  The only change is that instead of a data structure, the project is user/task focused. 

If I look back at the application structural diagram it gives me a place to start:

Structure1.jpg

The central object that the user interacts with is the Fly Pattern – seems as good a place to start as any.

If I look at a typical fly pattern it consists of some simple elements (the image, fly name, tier name, notes) and some more complex elements (recipe, instructions) that can repeat. To me this means that the pattern class has a couple of support classes that contain repeating elements.  Now we’re getting somewhere. 

I created a new MXML Component to hold the pattern and called it patternDetails.  I dropped on some objects to hold the simple elements – an mx:Image for the main picture, a mx:Text for the fly name and another mx:Text for the tier’s name.  I didn’t mess around with layout and design too much – I wanted to get all of the elements together before I worried about aesthetics. Not that aesthetics aren’t important, they are one of the keys to usability, but there is no use buying wallpaper until you know how big the room is.

Next I created two other MXML Components – one for the recipe data and one for the instructions.  Both of these have elements that repeat and are quite similar in function, although they are very different in presentation.  First the recipe: this consists of a list of elements consisting of parts, materials and notes.  The number of elements in the list is not fixed as one pattern may have three items and another may have forty.  I needed a MXML object that was capable of holding such a list.

In previous projects I have used the DataGrid in its various forms. Its a useful item that can be bound directly to a data source and has a lot of built in functionality (such as sort). Its really useful for lists of data items. I tried it, but it just didn’t look right, it was a bit too rigid in its layout.  I started to look for an alternative when I came across the mx:Repeater. Repeater also can be bound to a data source, but you specify all of the item layout yourself.  It doesn’t have the built in functionality, but it does have a lot of freedom in its layout – perfect.

Since I have to consider layout soon, I would like to see how the screens look with “real” data and image.  I picked a fly pattern called a Stimulator as a typical example, but how to get the data into the application?  Eventually this will be done by reading the information from a database, but this requires developing the database structure, supporting data structure and supporting classes.  It will have to be done eventually, but for right now I just want to see something quickly. I could go the other route and just hard code everything from images to text, but that doesn’t verify the functionality of the application – it means that I would need to rebuild everything when I built the functional code.

What I needed was a happy medium – something that I could put together quickly with out a lot of support classes, but still could be easily transitioned into functional code. Objects such as Repeater can use a dataProvider attribute to specify their data source. The dataProvider can be an array of Objects and can come from any data source.  In the long run the source will be the database, but right now I can create a local array and use it to test the Repeater. So I created a temporary folder for the images and set up an ArrayCollection to hold the data locally. For example, the following is the temporary array setup for the recipe component:

One other thing to note about the Repeater.  A consequence of complete freedom of look and feel is that you no longer have some of the basic functionality that you would expect.  For example when I first created the Repeater, connected the dataProvider and populated it with some text elements it repeated everything on the same line.  It did not lay new elements after the previous one.  What I wanted was something akin to the repeating subform functionality provided Acrobat.  I eventually found that wrapping the entire Repeater in a VBox did the layout as the VBox ensures that elements get placed one after the other.

So, now I have a rough fly pattern view with real (sort of) data.  I can now start making it look nice.  Here’s what it looked like before the beautification effort:

For those interested in seeing the early source code I’ve posted it in zip format here.

 

 


Thats no moon….

As you may recall, one of the main purposes of this project is to teach a traditional Java programmer (namely me) how to develop Rich Internet Applications (RIA).  This goes beyond just learning syntax and tooling, it means gaining a deeper understanding of the possibilities of a new environment.  To that end I have been doing quite a bit of reading about designing applications for RIA environments.  The more research that I do, the more I am convinced that this project requires a fundamental shift in thinking from a code based development mind set to a more visual based/user centric model. Developers/programmers (and I include myself in this category) can easily become too enamored with our own data structures and can loose track of the user that our applications should be designed for.  This is nothing new, but it becomes glaringly obvious as more tools become accessible to a wider range of development talent.  I guess what I’m saying is that crappy user design becomes less acceptable as tools make it easier for better design. Certainly, tools such as Flex Builder make it easier for a more diverse population to build better applications.  In no way does this excuse poor system design , it just means that good system design should support a good user experience.

Rob Adams, a Senior User Research Specialist with Adobe, has written a series of Developer Center articles that I really encourage anyone developing AIR/Flex applications to read. Rob’s articles will help get you into the RIA head space and help you to start designing better RIA applications.

I finally got around to putting together the system design document for the
Fly Tying Inventory tool that I described in earlier posts. I’ve tried to keep Rob’s suggestions (and others that I have read) in mind while working on the design for this project.  Specifically, I started with the consideration of the user’s task (finding a fly pattern and associated media) and worked the design from that.  Everything needs to be considered from the point of view of the user’s purpose. See the attached BC_Requirements document, which is a light weight combination of Requirements Document and Systems Analysis and Design document.  I can get away with something lighter because I will be building most of the application myself – I can wing it with some of the design.

One interesting outcome from this user/task oriented approach is the database layout.  When I started listing all of the things that a user needs in relation to the fly pattern (the central concept of the application) I found that I had created a horribly un-normal data record.  I went through an exercise to do some basic database normalization and got it at least to a 2NF state. Getting to 3NF can be more desirable, however I find that higher orders of normality can mean that many joins are necessary for searching, which is inherently inefficient.  Because I am using AIR and will be stuck with SQLite (which doesn’t allow foreign keys) 2NF should be good enough. I already know, from past projects, that you usually need one class for each of the database tables that you are loading into memory – so the database design has a direct correlation to the application’s data structures.

In previous posts I mentioned that I will be creating an Interface Design Document as well, but it is conspicuously absent.  I did try to write one, but I found out that I didn’t know enough of the capabilities of the AIR environment to write something useful.  I’m sure a Designer could have done it anyway, but I’m a coder – I need to learn what I don’t know first. I’ll probably write one up after I play with things a bit, some experimentation is necessary.

Ready, Fire, Aim

When last I posted, and it was a while ago, I was searching for an application to develop that would teach me some of the subtleties of AIR. I has laid out some possible options and I received a couple of suggestions from others.  Having thought about all of the possibilities, and made up a couple of new ones, I decided that I would go with a Fly Tying Inventory tool. 

I know, I know, there are many of you out there that are saying “well who the hell cares about something like that?”  Well, in this case the application is not the important thing, but rather its a vehicle for the learning of the software.  As such the application must have elements that lend themselves to multimedia (video, text, graphics, audio), offline capabilities (such as a local database), an engaging user interface, etc.  Lets look at how this tool would meet the criteria I set out before:

  • Must be user facing – back end software is incredibly important stuff, but AIR’s whole reason for being is to build an engaging interface
    Users will need to view patterns, search the database, enter new patterns and generally work with the pattern data that is available.  Users most likely are not developers and their patience with software may be limited.  Good interface design is very important.
  • Should make use of some of AIR’s special talents – otherwise why build it in AIR?

    • online/offline access – this implies that there is at least some kind of a back end system
      A central database of patterns that can be used to update the local software will be very useful
    • local database
      Patterns should be stored in a local database for easy searching and retrieval
    • have update capabilities for new versions of the software
      Updating the application as new features are added is a must
    • platform independence
      Being a public facing application we should not restrict users to a specific platform
    • encryption of data
      Admittedly this is not much of a requirement, fly patterns are not usually that much of a guarded secret (fishing locations on the other hand…..)
    • multimedia presentation
      Absolutely – patterns are listed as text with an accompanying picture. Often there are short videos demonstrating the tying as well audio explanations may be added

  • Should be fun, but it still should be somewhat useful.  Lets face it, I am in the high-tech industry and with that comes a bit of ADD.  The project has to be interesting enough to keep my attention.
    This is really a matter of opinion, but I find it very useful. There are thousands of patterns with many variations. Having a search tool would help a lot.
  • Must be well understood.  By this I mean that the project must be something concrete as opposed to an abstract thought experiment.  This is mainly so I can objectively assess the success of the project.
    No problem here, this will be a very concrete application.

Basically the application will be a storage and search tool for a specific type of multimedia. You really could substitute anything that has many parts and a recipe for putting them together and you would have the same thing (car parts inventory with installation instructions, stellar cartography with location data, etc.)

Okay, I’ve now got an application what are the next steps?  In this case I’m going to do two things:

1 – Put together a semi-formal set of requirements.  This will allow me to measure the success of the project against a fixed set of criteria.  It also will keep me from missing any key points in the software development.  Its a pretty common step in any software development.

2 – Create a visual design document.  This will let me keep the visual design consistant.  I believe that this is one of the most important documents when creating a user oriented application.  Its purpose is to make sure the visual integrety of the application is maintained.

I’m not going to create a 400 page manuscript, but a few of pages to keep things on track through-out the development process.  I’ll post the docs for discussion next time.


Of cabbages and kings

When I published my last blog entry I mentioned that I wanted to find a small but useful project on which to learn some of AIR’s nuances. The project has to be non-work related as that comes with some baggage (such as dead lines) that I don’t want to interfere with the learning process. 

At the risk of offending my old university Intro to Computer Programming professor (sorry Dr. Evans), I’m going to approach the problem bass ackwards. In this case I know what software I will use, I just need to find a project to develop.  My criteria are as follows:

  • Must be user facing – back end software is incredibly important stuff, but AIR’s whole reason for being is to build an engaging interface
  • Should make use of some of AIR’s special talents – otherwise why build it in AIR?
    • online/offline access – this implies that there is at least some kind of a back end system
    • local database
    • have update capabilities for new versions of the software
    • platform independence
    • encryption of data
    • multimedia presentation
    • etc……
  • Should be fun, but it still should be somewhat useful.  Lets face it, I am in the high-tech industry and with that comes a bit of ADD.  The project has to be interesting enough to keep my attention.
  • Must be well understood.  By this I mean that the project must be something concrete as opposed to an abstract thought experiment.  This is mainly so I can objectively assess the success of the project.

I also want to have something complex enough to be able to take advantage of many of AIR’s features while still being simple enough that one person can build it. I don’t want to need to learn an entire development architecture (such as
Cairngorm or Flight Framework). I think that adding a formal design pattern would muddy the waters right now.  Who knows, if this is a success maybe I’ll do another blog series on developing inside a framework.

So with this short list in mind I spent some time staring at the ceiling, thinking of a few applications.  Here’s what I have come up with so far:

  • Expense report tool - My job involves a fair amount of travel and that leads to filling in expense reports.  Most large scale expense reports software requires online access to impossibly huge back end systems such as SAP.  Unfortunately this means that I can’t enter my expense data while on the road (or on the plane).  It would be very helpful if I could create expense reports off line and then synchronize when I connect. Also, all of the user interfaces for expense systems that I have used seem to have been designed by accountants (no offence to accountants out there) with little regard for aesthetics.
    The drawback is that the connection to the back end system requires a pretty in depth knowledge of the systems APIs. I am worried that I could get bogged down in the back end connection.
  • Fly Tying Inventory – One of my favorite hobbies is fishing and recently I have taken up fly fishing and fly tying.  For those of you not familiar with this all encompassing waste of time and money – fly fishing consists of standing in the middle of a river waving a long stick around with a string tied to bits of feathers and fur on a hook.  The combination of feathers and fur are called a fly pattern and there are literally thousands of different fly patterns out there. As a software guy it would be nice to have a tool from which I could search those patterns. This sort of thing screams for a well organized database that could contain videos and images of each pattern.  The problem here is seeding the database with enough information to become useful
  • Tournament Tracker – I was recently involved in a kayak fishing tournament in support of the Ottawa Riverkeeper organization. A good friend and fellow Adobe employee had volunteered to help monitor the event and register each entrants catch as well as work out who won what prizes.  Being a “photo release” event, each angler was required to take a photo of their catch before returning it to the water.  The length of each catch determined the winners.  I couldn’t help but think that a tool for the organizers to track anglers would be useful.  At the same time a way for angler’s to see up to date tournament information would be pretty cool. As the “weigh-in” information is gathered on the beach, off-line use would be really useful.
  • Hockey Pool – I’m the first to admit that I’m not a hockey fan (which is blasphemy in this part of the world), but conceptually a hockey (or baseball, football, F1, cricket, whatever) pool may lend itself to this kind of application.  Data must be centrally stored, but user picks and some other operations may be able to happen offline (with a data synch happening later).  I wonder if the NHL would let me put in video clips :-)
  • Gas Price Monitor – A very timely idea.  It would be very interesting to have a tool that charted gas prices around the country (world?) and compared them to the price of crude oil.  There are a few web sites that do this, but their interfaces are not exactly the sexiest things in the world.  I can’t however think of an offline use for this as current data is key to the application.

Okay, so now I have a few ideas.  My next chore is to pick one of the above (or something else if it comes to me) and then start to put some requirements together. Remember my main goal is to learn AIR, the application I use to do that is secondary.

Stoking the Fires

,,

Welcome to the initial posting of the Steam Powered blog.

I’ll be honest with you, the idea of posting regular blog entries is not something that previously appealed to me.  I’ve actually been quite resistant to the entire idea as I always believed that I really don’t have anything to say (not that that hasn’t stopped most bloggers).  This has changed recently however when I started working beyond my “comfort zone” and started looking into developing AIR applications.

Let me back up and tell you a bit about my self (it does have some relevance, trust me).  I’m currently employed as a System Specialist at Adobe in Canada.  This means that I work with Sales, Marketing and Professional Services teams to develop customer facing proof of concepts.  Essentially I lend programming assistance to large customer deals for short term pre-sales projects.  I work a lot with the Adobe LiveCycle product, meaning most of the work I do is around Java and JEE development with some .Net thrown in to keep it interesting.  I’m not a rich internet application (RIA) developer and lord knows I’m not a graphic designer (stick people are the limit of my design capabilities). 

Recently Adobe has released a new application environment called AIR (Adobe Integrated Runtime) which allows developers/designers to build desktop applications using Action Script (the scripting language of Flex).  This means that a developer should be able to build a sexy interface without having to develop piles of library code. The applications will also run on all client environments  – build once, run anywhere (where have I heard that before?)  Quite understandably, everyone at Adobe has been encouraged to try out AIR and there are many, many projects that will be using AIR for their interfaces. 

Naturally this “AIR everything” fever has also been contracted by those of us working with the server side technologies. More and more of the POCs that I have built are requiring a snazzy front end with lots of spinney bits, cool fades and overall mind blowing eye candy.  My usual design of two hot links and a button just won’t cut it anymore – I need to add dancing bananas.  I’ve played a bit with Flex and AIR, putting together some very basic applications that usually do a single simple thing (upload a file to the server, put a graphic on the screen, etc.). But I really want to do more. 

Since I learn best by doing, I have decided to pick a large(ish) project with many different interface aspects and attempt to build something useful (sort of).  And, as I believe that I’m not the only one out there that is faced with a similar challenge, I thought I’d post my journey in a blog.    As I pick a project, start the design and build the code, I will post my findings, frustrations and triumphs here. Hopefully you’ll find it useful.

Next step – pick a project that I can learn with.  I don’t want it to be something directly work related as customer information is confidential and I won’t be able to blog about it.  Also I don’t want a deadline – I’d like this project to proceed at its own pace.  If you have any ideas, let me know.  Otherwise I’ll post when I narrow down the field to a few (or one) good idea.

Cheers,

Mike

 

Note:
Although I do work for Adobe, and they are allowing me to post this blog on their site, this is not an “officially sanctioned” information source.  Meaning that I may not be presenting the best way for doing something, and I may go down several blind allies.  On the other hand, if I find something that is weird, of just plain sucks – I’ll call it out (I’ll try to be polite – I like my paycheck).

 

BTW
Why “Steam Powered”?  I live quite far from the city and my home internet connection is still dial-up.  My father was visiting us a while ago and was trying to check his eBay account and since the connection was so slow he commented  – “What is this, Steam powered?”.  I thought it was an appropriate way to describe the way that I, as a developer, approach developing an esthetically pleasing user interface.