Archive for the ‘flex’ Category

No more Flex Framework frameworks

Friday, August 14th, 2009

Let me start by providing examples of Flex Framework Frameworks (FFF): Cairngorm, PureMVC (I know, it’s not just Flex), Mate, Swiz.  You get the idea.  All these frameworks provide ways to deal with Event Handling, Command or Action handling, ease separation of concerns so you can code in MVC, some provide inversion of control, or some combination of Enterprise Patterns.

Developers who are looking for a solution to bootstrap their application development are looking at the wrong abstraction level when they evaluate these frameworks.  You can’t base an entire application on just these frameworks.  If you do, you’ll be coding at too low a level.

What is needed is a library or framework above MVC, a framework that provides a core set of services that are present in most run-of-the-mill applications you’ll code in Flex, and a standard way for you to write your app on top of these services.

What’s a run of the mill Flex application?  I’m talking about business applications that may be deployed over a browser or in AIR and that allow the user to enter information in a form, to create a dashboard.  I’m not talking about other types of online apps like Blogs where you just read information and post (sure, there’s a form, but whatever), advertisement sites like movie websites (these mostly use Flash and are highly interactive but the focus is not to gather information from the user.   I hope you get the picture.  If I had more time I’d come up with a better bullet point list.

So, what are the base services for these applications?  I’ll try to describe them without resorting to Enterprise pattern names like Commands or Actions and just describe what I want my app to do.

I want to …

  1. be able to have buttons, menu items, links, and other UI widgets through which the user can perform the same action.  So there might be an undo button, an undo menu item, and an undo menu item in a context menu and clicking or selecting it should execute the same action.  They should be enabled or disabled automatically for me, their visibility should be set to true or false automatically.  I should be able to declare their enablement/view states and their position on a toolbar or menu without my having to add any code or have any giant switch statements.
  2. have undo/redo
  3. handle long running operations with the ability to provide feedback to the user and the ability to cancel them
  4. have the same button or menu option perform what seems like the same action based on what thing I currently have selected or what view I currently have selected
  5. global item or resource selection handling
  6. Modularity so that functionality can be added by providing another module and not by recompiling the whole thing
  7. Context based action enablement

Ok, I’ll stop there because that last one is very jargony.  I’m basically talking about something like the Eclipse Rich Client Platform (RCP) but for Flex.  Moccasin, a Flex framework for graphical editor apps has history  management and editor functionality.  I want a library that goes further.

If you’re not familiar with the RCP, that’s OK, let me explain how this mythical framework might handle the features up there:

Commands and Handlers

The RCP has the concept of a Command, which is just a declaration of an intent to perform some action. It doesn’t actually do anything, it’s just a marker.  For example, “Cut” is a command.  It doesn’t actually know how to perform anything.

In order to actually do something you have to provide a Handler for a command and tell the framework when your handler should be invoked.  For example, let’s say your application has a tree on the left that shows a hierarchy of files.  And there’s a text editor on the right, which just shows the contents of the selected file.  If you currently have a file selected on the tree and you click on the “Cut” button then the Cut File Handler is invoked.  It knows how to take a file, delete it from the current location and store the contents in the clipboard.  If instead your text editor had focus and you had selected a piece of text then clicking on the Cut button would invoke the Text Editor Cut Handler which knows what part of the text is selected and can yank it out of the editor then store that in memory.

How did the framework know which handler to invoke?  When a handler is declared in the system you must also provide an “activate when” expression.  The activate-when for the Cut File Handler might be something like:

if Selection == Resource of type File

for the Text Editor Cut Handler it might be:

if selectedView == editor and and selection length > 0

Handlers can also be declared with “enabled-when” and “visible-when” expressions that allow the framework to dynamically, automagically enable buttons, menu items, links or whatever other UI widget is currently hooked up to a command, if the expression executes true.  ”visible-when” expressions would remove or add the widget if the expression were true.

That’s how we deal with 1, 4, and 7.

Undo/Redo - History Management

This one’s easy, but I haven’t seen any framework address it directly. It’s a pretty generic feature and even if your app is whiz bang it can still use the same basic generic solution.  The solution is simple:

Execute stuff in an undoable operation interface (call it IUndoableOperation).  Put it in some manager that has two stacks, an undo stack and a redo stack.  Implement an redo/execute method or methods and implement an undo method.

If you want to get fancy, use Undo Groups so that you can group together a set of operations that should be undone/redone as a group though each operation by itself may be undo/redone independently.  That takes care of 2.

In order to do this right in Flex, however, the history manager should anticipate having to perform its undo/redo/execute asynchronously because some operations may require network access and their completion can only be determined asynchronously.  Which brings us to my next topic:

Long Running Operation

In fact, the spark that started this post brewing in my head was when Ted Patrick tweeted about their being so many Flex Framework Frameworks.  The conversation turned into creating a library of useful patterns that Flex developers could use and feel confident in using them.  That the benefits it would provide would be to cut down on development because we wouldn’t have to reinvent the wheel, that we could share projects more easily because they wouldn’t depend on different libraries that performed the same thing though slightly different.

Anyway, one of the features or patterns requested was a way to perform long running operations, something that looks like threads (there’s a google code project for this in Flex).  I think this is a useful pattern that should be available in this framework I’m dreaming about.  And that there’d be support in the UI for monitoring its progress and canceling it.  It seems easy, have the method implement an ILongRunningOperation interface which can report progress as well as human readable information like the task it is currently performing.  This interface can take an IProgressMonitor interface object to which it can report its progress.

On the UI side, the framework can provide a simple, standard, sample progress bar that implements the IProgressMonitor and that is hooked into the Long Running Operation manager of the framework, so that all the developer has to do is declare a long running operation, give it to the manager, and the manager knows to perform this operation when all other ops are done, or maybe concurrently if the operation does not have to block.

That takes care of 3.

Global Resource Selection Handling

I’m not talking about the Flash global selection handler, I’m talking about a manager above that to which your views can set the selection of native objects in a standard way.  For example, if I have selected a node in the tree example above then the selection would show as an array of one object of type FileResource.  If I’d selected several nodes then the selection would be a flat list but would have an associated hierarchical selection.   If, instead I’d selected text in the editor it would be a one element array with an object of type TextRunSelection (or something) that encapsulated the start, end and any other attributes of the text.

This selection manager is an essential component that can be used by the command/handler framework when evaluating active-when, visible-when, enabled-when expressions.

That takes care of 5.

Modularity

This one obviously would use Flex modules at its core, but would add a layer above it that would provide the following:

Extension Points: Extension points are basically where you declare your application hooks and in which other modules or plugins can hook into to provide functionality.  An example extension point is an Editor, for example.  Let’s say that I can have different types of editors based on the extension of the file I have selected.  My main application would declare that there’s an extension point called editor through which other plugins or modules can add their own editors.

Extensions: These are the actual things that modules or plugins provide.  My XML editor plugin can provide an extension to the editor extension point that says: If you have selected a resource of type file with the filename ending in “.xml” then use this editor.

The framework would not provide a set of defined extensions, but just the ability to declare extension points.  And it would provide an easy way for applications to request what extensions are declared for some extension point.

If we wanted to get fancy, the plugin framework would allow the developer to provide all this in a plugin descriptor as well as initial proxy objects that would delay the actual loading or instantiation of a plugin until it was actually needed.  I think this level of delaying might not be desirable, however, as it would add a level of complexity to the extension user because they’d have to account for the asynchronous nature of module loading when accessing proxy classes.

One additional benefit of a layer above Flex modules is that developers would not have to worry about adding the latest best practices to flex module  handling that are discovered as bugs and other “features” of Flex modules pop up.  It would also relegate the need to deal with application security mostly to the plugin framework and away from the application developer.

That takes care of 6.

Stuck in the Weeds

My old business partner had a great expression: Whenever I’d start proposing solutions in terms of MVC or using httpservice vs. remoteobject he’d tell me: “Robert, you’re stuck in the weeds!”  It’s obvious what he means: I’m focusing too much in the details without stepping back and looking at the whole problem.  What am I trying to accomplish?

When I picked up Flex I started without a framework, then I started with Cairngorm.  The application grew in complexity and it seemed Cairngorm just made it too hard to keep going.  Then we stepped back and we thought about MVC and how we could use the basic stuff that Flex provided to code in MVC rigorously.  It worked, but we were still stuck in the weeds.  It was hard to add stuff to our application.  One sign of the problem with just thinking in MVC was that when we talked to the client they didn’t talk about views or models or controllers, they talked about editing things, loading resources, selecting stuff, undoing this, selecting that file, selecting this text.  Cutting and pasting that, adding a page.  (forget about use cases and user experience for now)

So I stepped back and started thinking about application level services.  I’d worked with Eclipse for a long time before Flex and I remembered how easy it was too think in terms of what the application does.  I’ve written some complex stuff in Eclipse and it wasn’t trivial but it was fairly easy.  Why couldn’t I do the same with Flex?

I don’t mean to say that the frameworks out there are focusing on the wrong things; they are targeted at the layer they are meant to target.  I think many Flex developers are stuck in the weeds, however.  They’re looking at the wrong level when they’re looking for a framework to build their apps on top of.  Where the focus is wrong, I think, is in the energy devoted to creating these frameworks and advocating their use as the solution to Flex application coding difficulties.

Why don’t I start this framework?  I may. I’m not sure what the level of interest is.  I felt the need to put this out there to see if I can make the case that the majority of Flex developers are stuck in the weeds.

March 2009 - RIA Buzz >> NewsFlash

Wednesday, March 11th, 2009

The March 2009 issue Adobe’s NewsFlash is out.  This is the monthly newsletter for Flash Platform Developers that used to be called RIA Buzz.  I like the new name, as it points out that we’re talking about the entire Flash platform, including AIR, Flex, PDF, server side, Ajax, and more.

Check out the issue and sign up to receive an email announcement when the next newsletter comes out.

Also, I’m always looking for new content for my segment of the newsletter, so if you have any interesting leads send them to me: robert.cadena@gmail.com.

#tweetcoding winners announced

Wednesday, March 11th, 2009

The winners of the 1st round of #tweetcoding have been announced. #tweetcoding is a contest where you submit to twitter a bit of AS3 code that does something interesting in 140 characters or less.  @gskinner, @adobeted, and @NeoRiley had to comb through 250 interesting entries and decide on the winner.  It came down to a tie between two really cool apps.

Surprisingly, I didn’t have time to submit something in 140 characters but I did have time to write a couple of server side python scripts to download and compile the entries and put them up on http://tweetcoding.machine501.com/.

When the contest was really getting going and entries were coming in pretty frequently my scripts ran into the Twitter API rate throttling.  I asked twitter on a Friday afternoon for permission to whitelist my app and raise the limit.  To my amazement, they replied in just a few hours, right before the end of the day on the west coast, and let me know that the app could make calls above the throttle limit.  So, many thanks to the twitter folks for following up so fast.  This obviously increases the popularity of their system, even if just by a little bit.  In fact, I saw someone say they joined twitter just to participate in the contest.  Awesome.

This was a great experience with twitter.  I was pretty slammed with work at the time so sometimes the compiling process was stalled or failed and I couldn’t get to fixing the bug right away.  But, it was tons of fun.  @skiller asked if we’d thought about putting the contest up for public voting.  That sounds like an interesting proposition and I was thinking of using Django to code up something cool, as well as polishing up the interface.

#tweetcoding AS3 code in 140 chars or less

Wednesday, February 18th, 2009

#tweetcoding

@gskinner started off a little contest where the object is to create an interesting SWF in 140 characters or less of AS3 code.  

I went ahead and wrote a server side script that scans the tweets submitted to this contest and compiles the entries then makes them available here: http://tweetcoding.machine501.com/

There are already some interesting pieces submitted and Adobe has pitched in with a copy of Flash CS4 as a prize.

Check out the #tweetcoding rules

This was done easily with the Flex 3 SDK and some python scripts.  Many thanks to

BeautifulSoup for HTML entity parsing

Python Twitter Tools for a great, minimalist Twitter API that works on Python 2.3

And, of course, Twitter.

Oh, and the Flex SDK team

Useful Patterns for BlazeDS

Tuesday, June 3rd, 2008

Neustadt, Dresden, Deutschland

While running the Los Angeles Flex Users Group I got a lot of questions from people about how BlazeDS could fit into their existing infrastructure.

Typically, they will have an application container, such as JBoss, or maybe just a servlet container, like Tomcat, and a SQL backend. Usually MySQL or PostgresSQL. JSPs are used for the presentation layer and, sometimes, they may use Struts or SpringMVC as a web application framework. If you’re using ColdFusion this post is likely of little use to you.

Many programmers are understandably weary of introducing yet another component into their system and BlazeDS sounds like such a complex component that it’s often mistaken for a standalone application container that doesn’t readily integrate with standard Java application containers. This couldn’t be further from the truth. Those programmers who follow the bundled BlazeDS examples get stuck trying to figure out how to expand the example to fit their application or how to even start from scratch.

Let’s tackle the first misconception, that is, that BlazeDS doesn’t play well with Java application containers. To put it simply, BlazeDS is configured as a standard servlet. When a Flex client wants to make a request to a BlazeDS server it will issue a POST request to a defined servlet path. That path is whatever you configured the BlazeDS MessageBrokerServlet to. Flex sends the request as an AMF binary payload or an XML version of AMF. I’m glossing over some details but just knowing that you can access BlazeDS as a servlet is a good starting point for figuring out how you can start integrating BlazeDS into your existing application.

What this means to you is that BlazeDS can use container authentication or even work with Spring.

Let me make it even more clear by putting some sample configuration and code.

Here’s the part of the web.xml in which you declare and configure the MessageBrokerServlet:

<servlet>
<servlet-name>MessageBrokerServlet</servlet-name>
<display-name>MessageBrokerServlet</display-name>
<servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
<init-param>
<param-name>services.configuration.file</param-name>
<param-value>/WEB-INF/flex/services-config.xml</param-value>
</init-param>
</servlet>

Here’s the part where you map the MessageBrokerServlet to a path:

<servlet-mapping>
<servlet-name>MessageBrokerServlet</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>

The file “services-config.xml” is the primary configuration file for BlazeDS. Here is where you define a “channel”:

<channel-definition id="amf" class="mx.messaging.channels.AMFChannel">
<endpoint url="http://localhost:8080/sample_bds/messagebroker/amf"  .... />
</channel-definition>

This tells the Flex client where to make an HTTP POST request when using the “amf” channel on a RemoteObject, for example.

In fact, try it out on a browser, startup BlazeDS and point to htp://localhost:8080/blazeds/messagebroker/amf/

You’ll get a blank page. That’s a good thing!

The next question I usually get is, “do I have to dump my JSP/WebServices/Struts in order to use BlazeDS?” The answer is definitely no! In fact, if you have a JSP AND a WebServices front end to your application you’re a good bit along the way towards integrating BlazeDS. The reason for this is that if you have two front-ends to your application, and these two front-ends share some functionality, then you have probably structured your application in such a way (using a Service Layer, for example) that makes it easy to add a third front-end.

So what architectural patterns are useful for BlazeDS? To cut to the chase, I use Service Layer, Data Transfer Objects, and Mapper (or Assembler) on the server side. I’ll have a post on what I use on the client side later.

If you have played around with BlazeDS or used it to create a production application you’ve probably followed the examples bundled with the turnkey solution. And you probably have a hunch and instinct about how to create your app. I’m guilty of jumping right in and starting to code from my gut, but after a few days of learning a technology I like to step back and formalize my approach. My first place to consult is Martin Fowler’s Patterns of Enterprise Application Architecture (PEAA), and Design Patterns: Elements of Reusable Object-Oriented Software (Typically referred to as The Gang of Four Book, or GoF).

Service Layer

A Service Layer can have many methods, each using a variety of domain objects and models. Service Layer have application logic, like telling an emailing component to notify administrators that a payment has been processed, while delegating the business logic to the domain models. It’s pretty easy to figure out what types of methods a Service Layer should support; you can use the user interface as a guide to what sorts of things a client can do or you could base this off your use cases, if you’ve taken the time to do this.

The defining characteristics of Service Layers are the following:

  • Defines application boundaries
  • Defines available services from the perspective of interfacing clients
  • Encapsulates business logics
  • Provides convenient place for handling transactions, logging, etc.
  • Prepares the response appropriately for the client

That last one brings me to the next pattern I use.

Data Transfer Objects

These are objects that have a bunch of properties, contain no domain logic, and may be structured in a simple hierarchy. When I first started with BlazeDS I was using an Hibernate as my object-relational mapping (ORM) solution and so I was happily transporting the objects I got from a database straight through BlazeDS and over to Flex. Some of my objects had few methods for domain logic, some had more. Few had a complex hierarchies.

Once I started adding parent child relationships and collections then I suddenly encountered a problem where retrieving one of these objects would cause Hibernate to recreate a pretty huge hierarchy. Just as bad was a problem with transactions; when you’re about to send an object down the wire, BlazeDS will call each of its getter methods and each of those Object’s getter methods in turn. This is why it recreates entire hierarchies, but if you close the Hibernate session before BlazeDS has a chance to get to these methods then you’ll get an exception because the Hibernate proxy object can’t get a hold of a session with which to get the rest of the objects out of the database.

There are ways to go around this, such as using the Open Session in View approach, and that works well, though I found it felt awkward because of the name, since the “view” part of this is that hibernate objects are being used by the view and so the session should not be closed, but I also didn’t need to load all the objects that were connected to the one measly object I wanted to read.

I could have used the custom serialization method specified here: Using custom serialization between ActionScript and Java.

So, the simples solution I finally adopted was to use Data Transfer Objects. Characteristics of DTOs are the following:

  • May contain aggregated data
  • Fields are simple, such as primitives, or other DTOs

The pain of adding DTOs is that you now have to transform some of your domain models, in my case, for example, some of the objects gathered with Hibernate into DTOs. So you have to use the Assembler (or Mapper) pattern. An Assembler can take care of:

  • Knowing how to transform an object into a DTO
  • How to reconstruct hierarchies for DTOs
  • Keeps the domain model independent of external interfaces
  • May make use of more than one assembler per dto based on the semantics of the request.

Now I have no problem with building deep hierarchies when I only need one object. If I do need the complete hierarchy I can use a different assembler that knows how to reconstruct that. That’s what the last bullet point on that list is talking about; if it makes sense in one request to bring in all children and grandchildren objects then an assembler can know how to do that, if, instead, all you need, is the one object, then that’s all the other assembler needs to do. In my case, I now had better control over when I could close the session without having to worry about Session closed exceptions.

An additional benefit with respect to BlazeDS and Flex is that the RemoteClass mapping from Flex to Java can always map to DTO and you won’t have to worry about changing your actual Domain Objects and having those changes reflected in the mapped actionscript class; if you remove a property from your domain object then the Java compiler will complain because the assembler will be unable to access that property. You’ve caught the error earlier on.

I didn’t talk about the client side much. I’m working on another post that will address that side.

BlazeDS, Spring, and Acegi Security - Part 3

Sunday, June 1st, 2008

Update: The “start”-method-not-getting-called bug is now a filed in the adobe bug tracker: http://bugs.adobe.com/jira/browse/BLZ-190

This post is another baby step in getting acegi/spring security and blazeds to work together. The whole purpose of these exercises is to for acegi to handle authentication/authorization and destination security. Even bypassing container security.

In the last part I talked about how I was stumped by the LoginCommand and how the “start” method is never called. The reason I want the start method to be called is so that I am passed a ServletConfig and from there I can get access to the ServletContext, and thereby access to the Spring WebApplicationContext but unfortunately this method never seems to get called. I traced the BlazeDS source in SVN, not very thoroughly I should admit, and never found a spot where the start method gets called.

That’s not such a big deal because I can get access to the ServletContext by using the FlexContext singleton. I’m not generally a fan of singletons but what the hell; if it gets it to work =p

Anyway, here’s a brief outline of my AcegiLoginCommand, which extends AppServerLoginCommand:

.. class AcegiLoginCommand extends AppServerLoginCommand …

public AcegiLoginCommand() {
    initAuthenticationManager();
}

private void initAuthenticationManager()
{
    ServletContext servletContext = FlexContext.getServletContext();
    String beanId = servletContext.getInitParameter("loginCommandBean");

    if (beanId == null) {
        beanId = "authenticationManager";
    }

    WebApplicationContext context =
        WebApplicationContextUtils.getWebApplicationContext(servletContext);

    authenticationManager = (AuthenticationManager)context.getBean(beanId);

    if (authenticationManager == null) {
      throw new RuntimeException("AuthenticationManager could not be found.  Tried beanId='"+ beanId+"'");
    }
}

The LoginCommand needs access t othe authenticationManager so that it can pass it call the manager’s “authenticate” method. To make it more configurable, I added a little bit of code that will get the bean name from a web.xml init-parameter.

Finally, my “doAuthentication” method looks like this:

public Principal doAuthentication(String username, Object password) {
  Authentication authentication =
        new UsernamePasswordAuthenticationToken(username, password);
  authentication = authenticationManager.authenticate(authentication);
  SecurityContextHolder.getContext().setAuthentication(authentication);

  return (Principal)authentication;
}

I don’t need to override doAuthorization because when I’m doing MethodSecurityInterceptor, that class takes care of looking at the Authentication token’s “GrantedAuthority”es to see if they can execute the method.

That’s pretty much it. I need to figure out the extent of the security integration. I know that at the moment the authentication will not work on RTMP channels.

A good explanation and example for Spring and BlazeDS is important for driving adoption of BlazeDS into environments that run on Java. I know a potential client of mine is looking into using BlazeDS as a transport layer for a product they have running on a Tomcat container. They want to try following established practices in Java and want to use off-the-shelf, tried-and-true technologies like Spring and Hibernate, and having information on using these with BlazeDS would make them more confident when adopting BlazeDS.

Hope this helps. Also, I just found out someone else had documented a similar approach at this blog post:

http://blog.f4k3.net/fake/entry/acegi_logincommand_for_fds

BlazeDS, Spring, and Acegi Security - Part 2

Friday, May 30th, 2008

In an earlier post I talked about BlazeDS and Spring Security and gave a high level overview of how to get a BlazeDS destination to be secured with Acegi security instead of BlazeDS’ security. However, I overlooked a simple thing that would make the whole system play nicer with Flex. That is, I didn’t translate the authentication exception into a flex.messaging.SecurityException and did not set its code to Client.Authentication. It’s not really necessary to do so as you will get an error message anyway because BlazeDS catches Acegi’s exception and wraps it in a MessageException, but it’s nicer if it’s wrapped in a semantically appropriate exception.

I first thought I’d add an exceptionTranslationFilter to my filterChainProxy but this doesn’t work because BlazeDS wraps the exception after the proxied bean invocation and doesn’t let it percolate to the container filter. Duh! That took me about an hour to figure out.

The next step would have been to pass an afterInvocationManager to the method SecurityInterceptor but this guy never gets called when an exception occurs.

So, the next step, which I think is kinda hacky, is to extend the MethodSecurityInvocation class and override invoke. Catch any AuthenticationExceptions and translate them into SecurityExceptions so that BlazeDS can transfer that exception to Flex as appropriate. Here’s the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<pre lang="Java" line="1">
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
    try {
        return super.invoke(mi);
    } catch (AuthenticationException ae) {
        SecurityException se = new SecurityException();
        se.setMessage(ae.getLocalizedMessage());
        se.setRootCause(ae);
        se.setDetails(ae.getLocalizedMessage());
        // This is an authorization error instead of an auth error 
        if (ae instanceof InsufficientAuthenticationException) {
            se.setCode(SecurityException.CLIENT_AUTHORIZATION_CODE);
        }
        else {
            se.setCode(SecurityException.CLIENT_AUTHENTICATION_CODE);
        }
        throw se;
    }
}

My next step is to bypass BlazeDS’s authentication mechanism and just do it through Acegi. I’ll keep you posted.

Safari-like Text Finder in Flex

Friday, May 23rd, 2008

This is a component that mimics the text finding functionality in Safari. When you do a search it dims out the text field and highlights the currently found fragment of text. Other fragments in the text are currently set apart by a black rectangle, but I plan to change that.  This is kind of like the Highlighter component on FlexLib http://code.google.com/p/flexlib/wiki/ComponentList

The currently selected text indicator can be a IDataRenderer component that you can specify in code.

I couldn’t wait to show it to people before cleaning the code … so here it is. Without code. But I’ll release the source to the public once I clean it up and fix a few bugs.

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

Things I still need to do:

  • Allow custom renderer for non-selected item
  • Fix scrolling issues
  • Looks like I’m missing the ability to highlight items towards the very end of the text
  • Simplify so it can be used as a component. Currently needs a few lines of AS code to get working

Some notable features:

  • You are passed the text formats of the text fragment match so that you can render the text in the selected indicator exactly as it looks on the original text.
  • You can pass a custom selected text renderer. Notice it has animations as you click for the next find

There is another version that works on an HTML control in AIR. There’s a problem with that, however, when the text match wraps; I can’t figure out a way to find the coordinates of the start of text that’s been wrapped to the next line.

Going to the Microsoft Technology Summit

Monday, March 24th, 2008

I was recently invited to the Microsoft Technology Summit, a two days worth of sessions on MS technologies. My guess for why I was invited is because I run the Los Angeles Flex Users Group. I looked around for criteria for invitees and found a blog post here:

“The event is specifically for people other than Microsoft fanboys… they want to have a dialogue with influential members of the developer community outside of their comfort zone to see what we can learn from each other..”

The sessions cover specific technologies like ASP.NET MVC, to Silverlight, to IIS, to robotics and the projects under Microsoft Research.  There also will be a few presentations by attendees. The summit begins on Wednesday, March 26, and I’ll be blogging about it here and chatting it live at the Flex chat room at chatopica: http://www.chatopica.com/topics/flex/

Flex: Composite Validator

Wednesday, March 5th, 2008

This is a quick utility class I came up with that will keep track of a set of Validators and change a bindable property to true if all of the validators it tracks are valid and false if any of the validators is invalid.

I wanted this so I could quickly say something like:

<mx:Button label=”OK” enabled=”{compositeValidator.valid}” />

Here’s how to use it:

<validators:CompositeValidator id=”compositeValidator”>
<validators:validators>
<mx:StringValidator … />
<mx:EmailValidator … />
</validators:validators>
</validators:CompositeValidator>

<mx:Button …. enabled=”{compositeValidator.valid}” />

To get the source just right click on it and select “View Source …”

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)