Recipe 14.15 Changing a Swing Program s Look and Feel


Recipe 14.15 Changing a Swing Program's Look and Feel

Problem

You want to change the look and feel of an application.

Solution

Use the static UIManager.setLookAndFeel( ) method. Maybe.

Discussion

If you wish to specify the entire look and feel for a program, set it with the static UIManager.setLookAndFeel( ) method; the name you pass in must be the full name (as a string) of a class that implements a Java look and feel. The details of writing a look and feel class are beyond the scope of this book; refer to the book Java Swing or the Sun documentation. But using these classes is easy. For example:

UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");

This must appear before you create the GUI of the program, and it can throw an exception if the class name is invalid.

People sometimes like to show off the fact that you can change the look and feel on the fly. You call setLookAndFeel( ) as previously, and then call the static SwingUtilities.updateComponentTree( ) for your JFrame and all detached trees, such as dialog classes. But before you rush out to do it, please be advised that the official Sun position is that you shouldn't! The official Java Look and Feel Design Guideline book says, on page 23 (first edition):

Because there is far more to the design of an application than the look and feel of components, it is unwise to give end users the ability to swap look and feel while [running] your application. Switching look and feel designs in this way only swaps the look and feel designs from one platform to another. The layout and vocabulary used are platform-specific and do not change. For instance, swapping look and feel designs does not change the titles of the menus.

The book does recommend that you let users specify an alternate look and feel, presumably in your properties file, at program startup time. Even so, the capability to switch while an application is running is too tempting to ignore; even Sun's own Swing Demonstration (included with the JDK) offers a menu item to change its look and feel. Figure 14-13 is my nice little program in the Java style; see Example 14-8 for the source code.

Figure 14-13. Java, Windows, and Motif look and feel under Windows
figs/jcb2_1413.gif


Of course, not all looks work on all platforms. If I try the Mac OS look and feel under Windows, I get the error dialog shown in Figure 14-14, which shows what happens when you request any look and feel that is unavailable on the current platform.

Figure 14-14. Look and feel request refused on Windows
figs/jcb2_1414.gif


The OPEN LOOK design alluded to in the code is, well, not written yet. Vaporware. That's why it's grayed out.

Under Mac OS X, the default look and feel is, of course, the Mac OS look and feel. You can also select the Java or Motif look, but not the Windows look. See Figure 14-15.

Figure 14-15. Look and feel switcher under Mac OS X
figs/jcb2_1415.gif


Example 14-8 shows the code that implements the look and feel switcher. It's pretty straightforward based on what we've seen already. The only neat trick is that I've set the selected button back to what it was if the look and feel that the user selects is not available.

Example 14-8. LNFSwitcher.java
/**  * A Look-and-feel switcher.  * @author    Ian Darwin, http://www.darwinsys.com/  * @version    $Id: ch14.xml,v 1.6 2004/05/07 15:20:56 ian Exp $  */ public class LNFSwitcher {     /** The frame. */     protected JFrame theFrame;     /** Its content pane */     protected Container cp;     /** Start with the Java look-and-feel, if possible */     final static String PREFERREDLOOKANDFEELNAME =         "javax.swing.plaf.metal.MetalLookAndFeel";     protected String curLF = PREFERREDLOOKANDFEELNAME;     protected JRadioButton previousButton;     /** Construct a program... */     public LNFSwitcher( ) {         super( );         theFrame = new JFrame("LNF Switcher");         theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         cp = theFrame.getContentPane( );         cp.setLayout(new FlowLayout( ));         ButtonGroup bg = new ButtonGroup( );         JRadioButton bJava = new JRadioButton("Java");         bJava.addActionListener(new LNFSetter(             "javax.swing.plaf.metal.MetalLookAndFeel", bJava));         bg.add(bJava);         cp.add(bJava);         JRadioButton bMSW  = new JRadioButton("MS-Windows");         bMSW.addActionListener(new LNFSetter(             "com.sun.java.swing.plaf.windows.WindowsLookAndFeel", bMSW));         bg.add(bMSW);         cp.add(bMSW);         JRadioButton bMotif = new JRadioButton("Motif");         bMotif.addActionListener(new LNFSetter(             "com.sun.java.swing.plaf.motif.MotifLookAndFeel", bMotif));         bg.add(bMotif);         cp.add(bMotif);         JRadioButton bMac = new JRadioButton("Sun-MacOS");         bMac.addActionListener(new LNFSetter(             "com.sun.java.swing.plaf.mac.MacLookAndFeel", bMac));         bg.add(bMac);         cp.add(bMac);         String defaultLookAndFeel = UIManager.getSystemLookAndFeelClassName( );         // System.out.println(defaultLookAndFeel);         JRadioButton bDefault = new JRadioButton("Default");         bDefault.addActionListener(new LNFSetter(              defaultLookAndFeel, bDefault));         bg.add(bDefault);         cp.add(bDefault);         previousButton = bDefault;         bDefault.setSelected(true);         theFrame.pack( );         theFrame.setVisible(true);     }     /* Class to set the Look and Feel on a frame */     class LNFSetter implements ActionListener {         String theLNFName;         JRadioButton thisButton;         /** Called to setup for button handling */         LNFSetter(String lnfName, JRadioButton me) {             theLNFName = lnfName;             thisButton = me;         }         /** Called when the button actually gets pressed. */         public void actionPerformed(ActionEvent e) {             try {                 UIManager.setLookAndFeel(theLNFName);                 SwingUtilities.updateComponentTreeUI(theFrame);                 theFrame.pack( );             } catch (Exception evt) {                 JOptionPane.showMessageDialog(null,                     "setLookAndFeel didn't work: " + evt,                     "UI Failure", JOptionPane.INFORMATION_MESSAGE);                 previousButton.setSelected(true);        // reset the GUI to agree             }             previousButton = thisButton;         }     }     public static void main(String[] argv) {         new LNFSwitcher( );     } }

See Also

Some alternate look-and-feel implementations can be found on the Web. If you'd like to build your own look and feel, perhaps for corporate identity reasons, some of these, in conjunction with O'Reilly's Java Swing, would be a good starting point.



Java Cookbook
Java Cookbook, Second Edition
ISBN: 0596007019
EAN: 2147483647
Year: 2003
Pages: 409
Authors: Ian F Darwin

Similar book on Amazon

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