There's an old adage that one ends up writing the same software all over again, except each time using different technologies. That's true of developers who have become domain experts by virtue of long stints in a given industry, such as e-commerce, financial services, manufacturing, or HR.
Business problems tend to change less rapidly than the available technology solutions do, giving us the opportunity to, hopefully, improve on earlier attempts with each new iteration. User interfaces are an example of rapid technology development. Progress in UI toolkits partly addresses the changing needs of user interaction—for example, presenting user interfaces on mobile devices—and partly attempts to make the programmer's job easier.
The extent to which newer UI toolkits benefit a developer becomes apparent once you have worked on similar applications using different UI technologies. In this article, I relate my experience in moving from HTML to Swing, from Swing to Ajax, then from Ajax to Flex in very similar applications, and reflect on whether each of those technologies offers greater convenience to the developer. The application in each case addressed the same basic problem: it allowed auto dealerships to process their inventory and interface with financial services companies.
Although simplicity was perhaps its greatest strength, there was something inelegant and unsatisfactory about the HTML of the mid-1990s for business application UIs. To be sure, one could use the nascent Java Servlet API to generate HTML pages on the server, dedicating a large portion of an application's code to building HTML had something unattractive about it: Any change in the view had to load an entire page, and UI state had to be transferred back and forth between the server and the browser.
In a login page, for instance, suppose a user entered his email address and password, and then realized he had not yet created a user account. Web sites typically offer a Create a new account link next to the login button. Without client-side scripting, the new account link would have to go back to the server, which then would render a new page with additional fields to fill in. If the user reloaded his browser window, the system would have to remember to render the "account creation" versus the "login" state. As well, the account creation page should ideally reuse the email address and password the user earlier entered.
When Swing became a viable option, I thought I could finally benefit from making my user interfaces more interactive, reuse all those attractive UI widgets, code my UI entirely in Java, and deliver my application as an applet inside a browser—if I could only wait long enough for the Sun folks to cook up a practical and universally available way for users to access applets.
I waited, and waited, and waited, and in the meantime spent many a precious day writing HTML-generating code on the server. And then I waited a bit longer, and during that time learned to use new-fangled server-side frameworks to make the HTML generation more bearable. And then I waited even longer, and came to accept that applets would just not happen.
What did happen, though, was an opportunity to work on a similar application from the ground up, using any UI toolkit I wanted. Server-generated HTML was just not going to cut it this time. Applets were not practical, but Swing was thriving, and IntelliJ just showed the world what one could accomplish with a purely Java UI.
That's how my desktop Swing application was born. We used the new JNLP APIs and deployment mechanism, and was fairly successful in allowing users to update their JREs and install our app on their desktops with a single click. There it was: Swing running on users' desktops, in a business app written end-to-end in Java. Swing provided the interactivity that HTML couldn't, and its component architecture allowed me to focus on business-specific code.
Over time, though, Swing nirvana gave way to Swing realities. Although I did not have to create layout and rendering code in Swing, implementing new features was still a big undertaking: a lot of code had to be moved and refactored. Swing proved to be rather verbose: Defining a form that would have taken a few lines of HTML required a much more careful and laborious approach (even with the excellent JGoodies FormLayout). UI state could only be updated from the Swing event handling thread, and even then any update necessitated careful code review to avoid inadvertently hanging the UI.
Swing clearly needed a framework for common tasks, similar to server-side enterprise Java frameworks, but it didn't have one. There was some excitement in the Swing community when the JCP published the specs for the Swing Application Framework, JSR 296; but JSR 296 didn't go very far, and neither did many of the third-party additions and enhancements to the core Swing libraries.
That was perhaps in part because developers started to see promise in the advent of Ajax frameworks at just about that time. After all, Ajax allowed one to write apps that appeared to rival what one could accomplish with Swing, except that these apps ran inside the browser, alleviating the need for client-side JRE updates and installations. In addition, some server-side frameworks, such as Rails and JSF, took great pains to integrate with a few Ajax frameworks in the presentation layer.
As our application became even more popular, a few performance issues cropped up here and there, and we had to start thinking of scaling long before we would have reached that point with Java. Part of the scaling issue was rooted in the UI architecture, though: Rails made things easy when computation was sent to the server and the UI was merely doing presentation. That was a bit of a throw-back to the HTML-generation days, and a move away from Swing, where lots of user interaction could be processed directly on the client.
The further I got into using YUI, the further I departed from the beaten Rails path. After a while, the Rails and Ruby parts of the app started to look like a JSON server, merely serving up requests from the clients. Would server-side Java not have done an equally fine job at JSON serving, but without the performance issues? I wondered.
Most application design emerges over time, which makes refactoring an important tool in sharpening the robustness of a codebase. Refactorings come in various sizes and shapes, from renaming of private methods and variables to moving and renaming classes across packages and modules. Larger refactorings often incorporate hindsight that, in turn, can make a codebase simpler.
Having gotten used to IntelliJ-style refactorings with Java, I was, perhaps naively, surprised that refactoring a largish Ruby/Rails application requires far more finesse and caffeine. Unless one has an iron-tight test suite, covering virtually every aspect of the code base, big refactorings of a Rails app can be an exercise in guts and bravery. I could never be sure if I inadvertently broke something, even though my tests all passed. Mistakes did not happen often, but I would on occasion get calls from users, compelling me to log into a production server, fire up vi, and make the needed changes then and there—an absolute worst practice.
But it was ultimately the desire to create more engaging user experiences, especially in the presence of larger amounts of data on the client, that led me to look into Flex. Flex just then reached its 2.0 release, making use of ActionScript 3. Coming from a Java and then Rails/Ruby background, Flex's Flash heritage seemed foreign, even alien, to me: I had not much interest in creating Flash animations or movies; I was interested in business applications.
ActionScript's language improvements were a nice feature, but I already enjoyed most of those benefits when programming with Java and Swing. What Flex had that Java and Swing didn't, was a very well-designed, visually appealing UI widget library; and, on top of that, the ability to seamlessly embed Flex content inside an HTML page. That sounded like some combination of Java's and Ajax's benefits.
Our Flex-based application has been in production for two years. During that time, we evolved the app with new features, and implemented an almost complete UI makeover, moving from a browser-based app to one accessed via a desktop icon and delivered on the AIR toolkit.
Before comparing from a developer's perspective the various UI technologies I used throughout this application's evolution, I must note that all these technologies are capable of achieving similar results in terms of usability and visual appearance.
Recent advances in HTML and CSS make Web UI's indistinguishable from user interfaces created via non HTML-based technologies: browser performance, built-in support for SVG and video rendering, and CSS-based layouts can make HTML-based UIs very polished. Swing, while looking the October rose when used with its default look and feel, can also be visually attractive in the right hands, as Chet Haase and Romain Guy showed in their book on Filthy-Rich Clients. Finally, Ajax toolkits, such as YUI, provide sharp-looking, skinnable widget libraries.
How easily a developer can achieve an attractive UI is another matter, though. While much depends on a developer's sophistication and knowledge, creating attractive-looking UIs requires different levels of effort with each of these UI approaches. Swing programmers can achieve virtually any UI effect and appearance, because Swing gives the developer access to Java's low-level graphics primitives. Such low-level programming, while a great deal of fun, is not always practical in the context of a business application. It is also possible to apply third-party look-and-feels to a Swing application, which can improve the default Swing appearance considerably, and with much less effort.
HTML and CSS-based UIs are often developed in conjunction with designers. Separation of designer and developer responsibilities may be appropriate in many cases, and even necessary; but it also incurs additional cost and complexity.
One thing that attracted me, a graphically challenged developer, to Flex in the first place was that Flex's default UI appearance was already beyond anything I could have ever designed. In addition, Flex components, like their Swing cousins, define UI delegates that make it easy to customize a component's visual presentation. Unlike in Swing, where you can code up and associate a new UI delegate with a component, Flex lets a developer specify some delegate settings via a CSS stylesheet as well. CSS-based component styling brings one of the best features of HTML to Flex developers. Similar functionality for Swing was discussed in the Java community several years ago, but then the JavaFX effort crowded out such desires.
Specifying UI presentation closely relates to each framework's programming model. It is in their programming models that HTML, Swing, Ajax, and Flex differ the most.
HTML can be considered a layout language in the sense that HTML code specifies the positioning of components on the screen. Inasmuch as HTML code works closely with the browser's DOM and rendering engine, it can also be considered a domain-specific language for container-based UI layout. HTML's simple, container-based layout model has proven very effective, and is well-understood by developers.
At the opposite end of the programming model spectrum stands Swing: with Swing, you get the full power and expressivity of the Java language, but not much that would simplify common UI tasks. Even container-based layout, a common UI development chore, is performed in full Java code. JavaFX attempted to address that with a scripting language, but JavaFX was not Swing and did not work well with existing Swing code or components.
Flex does not impose any sort of system-wide architecture on a Web application: A Flex component can be embedded into an existing HTML page, progressively enhancing that page, or it can serve as the basis in a page-per-application model where the entire Web is, in effect, the Flex app. A Flex application can interact with its environment in a variety of ways: It can acquire data from its surrounding HTML page via Flash variables, it can communicate HTTP-bound data sources, or it can take directly invoke server-side Java objects via the open-source BlazeDS framework.
BlazeDS, in particular, has proven effective in our application, as it not only takes care of remotely invoking methods on server-side Java objects, it also serializes complex methor parameters and return values, converting between Java and ActionScript objects. That enables a client-side application to benefit from a rich server-side object model common to many business applications.
Flex also seems to be improving with each new release. The latest version, Flex 4, introduced a new component architecture with strong separation of visual and non-visual application elements. That separation directly facilitates closer collaboration between designers and developers, a familiar arrangement for those working with enterprise Web apps.
Overall, however, I found Flex fun to program in. While Flex is not without shortcomings, it is so far the most desirable solution I found throughout the journey of writing a similar kind of application four times, each time with different UIs.
Flex 4 Fun by Chet Haase
Frank Sommers is Editor-in-Chief of Artima.