4.1 Swing and Aqua

Swing is the user interface toolkit of Java Foundation Classes (JFC). When Sun developed the original version of Java, it introduced the Abstract Windowing Toolkit (AWT), which drew user interfaces based on an abstract layer that sat on top of the native windowing toolkit. This caused many problems, as the abstraction tended to blur when faced with the peculiarities of many windowing platforms. To resolve these issues, JFC and Swing were introduced as a more sophisticated toolkit with much better cross-platform support. JFC and Swing are based on AWT, so the core AWT is still part of Java. You could even write a pure AWT application, although there's really no good reason to: if you're developing a rich user interface you'll want to stick to Swing APIs.

One of Swing's most interesting aspects is its notion of a "pluggable" look and feel. The entire Unix world has a high degree of customizability, at the cost of a staggering variety of different approaches to user interface design. At first, these custom behaviors and functionality seem ideal, but they soon become a headache for developers and users. To deal with this issue, Swing introduced a standard look and feel called "Metal" that provides a reasonably attractive user interface for all platforms. Metal looks the same, more or less pixel-for-pixel, on all supported platforms.

However, it is still possible to override Metal and use a custom look and feel instead. Windows users may choose to add a Windows-specific look and feel to their application instead of going with the standard Metal. On Mac OS X, the obvious choice is the native Aqua look and feel. Apple has done an excellent job with their implementation of the Java-based Aqua look and feel, with many graphical operations featuring native hardware acceleration.

Therefore, when developing applications in Java, it is useful to determine what your supported look and feel options are going to be. While it's possible to say that you intend to support Metal, Aqua, Motif, and Windows look and feel selections, you'll wind up having to test your application's appearance (including the length of localized strings?you were planning on making your application localizable, right?) on each supported look and feel. This is largely a matter of budget and resources, but in this section we will focus on comparisons between the standard Metal look and feel and the Mac OS X Aqua look and feel.

You may notice that, by default, Java applications on Mac OS X have the Aqua look and feel instead of Metal. This is a result of the default being set in a Mac OS X properties file (/Library/Java/Home/lib/swing.properties). If you wish, you could change the look and feel default to Metal, but in the interests of keeping your system as "virginal" as possible, it is probably best to change the settings on a per-application basis.

You'll notice that this chapter does not detail the basics of Swing programming; instead, I've focused on the specifics of Swing as they relate to Aqua. If you're not comfortable in Swing land, you might want to pick up Java Swing, by Eckstein, Loy, and Wood (O'Reilly).

You can specify the default look and feel for a specific application in several different ways. Chapter 3 created scripts that specified two ways to launch the NetBeans IDE. Looking at the scripts, you can learn how to set the JDK and the default look and feel. While this may work for some applications, scripts like this are poor form and should be avoided for commercial (or even in-house) deployment. Instead, use global properties files (as Mac OS X does) or some other static method. It's a real pain to have to keep multiple versions of startup scripts, or to select a look and feel every time you start up an application.

4.1.1 A First Look at Aqua

The best way to get a sense of the Aqua look and feel is to examine the SwingSet2 demo application. On Mac OS X, you should find this application at /Developer/Examples/Java/JFC/SwingSet2/SwingSet2.

If you view the application with the Terminal, you will notice that SwingSet2 actually appears as SwingSet2.app, which is in turn a directory. Chapter 10 will explore this topic more thoroughly. For now, double-click the SwingSet2 icon in the Finder.

The application may take some time to launch, but when it does, you should see the sample output shown in Figure 4-1.

Figure 4-1. The SwingSet sample application

Playing around a bit with this application, you'll see that it is built on an instance of JDesktopPane. You should also notice that the application is a miniature version of a Mac OS X desktop, complete with a rather strange "mini-dock" at the top of the application interface. This is an odd arrangement, and it's a user interface concept you won't find referenced anywhere in Apple's documentation (aside from an admonishment in a README file against using it!). It's clearly provided for compatibility with multiple document interface (MDI) applications from other platforms, but is unlikely to be satisfactory for any real GUI programming task.

If you're wondering how I knew that this application used a JDesktopPane, I simply clicked the "Source Code" tab on the application. There is also a src folder in the SwingSet2 directory, which includes the source for the application.

Clicking on the second icon in the SwingSet2 button bar, we immediately confront the largest issue of the Aqua GUI: the radical difference in size required by common user-interface elements.

As you can see by comparing Figure 4-2 and Figure 4-3, the Aqua version of these buttons requires almost 50 percent more horizontal screen space than does the Metal version. This can reduce a nicely laid out Metal interface to a jumble of clipped text and ugly ellipses when converted to Aqua.

Figure 4-2. Metal buttons
Figure 4-3. Aqua buttons

In Aqua, buttons by default have a gap of 12 pixels between them and are based on a 13-point font. This font can be a bit large when compared with other platform defaults. Rather than settling for a nasty-looking Metal interface based on these patterns, you may wish to standardize the "utility" UI patterns in Aqua for your Java applications. These smaller controls are closer to the control sizes of other platforms, and look good on Metal as well as Aqua. To support this smaller utility user interface, use controls based on an 11-point font and use a default control spacing of 8 pixels.

Another interesting contrast between Aqua and Metal can be found when comparing JList implementations (the seventh button from the left in the SwingSet2 mini-dock).

If you compare the user interface components in Figure 4-4 with those in Figure 4-5, you can see that while elements in the Aqua implementation are generally wider than those in Metal, they are often vertically shorter. So although Aqua interface widgets generally require more space than their Metal counterparts, this is not always the case.

Figure 4-4. Metal JList component
Figure 4-5. Aqua JList component

The moral here is to be extremely careful when designing user interfaces for multiple look and feel motifs. The next section shows how you can minimize these problems.

4.1.2 Look and Feel "Gotchas"

Unfortunately, many developers test their applications with the Metal look and feel, ignoring other platforms and look and feel packages. While that may be acceptable for Windows or Motif users, the Aqua look and feel implementation is excellent, and there is no reason not to test for and support it. Sizing of elements

As pointed out so glaringly in the last section, the biggest issue you need to deal with is sizing elements. When you first run your application under Aqua, you may be taken aback by the number of places where element size will affect you?from buttons that are clipped short with an ellipse, to navigation tabs that are now centered and occupying two levels, to portions of the user interface that are now unusable or even completely hidden. All things are not created equal on Aqua and Metal.

If you are bringing an application over from another platform, this may be a good time to examine the interface. Often, an application that looks too busy on Aqua is actually too busy on all platforms; Aqua is just driving the point home, especially when compared to the quality of the user interface work put into other Mac OS X applications.

The bad news is that no mantra or special set of steps can convert a Metal-size application to an Aqua-size one. That means that you'll have to dig into your code by hand and space things out until they look good on Aqua. Be sure to use the "utility" UI patterns, which dictate 11-point fonts and 8-pixel spacings. The good news, though, is that you'll end up with a better-designed application, and reap the benefits of both look and feel motifs. Background color

The default Aqua implementation of a JFrame is set to the textured background common to many Aqua applications. However, most developers prefer to use a plain white background, like one you'd see in a Finder folder or the various mail applications. To set the background to white (or some other color), you will need to use the following in your Swing code:

myJFrame.getContentPane(  ).setBackground(java.awt.Color.white);

This explicit color setting ensures that defaults on different platforms don't change your application's background color without your knowing about it. Dirty windows

Another difference between Mac OS X and other platforms is that Mac OS X applications consistently use a small dot to indicate when a window is "dirty," meaning that information has been changed and a save is in order. Figure 4-6 shows a "dirty" window icon, and Figure 4-7 shows the same icon once a save has been completed.

Figure 4-6. A "dirty" window
Figure 4-7. A window after saving

To set this "dirty" dot, use the following code:

myJFrame.getRootPane(  ).putClientProperty("windowModified", Boolean.TRUE);

Use the following line to clear the dot after a save has occurred:

myJFrame.getRootPane(  ).putClientProperty("windowModified", Boolean.FALSE); Menu bars

The last major issue to think about is the location of actions on a menu bar. The standard Mac OS X menu bar is typically organized by the scope of the action. For example, consider the menu hierarchy detailed in Table 4-1, which indicates a menu bar's headings and the scope that each heading's actions should govern.

Table 4-1. Menu headings and their scope

Menu heading



Apple menu

Entire system (including global actions)

Restart, Sleep


Entire application

Quit, Preferences, Hide, About


Entire document

New, Save, Print


Section of document

Find, Replace


Changes appearance but not data

Font, Alignment


Switches between documents

Tile, Cascade, Go To


No effect on application, but easy to find

Help, Documentation

If you use these scopes as a standard set of rules for your own menu locations and choices, you'll find that users intuitively know where to look for items and will feel at home with your application quickly.