What's the deal with Swing?
dave at thesmithfam.org
Tue Mar 28 21:08:59 MST 2006
ross at indessed.com wrote:
> <a fantastic writeup on the history of AWT/Swing/SWT>
The following opinions are highly personal. All my evidence is
anecdotal. Please enjoy my comments and rebut where you'd like.
I learned Visual Basic years ago, then AWT, then Swing, then Borland
Delphi, then SWT. Then, I picked up Qt. I've been coding in Qt (in C++)
at work for about a year now, and I love it. Qt is the greenest GUI
pasture I've ever played in. Swing is the worst. Let me elaborate:
* Swing is too verbose.
Java is, by its nature and to its credit, very verbose. This makes it
readable, but somewhat more time-consuming to write. This isn't a deal
breaker for Java. In fact, I quite like it. Swing takes verbosity to the
extreme. It takes too many lines of code to create and place a widget.
SWT got it slightly better by giving each widget its parent in the
widget's constructor. Qt got it just right by providing an excellent
graphical GUI builder that actually works!
* Hard-to-use layout managers.
One word: GridBagLayout (wait, was that 3 words?). I dislike Swing
layout managers. With Swing, I spent a lot of time
coding/compiling/running/repeating over and over to tweak layout. The
first time I tried to layout a pretty simple dialog with a few input
boxes and labels, it took me hours to get it right. If I had been
satisfied with the heinous defaults, I could have let it go after 30
minutes, but please. Any GUI toolkit that doesn't provide real-time
layout feedback wastes too much developer time. SWT got it slightly
better with FormLayout, which I found very useful. Then I discovered
Qt's layouts: horizontal, vertical, and grid. That's it. Super simple.
Qt got it right, because widgets know how they are supposed to stretch.
Don't you love the Swing "hello, button" sample program where one button
fills the entire JFrame? Who's idea was that? Qt knows that buttons
aren't supposed to expand to fill the whole panel, while other widgets
(like progress bars and line edits) usually do. Every QWidget can tell
the layout manager how to lay it out, and buttons know that they
shouldn't behave like scrollbars.
* Cumbersome Deployment
Since we're talking about desktop applications, we have to mention
deployment. Java desktop applications are hard to deploy. I think Java
WebStart is pretty nifty, but it requires a JVM to work! My experience
porting from Java 1.3 to 1.4 was painful enough to teach me that Java
apps would have to ship their own JVM (meaning they would never be able
to adapt to the already installed JVM at runtime). That's sad, because
the JVM is huge, even by today's standards. I used InstallAnywhere to
deploy my Swing app at work, and that thing took 30 minutes just to
build the installer. Now I use Nullsoft's NSIS, which takes about 3
seconds to build my Qt GUI's installer. All I do is install the 2Mb Qt
DLL on Windows and I'm done. If I don't have that liberty, then I
statically link the whole executable (which works fine on Windows and
Linux), and I have zero dependencies! Zero!
* Swing is ugly by default
Last I used Swing, it was still "ugly by default." What I mean here is
that Swing requires some heavy tweaking to make it look decent. Qt, on
the other hand, is pretty by default. I don't have to choose styles, or
subclass buttons to make my Qt GUIs look nice. SWT is pretty darn good
in this respect too, but Qt is by far better.
* Swing's canvas is crappy
It is hard to use JCanvas. I've found QCanvas to be a delight to work
with, even with very complex display/interaction. QCanvas supports
animation, velocities, and double-buffering out of the box. Every object
you create on a QCanvas knows how to draw itself, and you can reposition
them with a single line of code, without having to worry about all the
other items on the canvas. JCanvas doesn't provide such a powerful API.
* Swing is slow by default
It's bad to do heavy lifting on the event thread. Every GUI developer
knows this. Swing makes it hard to avoid though. So they invented the
invokeLater() hack, which ends up filling your code with anonymous
instances of Runnables (Runnable is pretty cool, though), which still
get run in the event thread, just a tiny bit later, resulting in a slow
GUI. On the other hand, all of Qt's API is non-blocking. That means you
can call QSocket.connect() and it will immediately return. The QSocket
will notify you when it's done. The same is true of all of Qt's classes.
In Swing, you would have to code all that infrastructure yourself.
Thanks for reading! Hope you found this useful!
More information about the PLUG