Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4329280

UIManager default table is not correct updated during a LAF change

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.0
    • 1.3.0
    • client-libs
    • None
    • beta
    • x86
    • windows_nt

      When a UI undergoes an LAF change, the ActionMap table isn't correctly updated with the map of the new LAF UI.

      This example can be illustrated in the ComboBoxUI change from Windows to Motif. WindowsComboBoxUI.installKeyBoardActions overrides a couple of action mappings of BasicComboBoxUI. In the example below, start it with the Windows LAF with the command:

      > java PLAFTest windows

      and use the up and down arrow keys to scroll throught the combo box items.

      Change the LAF to Motif with the menu and use the arrow keys to scroll through the list. You should get a class cast exceotion from WindowsComboBoxUI$DownAction.actionPerformed since the same actions which were bound to the Windows LAF are still bound to Motif.

      Some places to look:
      - BasicComboBoxUI.createActionMap() should be always be called on a LAF change.
      - BasicComboBoxUI.uninstallKeyboardActions(): the call to SwingUtilities.replaceUIActionMap() should set set or reset the action map.

      You should test between the Windows and Motif LAFS (for combo box) since the default up and down actions in BasicCombBoxUI will work with all three LAFS. by installing Windows actions and having Motif LAF reference them will illustrate the bug.

      -------- PLAFTest.java ------------
      import java.awt.*;
      import java.awt.event.*;

      import javax.swing.*;
      import javax.swing.event.*;

      /**
       * Changes the look and feel on a JComboBox.
       *
       * @version 1.1 04/10/00
       * @author Mark Davidson
       */
      public class PLAFTest extends JFrame {
          
          // Actions defined for the application
          private WindowsLAF winAction;
          private MotifLAF motifAction;
          private MetalLAF metalAction;
          
          private static String[] strData = {
              "One", "Two", "Three", "Four", "Five", "Six", "Seven"
          };


          /**
           * ctor
           *
           * @param laf Sets the look and feel.
           */
          public PLAFTest(String laf) {
              if (laf != null) {
                  try {
                      UIManager.setLookAndFeel(laf);
                  } catch (Exception ex) {
                      // Fail silently to cross platform laf.
                  }
              }

              initActions();

              setJMenuBar(createMenu());
              getContentPane().add(createPanel(), BorderLayout.CENTER);

              addWindowListener(new WindowAdapter() {
                  public void windowClosing(WindowEvent evt) {
                      System.exit(0);
                  }
              });
          }

          /** Add more components to test here. */
          private JPanel createPanel() {
              JPanel panel = new JPanel();
              panel.add(new JComboBox(strData));
              panel.setPreferredSize(new Dimension(300, 200));

              return panel;
          }


          private void initActions() {
              winAction = new WindowsLAF();
              motifAction = new MotifLAF();
              metalAction = new MetalLAF();
          }

          // Creates the application menu bar.
          private JMenuBar createMenu() {
              JMenuBar menuBar = new JMenuBar();

              JMenuItem menuItem;

              // Build the Look and Feel menu
              JMenu lafMenu = new JMenu("Look and Feel");
              lafMenu.setMnemonic('L');
              menuItem = lafMenu.add(winAction);
              menuItem = lafMenu.add(motifAction);
              menuItem = lafMenu.add(metalAction);

              menuBar.add(lafMenu);
              
              return menuBar;
          }

          public static void main(String[] args) {
              String laf = null;
              
              if (args != null && args.length > 0) {
                  String arg = args[0];
              
                  if (arg != null) {
                      if (arg.equals("windows")) {
                          laf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
                      } else if (arg.equals("motif")) {
                          laf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
                      }
                  }
              }
          
              PLAFTest test = new PLAFTest(laf);
              test.pack();
              test.setVisible(true);
          }

          //
          // Look and Feel Actions.
          //
          
          private class LAFAction extends AbstractAction {
              private String laf;
              
              public LAFAction(String name, String laf) {
                  super(name);
                  this.laf = laf;
              }
              
              public void actionPerformed(ActionEvent evt) {
                  try {
                      UIManager.setLookAndFeel(laf);
                      SwingUtilities.updateComponentTreeUI(PLAFTest.this);
                  } catch (Exception ex) {
                      System.out.println("Unsuported Look and Feel");
                  }
              }
          }
          
          private class WindowsLAF extends LAFAction {
              public WindowsLAF() {
                  super("Windows", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
              }
          }

          private class MotifLAF extends LAFAction {
              public MotifLAF() {
                  super("Motif", "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
              }
          }

          private class MetalLAF extends LAFAction {
              public MetalLAF() {
                  super("Metal", "javax.swing.plaf.metal.MetalLookAndFeel");
              }
          }
      }

      ----- end PLAFTest.java ---------------

            svioletsunw Scott Violet (Inactive)
            mdavidsosunw Mark Davidson (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: