SWT (standard widget toolkit) has been billed as the fresh new way to develop desktop applications in Java, and is claimed to offer performance on par with native applications and a look that exactly matches that of the native platform. Should developers stop writing their desktop applications in Swing and move to SWT? The answer is clearly NO! As this article will detail, Swing performance can, and often does, exceed that of the equivalent SWT app. Further, Swing can provide a look and feel that exactly matches that of the platform, provides a more consistent cross-platform story, and offers a level of flexibility far and beyond what is possible with SWT.
In 1995 when the first release of Java was being assembled a small group of developers was given responsibility for creating the GUI toolkit, with about three months to go from start to finish. The result was AWT, the "Abstract Windowing Toolkit." The AWT developers got the job done in time by employing a simple architecture: they just perched the AWT components, graphics primitives, and events on top of similar elements from the underlying native toolkit. Because the native Macintosh, Win32, and X11 toolkits that AWT was balanced on top of were all somewhat different, a layer of "impedance matching" code had to be inserted in between AWT and the underlying toolkit to ensure that AWT semantics were truly portable. This layer started out small.
The original AWT GUI toolkit was sufficient for creating small user interfaces and decorations for web pages. However, it quickly became clear that developers wanted to do a great deal more. Unfortunately AWT had two problems: it didn't include the breadth of GUI components or graphics capabilities that developers expected, and its "perch" architecture made portability difficult and OOP extensions to the toolkit impossible. Although the first problem was remedied with increasingly complex impedance matching code, the second problem was fatal. The AWT team responded by making the AWT's component base classes "lightweight", which meant that they could be used as the basis of GUI components that were pure Java and did not rely on a native component peer.
Developers quickly took advantage of the new feature and began creating their own "lightweight" toolkits. Before too long there were dozens of competing standards. In 1997 Sun launched its own Swing lightweight toolkit into the mix, with strong encouragement from IBM and others. Over the next year or so Swing established itself and in the 1.2 J2SE release the Swing API was moved into the Java core. Because building great components and applications requires solid, high-performance graphics support, the 1.2 release also included the new Java2D API. The Java 2D API is a set of classes for advanced 2D graphics and imaging, encompassing line art, text, and images in a single comprehensive model.
One of the most important reasons that drove the developer community to settle on Swing was that "toolkit wars" don't benefit anyone. What the community needed was a way to write portable GUIs, and Swing has satisfied that need for the past five years. Although it's an entertaining exercise, there's little to be gained from promoting yet another slightly different vanity API for creating buttons and menus and tables and graphics. One need look no farther than the KDE/Qt GNOME/GTK schism in the Linux community to see how destructive this can be.
So now we're faced with emergence of just such a schism in the Java community. SWT is a new perch architecture toolkit that was intended to be the foundation for an extensible IDE platform that would "eclipse" all others. When SWT first emerged many of us were reluctant to make much of its flaws since we prefer to focus on strengthening the standard Java APIs. Also, similar projects come and go all the time. However, the authors of SWT are all too eager to make a success of SWT by driving a wedge into the middle of the Java community. So in this article let us take a close look at some of SWT's flaws as well as refute some of the the specious arguments that are often made to support SWT.
SWT's authors cite performance as one of the main reasons for creating SWT, arguing that at the time Swing did not offer adequate performance. At the time, certain parts of the toolkit were sluggish, but that was four years ago and Swing's performance has dramatically improved since then. While we don't doubt there are execution speed benefits to be gained from just exposing the native toolkit with Java APIs, end users are concerned about how an overall application performs, not how an isolated component performs. There are many Swing-based applications in the marketplace that validate Swing as a viable toolkit for developing rich applications with more than adequate performance.
Swing has had a bad rap for being slow. In 1998, with the debut of the first release of the Java 2 Platform, there were definitely performance problems in some areas. However it's now four years later and performance has been quite good for some time. The releases following 1.2.0 added the HotSpot VM [1], hardware accelerated graphics [2], and extensive tuning. According to our benchmarks, execution time performance of Swing in the current 1.4.1 release is twice as good as in the early days. The following chart shows total execution time for five Swing components in terms of an internal benchmark.
Although performance is one of SWT's claimed advantages, most non-partisan developers who've actually compared SWT apps with Swing apps have reported that there are few noticeable differences. And as you'll see below, SWT has scalability problems that can cause serious performance problems! Of course the most important evidence of good Swing performance is in the large commercial applications that use it, for example. Borland's JBuilder or IntelliJ's Idea. You'll find more applications in the Swing Sightings column.
The Swing architecture creates a uniform boundary between data and the visual presentation of that data, between the "model" and "view." GUI toolkits that aren't structured this way force applications to transform and copy their data, which inevitably leads to performance and scalability problems in real world applications.
SWT is really just a thin veneer over the native toolkit, so as one would expect, all application model data must be copied from application data structures to native toolkit components. Developers can't choose a representation that best matches their applications needs. Consider a spreadsheet application, in which the user is presented with a very large table but the table data is sparse. It is trivial in Swing to create such a model and bind it to a JTable. The time required to construct such a JTable is constant, whether 10,000 or 1,000,000 rows are shown to the user.[3]. The same is not true of SWT. It takes SWT 5 seconds to show a 40,000 row table [4], and I gave up waiting for SWT to display a 100,000 row table after one minute. Additionally, as SWT creates a native widget for each row, memory grows and grows with each additional row. The same is not true of Swing.
SWT is similar to the AWT in that there's a one-to-one correspondence between Java components and their native counterparts. This trivially gives applications a look and feel that matches the native look and feel, at least at the component level. Swing emulates the native look and feel through a pluggable module. Many applications choose to use alternative look and feels, for example the Java look and feel or the new Alloy look and feel. Developers who choose to use the Swing emulation of a native look and feel do occasionally complain about differences between Swing's emulation of a native look and feel and the real thing. Generally speaking, that kind of problem is readily fixed.
Swing has been faulted (reasonably so) for failing to provide XP and GTK look and feels. This will change with the introduction of 1.4.2. In 1.4.2, Swing will have both an XP look and feel and a GTK look and feel, further improving Swing's native look and feel story. Additionally there is nothing about Swing's architecture that precludes a look and feel identical to that of the platform's toolkit. Apple's Java support has gotten rave reviews for its identical rendering to that of the native platform toolkit.
The Java platform strives to provide a consistent developer experience regardless of the underlying platform. This is crucial in enabling developers to write once and run anywhere. As the following quote from the SWT home page shows, SWT doesn't attempt to provide consistency between platforms:
SWT also attempts to avoid "sugar coating" the limitations of the underlying operating system, since doing this always implies significant overhead in addition to introducing the potential for subtle failures and incompatibilities; this is the "sometimes you have to let the o/s win" rule. An example of the kind of problem that SWT would not attempt to hide is the existence of limitations on cross-threaded access to widgets. [5]
What's troubling about this statement is that SWT developers will need to know the limitations of the underlying native toolkit. In other words, when it comes to the most fundamental feature of Java, support for cross-platform applications, SWT punts!
Although one might show small applications that manage to navigate around this minefield, large-scale applications are sure to trip over platform-specific issues. Although the value of supporting cross-platform development should be obvious, it's worth noting that an SWT developer will be facing six different toolkits at last count. This cost ripples into the resources needed to test your application, requiring a more extensive testing matrix to ensure you have not unknowingly missed a subtle difference in one platform's toolkit vs. another platform's toolkit. Such differences can also constrain application design.
If you're willing to give up cross-platform support, perhaps you'll be happy to toss support for automatic storage management out the window, too.
One of Java's strongest selling points is the built-in garbage collector that obviates the need for developers to allocate and free resources. Automatic memory management solves two big classes of bugs. The first class is where developers forget to free resources. The second class is where developers accidentally free resources too early, when they are still being used elsewhere in the program. Most developers would argue that the second class of bugs is actually much worse than the first. The second class of bugs can lead to crashes on some systems with SWT. Both kinds of bugs grow increasingly common as systems grow larger, and fixing them becomes increasingly difficult.
SWT requires the developer to manually track and dispose of resources that are no longer being used:
If you created it, you dispose it. [6]This rule applies to all resources, including colors (yes, colors) and fonts. Some individual developers may find that punting the last eight years of Java GC technology provides an appealing opportunity to while away the hours building their own storage management infrastructures. As those projects grow in scale and complexity, those same developers will have the same epiphany that has led countless others to build systems that rely on automatic storage management.
Swing is a rich GUI toolkit offering a great deal of flexibility to component and application developers. For example, it is trivial to customize the painting of a particular widget, or the event handling, or the key bindings, or almost any other aspect of Swing. Because SWT offers a veneer over another toolkit, it must provide the lowest-common-denominator view of those toolkits and their components. This makes customizing aspects of the toolkit difficult, if not impossible, and may involve native code! Even simple things, like making all buttons slightly larger, are not trivial in SWT.
The Java 2D APIs provide an easy avenue for developers to combine widgets with advanced 2D graphics and imaging, encompassing line art, text, and images. SWT graphics support is minimal and closer to that of the Java 1.1 API's, a clear step backward in functionality. If the developer wants a richer API set they will most likely need to write native code specific to each platform that needs to be supported.
One of Swing's strong points is the ability to create a custom look and feel, allowing you to create an identity for your product. In fact a number of third party look and feels [7] exist today that can easily be used in a Swing application without changing a line of code. Because SWT is designed to provide the look of the native platforms, creating a custom look is very difficult and may involve code specific to each platform you intend to support.
Swing and SWT do not work together [8]. Swing is a lightweight toolkit (it does all its own rendering) that does not work well with heavyweight widgets. Because SWT is a heavyweight toolkit, Swing and SWT do not work well together, and in fact may never work together on some platforms.
Since SWT consists of a native library, the end user is required to grant full access to an SWT-based applet or application deployed with Java Web Start. Because Swing is a core part of the Java platform, a Swing-based application does not require full access and can run unsigned, allowing for seamless deployment options.
Swing is an extremely flexible toolkit that can offer performance on par with that of SWT. In fact, because of the level of extensibility offered by Swing, its performance can far and away exceed that of SWT. Swing requires very little from the native platform, allowing you to write once and run on a number of platforms without needing to consult the documentation of another toolkit. For all these reasons, Swing is still the superior technology for writing cross-platform applications.
| 1: | Java HotSpot Technology |
| 2: | High Performance Graphics White Paper |
| 3: | TableTest.java see my briefcase in the sidebar (you'll also need Args.java) 1.57 seconds on a 1.6Ghz Intel Pentium 4 machine running RedHat 8 with J2SE 1.4.1 with arguments -rows 1000000 -empty -exit |
| 4: | SWTTableTest.java - (see my briefcase in the sidebar, you'll also need Args.java) on a 1.6Ghz Pentium 4 machine running RedHat 8 with SWT version 2.0.2 and J2SE 1.4.1 with args -rows 100000 -exit |
| 5: | SWT home page |
| 6: | SWT: The Standard Widget Toolkit: Part 2: Managing Operating System Resources |
| 7: | Kunstoff and Alloy Look and Feels, L2F's look and feels, and Compiere. |
| 8: | SWT FAQ: Can I use Swing or AWT inside Eclipse? |