[an error occurred while processing this directive]

Page One
Page Two
The Databank
What Is Swing?
Special Report
IDE Roundup
Swing and the Web
Swing Text
Tech Topics
Friends
Tips and Tricks
The PLAF Papers
Call 911
The Archive
JFC Home
Download Swing
Swing API Docs
Download JDK
JDK Docs
Java Tutorial
 
The Swing Connection What Is Swing?


What Is Swing? - 2

Introducing Swing Architecture

NOTE: This article has three parts. Part 1, "Getting Started with Swing," introduces the basic fundamentals of Swing and Swing technology. Part 2, "Introducing Swing Architecture" (which you are reading now), tells how Swing Components are designed. Part 3, "Creating a Swing Applet," presents a tutorial that you can follow to build your own applet using Swing.

By Mark Andrews

Boy swingingDuring the early stages of Swing´s development, there were widespread reports that the Swing component set were being designed using something called MVC (model-view-controller) architecture. As it turns out, those reports were partly true, but not completely accurate.

MVC architecture is a well-known design for GUI objects that dates back to the SmallTalk language. Classic MVC architecture divides each component into three parts: a model, a view, and a controller, as shown in the following diagram. In classic MVC architecture, the model manages whatever data or values the component uses -- such as the minimum, maximum, and current values used by a scroll bar. The view manages the way the component is displayed. And the controller determines what happens when the user interacts with the component-- for example, what occurs when the user clicks a button control.

MVC diagram 

Swing´s modified MVC design

Classic MVC architecture is simple and elegant, and the Swing team started designing the Swing component set, they experimented with using a pure MVC design. But they soon discovered that classic MVC architecture didn´t work very well in real-world Swing application. So they wound up basing Swing architecture on a modified adaptation of the traditional MVC design. To implement Swing components, the Swing team created a modified MVC design. The component design that the Swing team eventually settled on is sometimes referred to a separable model architecture.

In Swing's separable model design, the model part of a component is treated as a separate element, just as the MVC design does. But Swing collapses the view and controller parts of each component into a single UI (user-interface) object. The result is an architecture that looks like this:

Separable model diagram 

Swing´s separable model architecture was developed because the creators of Swing found that the traditional MVC design didn't work well in practical terms in Swing-style components. Why not? Because the view and controller parts of a traditional MVC-based component require a tight coupling that is sometimes difficult to achieve in practical terms. For example, traditional MVC architecture makes it very hard to create a generic controller that doesn't know at design time what kind of view will eventually be used to display it.

To developers of Swing applets and applications, this is a big advantage. With Swing, it's easy to present complex data structures user in an attractive easy-to-understand way.

Under the following subheadings, each element shown in the precooking picture is described in more detail.

The UI Manager

To handle the look-and-feel characteristics of its modified-MVC components, Swing defines a class called the UIManagerapi, which always keeps track of the current look and feel and its defaults. The UI manager, shown on the right in the preceding diagram, controls the look-and-feel capabilities of each Swing component by communicating with the component's UI object, as shown in the diagram.

The UI Delegate

The Delegate (man with briefcase)In the Swing API, the name of each generic component class is preceded by a "J" -- for example, classes in the Swing set are named JButton, JTree, JTable, and so on. Each generic component class handles its own individual own view-and-controller responsibilities. But, as shown in the preceding diagram, each class delegates the look-and-feel-specific aspects of its responsibilities to whatever UI object the currently installed look-and-feel provides. For this reason, the UI object that's built into every Swing component is sometimes referred to as the UI delegate.

The ComponentUI Class

In Swing, all UI delegate classes are derived from a superclass named ComponentUIapi. This class contains most of the important machinery for making Swing's pluggable look-and-feel work. Its methods deal with UI installation and uninstallation, and with delegation of a component's geometry-handling and painting. Delegate UIs are described in more detail later, in the Pluggable Look and Feel section of this article.

The Component Model Interface

In component design circles, it´s generally considered good practice to center the architecture of an application around its data rather than around its user interface. To support this paradigm, Swing defines a separate model interface for each kind of component that can store or manipulate values or data. This separation provides Swing programs with the option of plugging in their own customized model implementations.

Default and Custom Component Models

If an application doesn´t explicitly provide its own model implementation for a particular component, Swing creates and installs a default model implementation which implements that component's model interface. For example, when you create a slide-controller component by instantiating an object of the JSliderapi class, Swing creates and installs a default model interface that an application can use to set a maximum value, a minimum value, and a current value for the control. These values can be set in the control's constructor, as follows:

  this.model =
     new DefaultBoundedRangeModel(value, 0, min, max);

When a Swing component defines a model, it does so by using a JavaBeansTM bound property for the model. For example, the JSlider class uses a bound property interface called the BoundedRangeModelapi to define its model. At any time you like, you can replace the default bound property of a component (such as the JSlider component instantiated in the preceding code fragment) with a model of your own design by calling a method named setModel(). Here's an example:

   JSlider slider = new JSlider();
   BoundedRangeModel myModel = new DefaultBoundedRangeModel()
   {
      public void setValue(int n) {
         System.out.println("SetValue: "+ n);
         super.setValue(n);
      }
   };
   slider.setModel(myModel);

Different Models for Different Components

By default, different kinds of components are equipped with different kinds of models. For example, the default model that Swing supplies for a JButton object is a GUI state model -- that is, an interface that defines the visual status of a GUI control, such the current state of a button. Similarly, the JList class is equipped with a GUI state model that can specify which items are selected in a list.

More complex components, such as JTrees and JTables, are equipped with more sophisticated default models application-data models -- that is, with interfaces that can manage more complex information, such as the value of a cell in a table or the items displayed in a tree. These data models provide a very powerful programming paradigm for Swing programs that need a clean separation between their GUI and their application data and logic.

Horizontal rule 

Swing´s Pluggable Look and Feel

Here´s one definition of PL&F: It´s the portion of a Swing component's implementation that deals with the component's appearance (or look), as distinguished from its event-handling mechanism (its feel), which is delegated to a separate UI delegate. The currently installed L&F module is what supplies this UI delegate.

The user of a Swing application can change UI delegates at runtime, so it's possible for the user of a cleverly designed Swing application to change the appearance and behavior (look and feel) of the application's components while the program is running.

Complexity and the need to know

Although any Swing developer can learn to use PL&F, but mastering it does require a firm grasp of some fairly complex topics. So if you ever need (or want) to develop a custom look-and-feel, you'll undoubtedly have to do some homework before you start writing code. It is a challenge. But, as challenges go, it is a rewarding one.

Another point: Although Swing's PL&F feature is complex, its complexity doesn't have much impact on most Swing developers because most of them will never be called upon to use it. The PL&F mechanism is designed to be used by a small subset of developers who have a particular need to develop new look-and-feel implementations. In most circumstances, other categories of developers will probably find that it's enough to understand the capabilities of the PL&F mechanism so they can make decisions on how they want to support look-and-feels (such as deciding whether they want to lock an application into using a single look-and-feel or whether they want to support look-and-feel reconfigurations by the user). Swing's UIManager class is the API that supports L&F management at this level.

The LookAndFeel Class

The Swing API defines an abstract LookAndFeelapi class that completely characterizes a look and feel from the point of view of the pluggable look and feel components. The LookAndFeel class represents all the information needed to create and implement a look-and-feel implementation, such as its name, its description, a property that specifies whether it's a native L&F -- and, finally, a hash table (commonly called a defaults table in Swing) for storing default values for various look-and-feel attributes, such as colors and fonts.

Every look-and-feel implementation defines an extension of the LookAndFeel class that an application can use to provide Swing with the necessary information to manage its L&Fs. For example, swing.plaf.motif.MotifLookAndFeel is a subclass that can be used to manage a Motif L&F in an application.

The recommended practice is for components and applications to access LookAndFeel objects indirectly, using the UIManager. Applications should rarely, if ever, talk directly to an instance of the LookAndFeel class. By accessing the class through the UI manager, an application can keep track of which LookAndFeel classes are available, which are installed, and which is currently the default. The UI manager also manages access to the defaults table being used by the current look-and-feel.

Default and custom L&Fs

When you load a program that makes use of Swing components, Swing's default behavior is to initialize the Java look and feel that ships with Swing. But any Swing program can set its own default by simply calling a UIManager method named setLookAndFeel(). For example, the following code sample sets the Motif CDE (Common Desk Environment) to be the default L&F:

UIManager.setLookAndFeel
   ("com.sun.java.swing.plaf.motif.MotifLookAndFeel");

The UIManager also provides a getLookAndFeel() method for obtaining the current L&F. In addition, there are UIManager methods for getting the current system look and feel, for setting the current L&F to whatever platform a program is running on, and for managing look-and-feel operations in many other kinds of ways.

You can learn more about Swing´s PL&F capabilities by reading the articles in the PLAF Papers section of The Swing Connection. But we won´t go into any more detail about PL&F in this article. Instead, we´ll move right along to Part 3, where you´ll learn how to create and activate an applet using Swing.

Part 3 Right arrow

[an error occurred while processing this directive]