Pluggable Look-and-Feel

A program that uses Java's Abstract Window Toolkit GUI components (package java.awt) takes on the look-and-feel of the platform on which the program executes. A Java application running on a Macintosh looks like other applications running on a Macintosh. A Java application running on Microsoft Windows looks like other applications running on Microsoft Windows. A Java application running on a UNIX platform looks like other applications running on that UNIX platform. This is sometimes desirable, because it allows users of the application on each platform to use GUI components with which they are already familiar. However, it also introduces interesting portability issues.

Portability Tip 22.1

GUI components look different on different platforms and may require different amounts of space to display. This could change their layout and alignments.

Portability Tip 22.2

GUI components on different platforms have different default functionality (e.g., some platforms allow a button with the focus to be "pressed" with the space bar, and some do not).

Swing's lightweight GUI components eliminate many of these issues by providing uniform functionality across platforms and by defining a uniform cross-platform look-and-feel (known as the metal look-and-feel). Swing also provides the flexibility to customize the look-and-feel to appear as a Microsoft Windows-style look-and-feel (on Window systems), a Motif-style (UNIX) look-and-feel (across all platforms) or a Macintosh look-and-feel (Mac systems).

The application in Fig. 22.9 and Fig. 22.10 demonstrates how to change the look-and-feel of a Swing GUI. The application creates several GUI components, so you can see the change in the look-and-feel of several GUI components at the same time. The first output window shows the standard metal look-and-feel, the second shows the Motif look-and-feel, and the third shows the Windows look-and-feel.

Figure 22.9. Look-and-feel of a Swing-based GUI.

(This item is displayed on pages 1023 - 1025 in the print version)

 1 // Fig. 22.9:
 2 // Changing the look and feel.
 3 import java.awt.GridLayout;
 4 import java.awt.BorderLayout;
 5 import java.awt.event.ItemListener;
 6 import java.awt.event.ItemEvent;
 7 import javax.swing.JFrame;
 8 import javax.swing.UIManager;
 9 import javax.swing.JRadioButton;
10 import javax.swing.ButtonGroup;
11 import javax.swing.JButton;
12 import javax.swing.JLabel;
13 import javax.swing.JComboBox;
14 import javax.swing.JPanel;
15 import javax.swing.SwingConstants;
16 import javax.swing.SwingUtilities;
18 public class LookAndFeelFrame extends JFrame
19 {
20 // string names of look and feels
21 private final String strings[] = { "Metal", "Motif", "Windows" };
22 private UIManager.LookAndFeelInfo looks[]; // look and feels
23 private JRadioButton radio[]; // radiobuttons to select look and feel
24 private ButtonGroup group; // group for radiobuttons
25 private JButton button; // displays look of button
26 private JLabel label; // displays look of label
27 private JComboBox comboBox; // displays look of combo box
29 // set up GUI
30 public LookAndFeelFrame()
31 {
32 super( "Look and Feel Demo" );
34 JPanel northPanel = new JPanel(); // create north panel
35 northPanel.setLayout( new GridLayout( 3, 1, 0, 5 ) );
37 label = new JLabel( "This is a Metal look-and-feel",
38 SwingConstants.CENTER ); // create label
39 northPanel.add( label ); // add label to panel
41 button = new JButton( "JButton" ); // create button
42 northPanel.add( button ); // add button to panel
44 comboBox = new JComboBox( strings ); // create combobox
45 northPanel.add( comboBox ); // add combobox to panel
47 // create array for radio buttons
48 radio = new JRadioButton[ strings.length ];
50 JPanel southPanel = new JPanel(); // create south panel
51 southPanel.setLayout( new GridLayout( 1, radio.length ) );
53 group = new ButtonGroup(); // button group for look and feels
54 ItemHandler handler = new ItemHandler(); // look and feel handler
56 for ( int count = 0; count < radio.length; count++ )
57 {
58 radio[ count ] = new JRadioButton( strings[ count ] );
59 radio[ count ].addItemListener( handler ); // add handler
60 group.add( radio[ count ] ); // add radiobutton to group
61 southPanel.add( radio[ count ] ); // add radiobutton to panel
62 } // end for
64 add( northPanel, BorderLayout.NORTH ); // add north panel
65 add( southPanel, BorderLayout.SOUTH ); // add south panel
67 // get installed look-and-feel information
68 looks = UIManager.getInstalledLookAndFeels();
69 radio[ 0 ].setSelected( true ); // set default selection
70 } // end LookAndFeelFrame constructor
72 // use UIManager to change look-and-feel of GUI
73 private void changeTheLookAndFeel( int value )
74 {
75 try // change look and feel
76 {
77 // set look and feel for this application 
78 UIManager.setLookAndFeel( looks[ value ].getClassName() );
80 // update components in this application 
81 SwingUtilities.updateComponentTreeUI( this );
82 } // end try
83 catch ( Exception exception )
84 {
85 exception.printStackTrace();
86 } // end catch
87 } // end method changeTheLookAndFeel
89 // private inner class to handle radio button events
90 private class ItemHandler implements ItemListener
91 {
92 // process user's look-and-feel selection
93 public void itemStateChanged( ItemEvent event )
94 {
95 for ( int count = 0; count < radio.length; count++ )
96 {
97 if ( radio[ count ].isSelected() )
98 {
99 label.setText( String.format( "This is a %s look-and-feel",
100 strings[ count ] ) );
101 comboBox.setSelectedIndex( count ); // set combobox index
102 changeTheLookAndFeel( count ); // change look and feel
103 } // end if
104 } // end for
105 } // end method itemStateChanged
106 } // end private inner class ItemHandler
107 } // end class LookAndFeelFrame

Figure 22.10. Test class for LookAndFeelFrame.

(This item is displayed on page 1026 in the print version)

 1 // Fig. 22.10:
 2 // Changing the look and feel.
 3 import javax.swing.JFrame;
 5 public class LookAndFeelDemo
 6 {
 7 public static void main( String args[] )
 8 {
 9 LookAndFeelFrame lookAndFeelFrame = new LookAndFeelFrame();
10 lookAndFeelFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
11 lookAndFeelFrame.setSize( 300, 200 ); // set frame size
12 lookAndFeelFrame.setVisible( true ); // display frame
13 } // end main
14 } // end class LookAndFeelDemo

All the GUI components and event handling in this example have been covered before, so we concentrate on the mechanism for changing the look-and-feel in this example. Class UIManager (package javax.swing) contains nested class LookAndFeelInfo (a public static class) that maintains information about a look-and-feel. Line 22 declares an array of type UIManager.LookAndFeelInfo (note the syntax used to identify the inner class LookAndFeelInfo). Line 68 uses UIManager static method getInstalledLookAnd-Feels to get the array of UIManager.LookAndFeelInfo objects that describe each look-and-feel available on your system.

Performance Tip 22.1

Each look-and-feel is represented by a Java class. UIManager method getInstalledLookAnd-Feels does not load each class. Rather, it provides the names of the available look-and-feel classes so that a choice can be made (presumably once at program start-up). This reduces the overhead of having to load all the look-and-feel classes even if the program will not use some of them.

Our utility method changeTheLookAndFeel (lines 7387) is called by the event handler for the JRadioButtons at the bottom of the user interface. The event handler (declared in private inner class ItemHandler at lines 90106) passes an integer representing the element in array looks that should be used to change the look-and-feel. Line 78 invokes static method setLookAndFeel of UIManager to change the look-and-feel. Method getClassName of class UIManager.LookAndFeelInfo determines the name of the look-and-feel class that corresponds to the UIManager.LookAndFeelInfo object. If the look-and-feel class is not already loaded, it will be loaded as part of the call to setLookAndFeel. Line 81 invokes static method updateComponentTreeUI of class SwingUtilities (package javax.swing) to change the look-and-feel of every GUI component attached to its argument (this instance of our application class LookAndFeelDemo) to the new look-and-feel.

Introduction to Computers, the Internet and the World Wide Web

Introduction to Java Applications

Introduction to Classes and Objects

Control Statements: Part I

Control Statements: Part 2

Methods: A Deeper Look


Classes and Objects: A Deeper Look

Object-Oriented Programming: Inheritance

Object-Oriented Programming: Polymorphism

GUI Components: Part 1

Graphics and Java 2D™

Exception Handling

Files and Streams


Searching and Sorting

Data Structures



Introduction to Java Applets

Multimedia: Applets and Applications

GUI Components: Part 2



Accessing Databases with JDBC


JavaServer Pages (JSP)

Formatted Output

Strings, Characters and Regular Expressions

Appendix A. Operator Precedence Chart

Appendix B. ASCII Character Set

Appendix C. Keywords and Reserved Words

Appendix D. Primitive Types

Appendix E. (On CD) Number Systems

Appendix F. (On CD) Unicode®

Appendix G. Using the Java API Documentation

Appendix H. (On CD) Creating Documentation with javadoc

Appendix I. (On CD) Bit Manipulation

Appendix J. (On CD) ATM Case Study Code

Appendix K. (On CD) Labeled break and continue Statements

Appendix L. (On CD) UML 2: Additional Diagram Types

Appendix M. (On CD) Design Patterns

Appendix N. Using the Debugger

Inside Back Cover

Java(c) How to Program
Java How to Program (6th Edition) (How to Program (Deitel))
ISBN: 0131483986
EAN: 2147483647
Year: 2003
Pages: 615 © 2008-2020.
If you may any questions please contact us: