Put a Flex UI On Your Application

来源:百度文库 编辑:神马文学网 时间:2024/06/30 22:25:04

Articles |News |Weblogs |Buzz |Chapters |Forums
Artima Weblogs |Bruce Eckel‘s Weblog |Discuss |Email |Print |Bloggers |Previous |Next
Computing Thoughts
Put a Flex UI On Your Application
by Bruce Eckel
June 19, 2007
Summary
Combine the power of Python with the polish of Flash to create adesktop application. This approach will also work with any languagethat has support for creating an XML-RPC server (Java, Ruby, C++, toname a few). Also, The XML-RPC server can easily be on another machine. Advertisement
<SCRIPT language=‘JavaScript1.1‘ SRC="http://ad.doubleclick.net/adj/N339.artima.com/B2351612;abr=!ie;sz=300x250;ord=36201694?"> </SCRIPT> <NOSCRIPT> <a target=‘_top‘ HREF="http://www.artima.com/zcr/adclick.php?bannerid=75&amp;zoneid=2&amp;source=&amp;dest=http%3A%2F%2Fad.doubleclick.net%2Fjump%2FN339.artima.com%2FB2351612%3Babr%3D%21ie4%3Babr%3D%21ie5%3Bsz%3D300x250%3Bord%3D36201694%3F&amp;ismap="> <IMG SRC="http://ad.doubleclick.net/ad/N339.artima.com/B2351612;abr=!ie4;abr=!ie5;sz=300x250;ord=36201694?" BORDER=0 WIDTH=300 HEIGHT=250 ALT=""></A> </NOSCRIPT>
I have been a Python enthusiast for over 10 years. Its power andexpressiveness has made it my first choice when solving my ownprogramming problems.
However, whenever I‘ve wanted to create a program with a userinterface -- an end-user application, for example -- I‘ve had problems.There have always been too many choices for Python GUI libraries, andeach one has its own idiosyncrasies. I‘ve studied most of them to onedegree or another and over time WxPython (based on WxWindows) seems tokeep pulling in front of the pack, but in my own experience I‘ve foundit far from the ideal solution. Mostly it seems like too much work,which is true for most of the Python GUI libraries.
The more I work with it, the more I find Flex to be preferableto any other GUI solution that I‘ve explored. As I learn more aboutActionscript, I gain greater appreciation for all the effort investedby the designers of that language to make life easy for the programmer.The combination of MXML and Actionscript is amazingly well-balanced;MXML keeps you at the "big picture" level most of the time, and you caneasily drop down into Actionscript to gain detailed control. Flex wasdesigned with user interfaces at the forefront, so it includes trueproperties and events as well as "data binding" to automatically movedata from one place to another when something changes. It‘s unfortunatefeatures like this never made it into Java.
And then there‘s Flexbuilder. Built atop Eclipse, this providesan incredibly powerful development environment with autocompletion,integrated help, debugging, and more. I haven‘t seen support for any ofthe Python GUI libraries that even comes close.
Creating Python XML-RPC Services
There are numerous RPC solutions which allow you to cross betweenone language and another, but I‘ve had the most experience -- and themost satisfying experiences -- using XML-RPC. So far it‘s solved allthe problems that I‘ve encountered, and it‘s simple to understand andstraightforward to use. And it‘s an excellent solution for distributedsystems, since you can effortlessly cross over machine boundaries (youdo, however, need to come up with your own callback approach whenstarting long-running processes on remote machines).
Python has the philosophy of "batteries included," which meansthat there‘s a very good chance that whatever you need is part of thestandard library. This isn‘t just convenient; the standard librariestend to get much greater focus and support than open-source projects,so the quality of the code tends to be better.
The SimpleXMLRPCServer library allows you to easilycreate a server. Here‘s about the simplest server you can create, whichprovides two services to manipulate strings:
import sysfrom random import shufflefrom SimpleXMLRPCServer import SimpleXMLRPCServerclass MyFuncs:def reverse(self, str) :x = list(str);x.reverse();return ‘‘.join(x);def scramble(self, str):x = list(str);shuffle(x);return ‘‘.join(x);server = SimpleXMLRPCServer(("localhost", 8000))server.register_instance(MyFuncs())server.serve_forever()
You can publish regular functions (not associated with a class), butI find the class approach is cleaner. This particular server is locatedon the current machine at port 8000, and that‘s all the client needs toknow.
Once the server is started, we need to make a client that willconnect to the server and call the services. This is also very easy todo with Python using the standard ServerProxy class in the xmlrpclib library:
from xmlrpclib import ServerProxyserver = ServerProxy("http://localhost:8000")print server.reverse(‘giraffe‘)print server.scramble(‘giraffe‘)
Once you make a connection to the server, that server acts like alocal object. You call the server‘s methods just like they‘re ordinarymethods of that object.
This is about as clean an RPC implementation as you can hopefor (and other Python RPC libraries exist; for example, CORBA clients).But it‘s all text based; not very satisfying when trying to createpolished applications with nice GUIs. What we‘d like is the best of allworlds -- Python (or your favorite language) doing the heavy liftingunder the covers, and Flex creating the user experience.
Calling XML-RPC Services from Flex/Apollo
One thing I‘ve found a little puzzling about Flex is the decisionabout which libraries are included in the standard distribution. Forexample, in earlier versions there was an MP3 player component, but forsome reason this has vanished (even thought the Flash player itselfdirectly supports MP3). And I personally like XML-RPC a lot, so itwould seem logical (to me) to include that as well. Fortunately, otherpeople have written replacements, and the Flex packaging mechanismmakes these easy to incorporate into your own projects.
After hunting around, I found an Actionscript XML-RPC client library, along with a description and an example,here. It was written by "Akeem"; I basically worked from his code but I trimmed it down to make it easier to read.
To use the library, download it and unpack it somewhere. The package includes all the source code and the compiled as3-rpclib.swc library -- the .swc extension indicates an archive file, and pieces of this library can be pulled out and incorporated into your final .swf. To include the library in your project, you must tell Flexbuilder (you can get afree trial or just use the free command-line tools,and add on the Apollo portion) where the library is located by going toProject|Properties and selecting "Apollo Build Path," then choosing the"Library path" tab and pressing the "Add SWC..." button. Next, you addthe namespace ak33m to your project as seen in the code below, and you‘re ready to create an XMLRPCObject.
Note: the only reason I used Apollo here was that I wasthinking in terms of desktop applications with nice UIs. You can justas easily make it a Flex app.
Here‘s the entire Apollo application as a single MXML file, which I‘ll explain in detail:

MXML is a higher-level abstraction of an application than isActionscript, but the compiler translates MXML into Actionscript, andyou can choose to write your entire application in Actionscript instead(if you want to do a lot of extra work -- you don‘t gain anything fromit).
An MXML file is proper XML, so it begins with the standard XMLtag. The body begins with a tag that determines whether it is a Flex orApollo application, followed by XML namespaces. The first namespace isthe standard mx that you‘ll see in every application, but the second ak33m is the special one added to use Akeem‘s XMLRPCObject.This is a good example of how to incorporate an external library (youcan also just place the source file in your project directory).
The focus of MXML is organizing and laying out components. Note that the main body tag includes a layoutattribute; "absolute" means that the components will be glued to theirpositions regardless of the size or proportion of the application.
MXML provides support for form creation via various Form... tags; it‘s possible to create these more verbosely, but notice that using the Form... tags requires lesswork than it would in HTML (there are also helpful fancy componentslike calendar date choosers, and a number of standard validators whichautomatically check user input). The fact that the result will look thesame under every browser on every platform, without any extra effort,makes creating forms this way very appealing.
Each FormItem can have a label, and it neatly organizes the label with the item (something that would take a table in HTML). The TextInput component allows the user to enter text, while the Text component is for display. I‘m just showing you the very basic use of these components; they can do a lot more.
Every component can be given an id so it can bereferenced elsewhere in the program; it‘s like a variable name for thatinstance of a component. In this program I only give ids to components that I actually reference.
Each component supports a set of events, and you can attach functionality to an event. In the cast of the TextInput, the change event (fired when the text in the input box is changed in any way) calls the manipulate() method, defined at the bottom of the program.
The XMLRPCObject, in this case, only needs an id and the "endpoint" to tell it where the server is.
A Script object is wrapped in CDATA because it maycontain special characters that need to be escaped. Here, you seeActionscript code embedded directly into the MXML file, but it couldalso have been placed in an external .as file and referenced from within the MXML.
One of the first things you‘ll notice about Actionscript, as aJava programmer, is how remarkably similar it is to Java. Many of thebasic concepts and even keywords are the same, which makes itrelatively easy for a Java programmer to learn. However, Actionscriptoften makes things a lot easier than Java does -- for example, whilepackaging and import statements are very similar, you are not facedwith the nightmares of Java‘s CLASSPATH.
Some things are different. As you can see, it‘s possible tohave free-standing functions. And when you define a function, you mustactually use the function keyword (Actionscript is actually asuperset of Javascript). Type declarations are optional (althoughFlexbuilder issues warnings, and I like my warnings to be useful so Iadd the necessary syntax); without them you get dynamic typing. Typedeclarations are expressed after type identifiers or function argument lists, following a colon.
Note the manipulate() function, which takes no arguments and returns void. Remember we set up the TextInput instring to call manipulate() whenever the input text is changed. When this method is called, it uses the server XMLRPCObject to call both the methods available on the server. At first glance, it looks similar to the Python client.
However, the Python client was making synchronous calls -- itwaited for the XML-RPC server to return the result before continuing.Flex is set up for asynchronicity, which means that it can initiate acall and continue processing while that call runs. The problem withasynchronicity is that you need to somehow catch the result, and thesolution is to install a callback function which will automatically becalled when the result comes back. Flex comes with builtin support forinstalling asynchronous callbacks, as you can see from the import statements.
The callbacks are attached as ItemResponders to the object returned from the XML-RPC call, using the addResponder() method. The first argument of the ItemResponderconstructor is the function to be called upon success, the secondargument is the function to be called in the event of failure. For bothcalls we are only interested in the first argument that comes back,which contains the result value from the XML-RPC call (from the code,you can see that it‘s possible to construct more complex callbacks).All the "success" methods do is insert the results in the appropriatetext fields.
Performance
Flash 9 includes a new, high-speed JITcompiler which has a very large impact on application performance --some have suggested as much as 10x. The UI portion of your applicationis thus unlikely to be a bottleneck; it‘s more probable that theunderlying Python program (in this case) or even the XML-RPC callsmight cause slowdown, although you‘ll find that making local XML-RPCcalls tends to be remarkably fast.
One of the benefits of this approach is that the UI is not onlyfast, it‘s completely separated from the implementation of theunderlying program logic, which makes it easier to apply performanceimprovements. In Python 2.5, for example, the new ctypeslibrary makes it very easy and fast to call DLLs written in anotherlanguage, so spot performance tuning becomes quite easy. If moredramatic measures become necessary, the approach used in this articleallows you can swap out the underlying application without changing theUI. In any event, remember that UI events are rarely the bottleneck ina program‘s performance, and even if you do run into issues -- dealingwith graphics, for example -- Flash is designed to optimize this kindof performance.
For me, the promise of this approach is in programmerproductivity. You can write the underlying program logic in using themost productive language for the job, and produce the UI with a system(Flex) that‘s optimized for that purpose.
Resources
I‘m currently reading Rich Internet Applications with Adobe Flex and Java by Fain, Rsputnis and Tartakovsky, and Programming Flex 2 by Kazoun and Lott, although there are lots of other books out there on Flex and Actionscript.
Watchmy calendar for upcoming Flex/Apollo events as well as the Rich Internet Application Summit.
Talk Back!
Have an opinion?Readers have already posted31commentsabout this weblog entry. Why notadd yours?
RSS Feed
If you‘d like to be notified whenever Bruce Eckel adds a new entry tohis weblog, subscribe to hisRSS feed.
About the Blogger
Bruce Eckel (www.BruceEckel.com) is the author of Thinking in Java (Prentice-Hall, 1998, 2nd Edition, 2000, 3rd Edition, 2003, 4th Edition, 2005), the Hands-On Java Seminar CD ROM (available on the Web site), Thinking in C++ (PH 1995; 2nd edition 2000, Volume 2 with Chuck Allison, 2003), C++ Inside & Out (Osborne/McGraw-Hill 1993), among others. He‘s given hundreds of presentations throughout the world, published over 150 articles in numerous magazines, was a founding member of the ANSI/ISO C++ committee and speaks regularly at conferences. He provides public and private seminars & design consulting in C++ and Java.
This weblog entry is Copyright © 2007 Bruce Eckel. All rights reserved.
Sponsored Links
Crystal Reports - Get free trial and technical resources
Free for Open Source - Continuous Integration Build Server from the makers of JIRA
JSF UI Controls for JavaServer Faces
Designing Objects & Systems : Seminar on DVD

Web Artima.com

Copyright © 1996-2007 Artima, Inc. All Rights Reserved. -Privacy Policy -Terms of Use -Advertise with Us
");}function replaceDiv(divID) {document.getElementById(divID).innerHTML = phpadsbanner;}-->