A Swinging Toolkit

   

Chapter 13, "Beginning AWT, " introduced you to the AWT's windowing toolkit. As you learned, this toolkit consists of components , containers, layout managers, events, and listeners. In an effort to overcome the limitations of these entities, Sun's engineers extended the AWT's windowing toolkit into a much more capable product ”the Swing windowing toolkit.

Note

Swing's windowing toolkit is vast. Because of space limitations, this chapter omits many details. To learn more about this toolkit, please consult both the SDK's documentation, and the Java Tutorial at http://java.sun.com/docs/books/tutorial/.


One of the main features that Swing offers is a superb collection of lightweight components. (This is the reason for not presenting an example of a lightweight component in Chapter 14.) Because no peers are involved, Swing's components are completely managed and rendered in Java.

Note

Swing's JApplet, JDialog, JFrame, and JWindow classes represent heavyweight container components. They are heavyweight so that their associated peers can render the appearances of lightweight Swing components and containers in native windows . Furthermore, the peers propagate events from the native windowing system to lightweight components and containers. (Because these are the only heavyweight Swing containers, and all other components are lightweight, Swing uses fewer system resources than the AWT.)


Model-View-Controller Architecture

Swing's components and containers weren't designed to work in the same manner as AWT components and containers. Instead, they were designed to be much more flexible. This flexibility results from supporting the Model-View-Controller (MVC) architecture.

MVC (developed by Xerox PARC in the late 1970s for use with its Smalltalk windowing system) factors a component into a model, one or more views, and a controller.

The model maintains a component's state. For a button component, a model would probably contain button press information. For a text field component, the model might contain the text field's characters . When some models are changed, they notify their associated views. With other models, corresponding controllers notify these views on each model's behalf .

The view provides a visual representation of a component's model. Views give components their "look." For example, a button view could receive button press information, either from the button's model or from its controller. In turn , the view would render an appropriate appearance for the button.

The controller determines if a component should respond to input events that originate from input devices (such as keyboards and mice). Controllers give components their "feel." For example, a mouse button press (while the mouse pointer is positioned over a button) would cause the controller to notify the model and/or all views for the underlying button component.

Figure 16.1 illustrates a generic component by way of its model, view, and controller.

Figure 16.1. MVC architecture factors a component into a model, one or more views, and a controller.

graphics/16fig01.gif

Each Swing component has a default model. However, this model can be changed by calling the component's setModel method. For example, the JButton class creates Swing button components. If you investigate its setModel method (which is located in its AbstractButton superclass), you'll discover that setModel requires a ButtonModel argument ”an object created from a class that implements the ButtonModel interface. The various methods in this interface manage the button's model. (Furthermore, this interface is also used to create models for check boxes and radio buttons ”which are special kinds of buttons .)

Because it is easier to manage an integrated controller and view, many modern windowing toolkits (including Swing) tend to collapse the controller and view into a single entity ”known as a UI (User Interface) delegate. UI delegates and models are completely separate: They communicate by way of events. As a result, a UI delegate can be associated with more than one model, and a model can be associated with more than one UI delegate. A generic component is illustrated in Figure 16.2, by way of its model and UI delegate.

Figure 16.2. The Swing windowing toolkit collapses a view and controller into a UI delegate.

graphics/16fig02.gif

Each Swing component has a separate UI delegate and each delegate is derived from the abstract ComponentUI class (located in the javax.swing.plaf ) package. ComponentUI 's methods provide a basic communication link between a UI delegate and its component.

Each Swing component has a setUI method that can be called to set the UI delegate for that component. Furthermore, some components have a getUI method that returns this delegate. You will rarely (if ever) need to call these methods, because they are designed to be used by Swing's pluggable look and feel capability.

Pluggable Look and Feel

A set of UI delegates (one per component) is known as a look and feel. Swing provides a mechanism for choosing between a variety of look and feels. By using this mechanism, a look and feel can be plugged into a GUI at any time. For this reason, a look and feel is also known as a pluggable look and feel or PLAF.

The classes making up a PLAF are stored in a unique package. One of these classes is the PLAF's main class, and extends the abstract LookAndFeel class (located in the javax.swing package). The following PLAFs are available:

  • The Basic PLAF is an abstract PLAF that serves as a foundation for other PLAFs. Its main class is BasicLookAndFeel (located in the javax.swing.plaf.basic package).

  • The Java PLAF (also known as the Metal PLAF) is a cross platform PLAF that serves as the default PLAF. MetalLookAndFeel (located in the javax.swing.plaf.metal package) is the main class.

  • The Motif PLAF provides the look and feel of Unix's Motif. Its main class is MotifLookAndFeel (located in the com.sun.java.swing.plaf.motif package).

  • The Windows PLAF provides the look and feel of Windows. Its main class is WindowsLookAndFeel (located in the com.sun.java.swing.plaf.windows package). For trademark reasons, this PLAF is only available on Windows machines.

  • The Macintosh PLAF provides the look and feel of the MacOS. Its main class is MacLookAndFeel (located in the com.sun.java.swing.plaf.mac package). For trademark reasons, this PLAF is only available on Macintosh machines.

  • The multiplexing PLAF provides multiple look and feels that can be simultaneously associated with a GUI. Its main class is MultiLookAndFeel (located in the javax.swing.plaf.multi package). Each multiplexing UI delegate is designed to manage its child UI delegates. (This PLAF is primarily intended for use with accessibility PLAFs.)

The UIManager class (located in the javax.swing package) provides the means to choose any of these PLAFs. To establish the new PLAF, pass the fully qualified name of the PLAF's main class to UIManager 's setLookAndFeel method. The following code fragment shows how to accomplish this task:

 public static void main (String [] args) {    try    {        UIManager.setLookAndFeel ("com.sun.java.swing.plaf.motif.MotifLookAndFeel");    }    catch (Exception e) {  }    new SwingApplication (); // Create and show the GUI. } 

The code fragment establishes Motif as the current PLAF. If the MotifLookAndFeel class cannot be found, setLookAndFeel throws a ClassNotFoundException object. An InstantiationException object is thrown if an instance of this class cannot be created. If the class is not public (or is located in some other package), an IllegalAccessException object is thrown. Finally, setLookAndFeel calls UIManager 's isSupportedLookAndFeel method to find out if this look and feel is supported on the current platform. If this method returns a Boolean false value, setLookAndFeel throws an UnsupportedLookAndFeelException object. (A PLAF is not supported for trademark reasons.) Figure 16.3 shows an application's GUI, rendered using the Motif PLAF.

Figure 16.3. An application's GUI, rendered by the Motif PLAF, has a rather dark appearance.

graphics/16fig03.gif

UIManager provides a getCrossPlatformLookAndFeelClassName method, as a convenience in identifying the Java PLAF. (This method might not be much of a convenience, considering the length of its name. However, getCrossPlatformLookAndFeelClassName is recommended for applications to use because it allows applications to be extensible if the default look and feel package changes in the future.) The following code fragment shows how you would call this method to retrieve the name of the Java PLAF's main class, and then pass this name to the setLookAndFeel method to establish the Java PLAF as the current PLAF.

 public static void main (String [] args) {    try    {        String name = UIManager.getCrossPlatformLookAndFeelClassName();        UIManager.setLookAndFeel (name);    }    catch (Exception e) {  }    new SwingApplication (); // Create and show the GUI. } 

Figure 16.4 shows an application's GUI, rendered using the Java PLAF.

Figure 16.4. An application's GUI, rendered by the Java PLAF, has a subtle 3D appearance.

graphics/16fig04.gif

UIManager also provides a getSystemLookAndFeelClassName method as a convenience in identifying the system PLAF. (This is the native windowing system's look and feel.) The following code fragment shows how you would call this method to retrieve the name of the system PLAF's main class, and then pass this name to the setLookAndFeel method to establish the system PLAF as the current PLAF.

 public static void main (String [] args) {    try    {        String name = UIManager.getSystemLookAndFeelClassName();        UIManager.setLookAndFeel (name);    }    catch (Exception e) {  }    new SwingApplication (); // Create and show the GUI. } 

Figure 16.5 shows an application's GUI, rendered using the system PLAF (which just happens to be Windows on the author's computer).

Figure 16.5. As with Motif, an application's GUI, rendered by the Windows PLAF, has a strong 3D appearance. However, unlike Motif, toolbar buttons are placed side by side, with no in-between spacing.

graphics/16fig05.gif

When a Swing program begins running, it might or might not attempt to change its PLAF. If it doesn't (or its attempt is unsuccessful ), the Java runtime environment's lib directory is examined for a file called swing.properties. If this file exists, it is examined for a swing.defaultlaf entry. If this entry exists, its value is used to create the default PLAF. However, if this entry is invalid (or doesn't exist), the Java PLAF is chosen as the default startup PLAF.

Suppose you want to change a GUI's PLAF, after the GUI is visible. You can make this change by invoking the updateComponentTreeUI method (in the SwingUtilities class located in the javax.swing package). You pass a container as the sole argument, and this method informs all the container's children that the PLAF has changed and that they must replace their UI delegates with the new PLAF's delegates. The following code fragment provides a demonstration:

 String lnfName = " com.sun.java.swing.plaf.motif.MotifLookAndFeel"; try {     UIManager.setLookAndFeel (lnfName); } catch (Exception e) { } SwingUtilities.updateComponentTreeUI (frame); // Assume frame exists. frame.pack (); 

Tip

You should resize the container after calling updateComponentTreeUI (by calling pack ), because new UI delegates could reflect views that provide different sizes.


So how is a component made aware that its PLAF has changed? The answer lies in the updateUI method that every component inherits from the JComponent class. This method is automatically called for each component when a PLAF change occurs. In response, updateUI calls UIManager 's getUI method to return the new delegate, and either the inherited or overridden setUI method to establish this new delegate as the current delegate.

Troubleshooting Tip

As you've seen, Java includes a small handful of PLAFs. Although they are adequate for many situations, suppose that none of these PLAFs meet your needs, and you find yourself in a position where you must create a new PLAF. What do you do? The answer is to check out "Creating an Alternate PLAF" in the "Troubleshooting" section at the end of this chapter.


   


Special Edition Using Java 2 Standard Edition
Special Edition Using Java 2, Standard Edition (Special Edition Using...)
ISBN: 0789724685
EAN: 2147483647
Year: 1999
Pages: 353

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net