Swing provides many features for writing large-scale applications in Java. Here is an overview of some of the more popular features.
One of the most exciting aspects of the Swing classes is the ability to dictate the L&F of each of the components, even resetting the L&F at runtime. L&Fs have become an important issue in GUI development over the past 10 years. Many users are familiar with the Motif style of user interface, which was common in Windows 3.1 and is still in wide use on Unix platforms. Microsoft created a more optimized L&F in their Windows 95/98/NT/2000 operating systems. In addition, the Macintosh computer system has its own carefully designed L&F, which most Apple users feel comfortable with.
Swing is capable of emulating several L&Fs and currently supports the Windows, Unix Motif, and “native” Java Metal L&Fs. Mac OS X comes with full support for its own L&F based on Apple’s Aqua Human Interface Guidelines, although you can still access Metal if you prefer. In addition, Swing allows the user to switch L&Fs at runtime without having to close the application. This way, a user can experiment to see which L&F is best for her with instantaneous feedback. (In practice, nobody really does this, but it’s still pretty cool from a geeky point of view.) And, if you’re feeling really ambitious as a developer (perhaps a game developer), you can create your own L&F for each one of the Swing components!
The Metal L&F combines some of the best graphical elements in today’s L&Fs and even adds a few surprises of its own. Figure 1-3 shows an example of several L&Fs that you can use with Swing, including the Metal L&F. All Swing L&Fs are built from a set of base classes called the Basic L&F. However, though we may refer to the Basic L&F from time to time, you can’t use it on its own. If you’re lucky enough to be developing applications in the Mac OS X environment, you’ll be familiar with the L&F shown in Figure 1-4.
Most Swing components are lightweight. In the purest sense, this means that components are not dependent on native peers to render themselves. Instead, they use simplified graphics primitives to paint themselves on the screen and can even allow portions to be transparent.
The ability to create lightweight components first emerged in
JDK 1.1, although the majority of AWT components did not take
advantage of it. Prior to that, Java programmers had no choice but to
java.awt.Panel if they wished to
create their own components. With both classes, Java allocated an
opaque peer object from the underlying operating system to represent
the component, forcing each component to behave as if it were its own
window, thereby taking on a rectangular, solid shape. Hence, these
components earned the name “heavyweight” because they frequently held
extra baggage at the native level that Java did not use.
Equivalent components on different platforms don’t necessarily act alike. A list component on one platform, for example, may work differently than a list component on another. Trying to coordinate and manage the differences between components was a formidable task.
The L&F of each component was tied to the host operating system and could not be changed.
With lightweight components, each component renders itself using
the drawing primitives of the
Graphics object (e.g.,
fillRect( ), etc.). Lightweight components
always render themselves onto the surface of the heavyweight top-level
component they are contained in. With the arrival of JDK 1.1,
programmers can directly extend the
java.awt.Container classes when creating
lightweight components. Unlike
java.awt.Panel, these classes do not depend
on a native peer and allow the developer to render quickly to the
graphics context of the container. This results in faster, less
memory-intensive components than were previously available in
Almost all of the Swing components are lightweight; only a few top-level containers are not. This design allows programmers to draw (and redraw) the L&F of their application at runtime, instead of tying it to the L&F of the host operating system. In addition, the design of the Swing components supports easy modification of component behavior. For example, you can tell almost any Swing component whether you wish it to accept or decline focus and how it should handle keyboard input.
Several other features distinguish Swing from the older AWT components:
Swing has wide variety of new components, such as tables, trees, sliders, spinners, progress bars, internal frames, and text components.
Swing components support the replacement of their insets with an arbitrary number of nested borders.
Swing components can have tooltips placed over them. A tooltip is a textual pop up that momentarily appears when the mouse cursor rests inside the component’s painting region. Tooltips can be used to give more information about the component in question.
You can arbitrarily bind keyboard events to components, defining how they react to various keystrokes under given conditions.
There is additional debugging support for rendering your own lightweight Swing components.
We discuss each of these features in greater detail as we move through the next three chapters.
Not everyone uses Swing for the same reasons. In fact, the Swing libraries have many levels of use, with varying levels of prerequisite knowledge. Here are some potential uses:
Use the Swing components as they are to build your own enterprise applications.
Create your own Swing components—or extend those that already exist.
Override or create a new L&F for one or more of the Swing components.
The first approach is what the vast majority of Swing programmers use. Here, using Swing components is just like using the AWT components. A familiar set of components, containers, and layout managers are all available in the Swing packages to help you get your application up and running quickly. If you’re adept at AWT programming, you probably need only a cursory introduction to each component to get started. You will we need to get into broader issues only if you use some of the larger and newer component families, such as tables and text. If you are planning to use each component as a JavaBean for visual programming, you also fall into this category.
Creating your own component, or extending an existing one, requires a deeper understanding of Swing. This includes a firm understanding of Swing architecture, events, and lower-level classes. Also, if you decide to subclass a Swing component, the responsibilities of that component must be adopted and handled accordingly—otherwise, your new component may perform erratically.
Finally, you may wish to change the L&F of one or more Swing
components. This is arguably the most complex of the three routes that
you can take—it requires a thorough knowledge of the design,
architectural fundamentals, and graphical primitives of each
lightweight component. In addition, you need to understand how Swing’s
UIDefaults classes work together to “set”
each component’s L&F.
This book strives to help you with each of these issues. Because we anticipate that the vast majority of readers are in the first category, we spend a great deal of time reviewing each component’s properties and methods, as well as providing source code for various scenarios that use these components. We try to document and illustrate the useful parts of the components. The online documentation (called Javadoc) has matured along with the rest of Java; the current stuff is always there first.
Programming your own L&F can get pretty complex; in fact, the source code for an entire L&F would far exceed the size of this book. However, we don’t want to leave you in the dark. If you are an experienced Swing programmer already, and you’re looking for a concise introduction on how to get started, see Chapter 26. This chapter provides details on working with L&Fs as well as examples of how to code your own L&F for both simple and complex Swing components.