Skip to main content

Swing for the Web--Are We Getting Closer?

Posted by cayhorstmann on January 21, 2008 at 10:10 PM PST

swinging twins src="http://www.horstmann.com/twins/mountain-lake-swings.jpg"
style="margin-right: 1em; width: 20%; float: left;" />When I first heard
about JavaServer Faces, way back at the 2002 Java One conference, it was sold
as “Swing for the Web”. That caught my attention. I was sick of
“assembly programming for the Web” with HTML, JavaScript, HTTP,
cookies, servlets, and that special form of torture—JSP custom actions.
Ever since, I have pinned my hopes on JSF because it has one thing going for
it: a component model. When I need, say, a progress bar, I want to
leave it to someone more skilled than me to make such a thing out of images,
JavaScript, or whatever. I just want to hook it up to some property that has
a progress value and move on to the next task. After all, when I use a
JProgressBar in Swing, I don't worry about the pixels and
animations either.

In that regard, the first release of JSF was a cruel disappointment. The
standard JSF components are very primitive. The most sophisticated one is the
data table, and it pales in comparison with a Swing JTable. No
progress bars, trees, menus, popups, or any of the other building blocks that
you want for a snazzy application. I don't want “FORTRAN for the
Web”.

In the last couple of weeks, I had to hack together a simple system to
support classroom discussions. The instructor puts up a question, students
give anonymous answers, and then the class looks at the collective wisdom and
has a (learning insight|good chuckle). Many instructors use
“clickers” for this purpose—special hardware devices with
voting buttons. But I wanted students to send text and images, not just
multiple-choice answers. (Also, they all already have a laptop, but they'd
have to buy the clicker.)

elephant src="http://today.java.net/images/tiles/111-elephant.gif"
style="margin-right: 1em; float: left;" />At first, I thought, oh no, don't
make me eat
the elephant again
, and I longingly looked at href="http://www.rubyonrails.org/">Rails, href="http://grails.codehaus.org/">Grails, or href="http://liftweb.net/index.php/Main_Page">Lift for my salvation. But
then I googled for "Rails progress bar", and the results were depressing. I
noted that NetBeans 6 has a perfectly good progress bar in the href="https://woodstock.dev.java.net">Woodstock component set, so I
decided to go with JSF once again. This time, Swing for the Web seemed within
reach. Here is what worked and what didn't.

  1. up The Woodstock
    components look pretty nice—much nicer than anything that I could
    put together with my limited CSS skills. For example, the alert component
    has some shading, some graphics, all that stuff that I am too busy to
    work on. Exactly what you want from a component set.
  2. up The progress bar
    worked great. I didn't have to know anything about AJAX. That's good
    because I really don't want to know any more about AJAX than about href="http://asn1.elibel.tm.fr/">ASN.1. For an application
    programmer, this should just be plumbing.
  3. down The href="https://woodstock.dev.java.net/Documentation.htm">documentation
    for the Woodstock components is totally wretched.
  4. left The NetBeans
    form designer is adequate for dragging together a basic UI, but it
    insists on the “Creator” model where each JSF page has a
    backing bean with bindings for each component. That may make sense for
    ASP.NET programmers, but I hated it. Apparently, this will go away in
    Netbeans 6.1. I used the form designer for the initial layout, then
    converted everything to plain JSF. I also had href="http://www.nabble.com/visual-web-JSF-page--jsp-and-design-out-of-sync-td14750202.html">other
    issues that hopefully will get addressed in a future version of the
    UI builder.
  5. down Achieving a
    common page layout, with a title bar on top and a menu on the left, is
    still way too hard. I want the framework and tools to guide me, not fuss
    with page fragments.
  6. up I used the XML JSP
    syntax and XHTML for the pages, and NetBeans caught all my silly
    formatting errors—a big help. (Why don't I follow that good advice
    in Core JSF? I tried, but my co-author and the reviewers all felt
    nostalgically attached to ye olde syntaxe.)
  7. up NetBeans is pretty
    good about keeping the various configuration files in sync, and I didn't
    have to fuss much with faces-config.xml.
  8. left If I had used
    Seam, I could have
    ignored faces-config.xml altogether, but I ran into some href="http://forums.java.net/jive/thread.jspa?messageID=253975&#253975">GlassFish
    problems. Once href="http://jcp.org/en/jsr/detail?id=299">WebBeans is integrated
    into NetBeans/GlassFish, I will definitely go that route.
  9. up JPA was a winner.
    Having the ORM and caching for free is nice, and JPQL is far less tedious
    than SQL. I spent essentially no brain cycles on persistence. Mostly,
    that was because my app is so simple that I never felt the need to export
    any entities outside the managed environment. Again, Seam/WebBeans would
    make this even nicer.
  10. down I still got
    the href="http://weblogs.java.net/blog/cayhorstmann/archive/2006/09/the_power_and_p.html">Stack
    Trace From Hell far more times than I wanted to. NetBeans did a
    fairly creditable effort in trying to scrape what little useful file
    name/line number data it could find. This still needs lots more work. For
    example, errors in session beans are silently swallowed.
  11. up The NetBeans
    debugger saved my bacon many times. It is very savvy about tracing from a
    JSF bean to a session bean, bypassing the intermediate layers.
  12. down I tried my
    best to use hot deployment, and even hot-switched code whenever possible.
    But every time that I edited a JSF page or even a CSS file, I had to
    redeploy, redeploy, redeploy, and each time, I stared at the console for
    what seemed like an eternity. I hated that. My Rails friends tell me that
    they can keep tinkering with their code without ever redeploying.

Overall, I felt that I still had to focus far too much on the care and
feeding of the app server. GlassFish programmers—remember that the app
server is not just a tool to run perfectly working applications, it is also a
part of the development environment!!! We need good error messages and
red-hot deployment to be productive.

Swing for the Web is getting closer. Woodstock, href="http://labs.jboss.com/jbossrichfaces/">RichFaces, href="http://myfaces.apache.org/trinidad/">Trinidad, all show promise.
But do we really want all of them? After all, there is just one Swing. And if
we must have them all, they should all play nice in a web GUI builder. href="http://jcp.org/en/jsr/detail?id=276">JSR 276 should get us
there—that started in June 2005. How time flies!

Apart from the UI components, we need more architectural guidance for
mediating between the UI and persistence layer. I think JPA with
Seam/WebBeans is our best bet, and NetBeans should support it ASAP.

All these issues are solvable, and I am hopeful they will be solved. I did
enjoy having the Java API for all those other things I needed to do (such as
crypto, zip file management, image manipulation, and so on). In the end, I
was able to hack together a somewhat nontrivial application using NetBeans,
GlassFish, JSF, and JPA, in a couple of weeks, while at the same time
contending with sick infant twins and a broken clothes dryer. Not bad...but
it could have been one week without the Stack Trace From Hell and redeploy,
redeploy, redeploy.

Related Topics >>

Comments

Have you tried javarebel, to get real hot deployment: http://www.zeroturnaround.com/javarebel/ Never tried it, but seems promising.

However, to me that seems too little too late. It is somewhat behind the competition, has no video/codec support and is highly dependent on a yet-to-be-released distribution improvement of the JRE. Behind in some aspects, yes, particularly the ones that you mentioned. However, I don't think it's too late just yet. The RIA game is just getting started, and Sun can claim advantage in other aspects, particularly the maturity, richness, and developer mind share of the Java platform. That's why I still think if they throw more resources at this effort, especially where they are lacking, they might still be able to catch up.

"I also hope that Sun would see the writing on the wall and divert all of their resources from the JSF effort toward their RIA one."
Some would argue that it's also what they are doing with the JavaFX (Script) stuff. However, to me that seems too little too late. It is somewhat behind the competition, has no video/codec support and is highly dependent on a yet-to-be-released distribution improvement of the JRE.

Totally agree with what kweinber said. JSF is pretty much a dollar short, and a day late technology, which has been designed with the full page refresh model in mind. A model which has been pretty much obsoleted by the Ajax movement. So all JSF it is trying to do now is change engines mid flight so that it can fit better within this new Ajax model. But we all know that's not gonna work: That's the impedance mismatch that kweinber is talking about. I think you'd better off pursuing a RIA based approach at this time for whatever JSF has originally set out to accomplish. I also hope that Sun would see the writing on the wall and divert all of their resources from the JSF effort toward their RIA one. Take a look at Simon Morris blog on this topic, he has some pretty good insights.

HTTP/HTML pages loaded on demand and Swing are two different things. JSF hasn't ever worked well because what it is trying to achieve simply doesn't make sense.

If you really want Swing, you should use Swing. If you need it delivered via a browser, you should use GWT (which is as close as you are ever going to get).

JSF will always be a waste of time. The impedance mismatch between a request-based model with all state on the server-end and a stateful, local gui is too great to overcome. The illusion falls apart when you want both local-responsiveness and remote state. You need a coherent, persistent event-context for your event-handling to work and the only way to get that is to run a persistent local gui.

There is a Hibernate4GWT but JPA will work "differently". GWT is a compiler that takes Java source code and compiles it to obfuscated JavaScript (its far more complex than that but thats the general principal). So currently (GWT 1.4) only Java 1.4 syntax is supported (e.g. no annotations or generics), you can use the 1.5 version from CVS which has support for annotations and generics but it might not be a good idea to serialize a JPA object into the client tier.

Generally the "right thing(tm)" with GWT is very similar to the same concept in Swing, passing a JPA object from a remote tier to a Swing client would work but has security and merge issues. You would be better off hiding the server JPA behind a facade and GWT has a simple RPC mechanism that supports object serialization (you pass Java objects and they dynamically pass into JavaScript compiled code... its really amazing).

@christiaan_se: Thanks for that link. I had a look at the article. I guess I don't want to bring the actual Swing to the Web. I just want a Web programming API that makes me productive, in the same general sense that Swing makes me productive for client-side programming.

A somewhat related and interesting discussion can be found on: http://www.theserverside.com/news/thread.tss?thread_id=40037 It mentions some interisting implementions to bring swing on the web.

A few thoughts that came to me while reading your otherwise excellent blog entry: There is not just one desktop Java UI framework, both SWT and QT Jambi represent a significant improvement getting-it-done wise (and has more controls, good luck finding a date control in the JRE). It strikes me as odd that you want to compare JSF up against Swing. Swing is a nightmare to get things done in, based on the extremely vague and cumbersome JavaBean component model and relying on L&F UIDelegates having been architected to everyones satisfaction. The fact that Apple can hold out on a Java 6 for so long and the only complainers seems to be Java developers, is a pretty big indicator that Swing has been a tremendous underachiever. I attribute this to a missing component model, hence, I'm a proponent of properties and events in Java 7. Last but not least, I am surprised you do not bring up the issue of managing layout for JSF using NetBeans. Unlike i.e. JDeveloper, NetBeans insists on positioning everything by pixels - not exactly scalable across the wide medium the browser is.

Interesting article. On the deployment problems: at least with Facelets, you can replace the XHTML templates of a deployed web application directly in domains/domain1/applications/j2ee-apps/.../yourapp_war. Works like a charm for me (without it, it would be redeployment hell as well).

@cay: I am actually not sold on RIA, it is just that I think that JSF can't ever cleanly adopt the clean component model of Swing. I actually find the action-oriented frameworks the most straightforward for web programming.

Why not JSF? Swing is innately event-driven, which essentially means that guis are fancy state-machines. JSF tries to be a client-side/server-side hybrid state-machine, which has recently tried lately to mix client-side and server-side state with Ajax. . . Overall, the concepts are so complicated, there is no way to keep the state straight and the programming model as simple as Swing.

@kweinber, mikeazzi: I am afraid I am not sold on RIA as much as you are. I just want to write a web app. I can live with the limitations of HTML and the page flashes (as long as it isn't in the progress bar :-)) When I said "Swing for the Web", I merely meant "a programming model that lets me focus on components and events".

@gadominas: Thanks for the link to the Wicket progress bar. Unfortunately, that is only with file upload, which isn't what I needed. I heard good things about Wicket. However, I find it unfortunate that each of these projects independently recreates a web widget set. I'd rather have one or two good ones than a whole bunch of mediocre ones.

You didn't mention about facelets. It makes JSF html authoring friendly.

Great articale, Cay. I saw Echo, GWT and some stuff like that, but no one marked "Wicket". Wicket, a lightweight, component-oriented web application framework in plain Java. Even progressbar component is on hands :) http://www.wicket-library.com/wicket-examples/upload/single

GWT is pretty much as close as you can get to Swing For the web, its remarkably powerful and easy to use... I also enjoyed using Echo2, myself and I noticed quite a few powerful frameworks using similar concepts (I came to prefer GWT recently).

Notice that I'm not dissing JSF/JSP, they have their place but they are not very good for web "applications". JSP is great for web sites (big difference).

A web site can employ AJAX but is essentially a document based system whose purpose is to navigate between pages (JSP/JSF rock there and Swing isn't all that great there). GWT/Echo2 and Swing excel in the more "free form" interactive applications, this seems to be the use case you have here.

BTW GWT works rather well with JSP allowing you to combine the strengths of both.

@mrmorris: Thanks for your interesting comments. Not having a date control in Swing is definitely sad. (Or a font chooser...) Just for the record--the NB6 web form designer defaults to absolute positioning (which is pretty useless), but it is easy to turn it off.

@vprise: Thanks for the heads up on GWT. I'll have to look into it more seriously. Does it play nice with JPA?