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

Cannot programatically distinguish between Steel and Ocean with 1.4 methods

    XMLWordPrintable

Details

    Description



      Name: jl125535 Date: 09/27/2004


      FULL PRODUCT VERSION :
      java version "1.5.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
      Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode)


      A DESCRIPTION OF THE PROBLEM :
      What I would like to be able to do is programatically figure out what the look and feel is. I would like to be able to programmatically tell the difference between Metal/Steel and Metal/Ocean.

      I can do this using Java 1.5 and the method
          MetalLookAndFeel.getCurrentTheme().getName()
      But in Java 1.4 I cannot do this because there is no method
          MetalLookAndFeel.getCurrentTheme().

      Because my program must continue to compile and run under Java 1.4, I cannot use that method. The preferable way to detect the current theme is using the method LookAndFeel.getName(), which is supposed to return a different value for different variants of the same look and feel. Unfortunately the MetalLookAndFeel returns "Metal" for both Steel and Ocean.

      API for javax.swing.LookAndFeel.getName()
      Return a short string that identifies this look and feel, e.g. "CDE/Motif". This string should be appropriate for a menu item. Distinct look and feels should have different names, e.g. a subclass of MotifLookAndFeel that changes the way a few components are rendered should be called "CDE/Motif My Way"; something that would be useful to a user trying to select a L&F from a list of names.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The output of the program when run under Java 1.4 will be "Metal".
          $ java -Dswing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel LNFWriter
             Metal

      I would expect that since Java 1.5 changed the look and feel, it should
      also change what it reports by this test program to be "Metal/Ocean":
          $ java -Dswing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel LNFWriter
             Metal/Ocean

      Therefore a program can detect whether the current theme is Steel ("Metal")
      or Ocean ("Metal/Ocean").

      ACTUAL -
      The output of the program when run under Java 1.5 will be "Metal", but
      the look and feel is NOT the same look and feel as in Java 1.4.
          $ java -Dswing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel LNFWriter
             Metal


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.swing.UIManager;

      public class LNFWriter {
          public static void main(String[] args) {
               System.out.println(UIManager.getLookAndFeel().getName());
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      I have developed a workaround that uses reflection to determine the look and feel.
      This method has many drawbacks - it requires that a NoSuchMethodException be
      thrown every time it is run on Java 1.4, and it does not support themes other than
      "Steel" on Java 1.4:

          /**
           * Workaround method to get the metal theme, either "Steel" or "Ocean". This is because the
           * Metal look and feel's getName() property does not distinguish between versions correctly.
           * A bug has been submitted to the Sun Java bug database and will be reviewed. If fixed, we
           * can get rid of this ugly hack method.
           */
          private static String getMetalTheme() {
              try {
                  if(!UIManager.getLookAndFeel().getName().equals("Metal")) return UIManager.getLookAndFeel().getName();
                  MetalLookAndFeel metalLNF = (MetalLookAndFeel)UIManager.getLookAndFeel();
                  Method getCurrentTheme = metalLNF.getClass().getMethod("getCurrentTheme", new Class[0]);
                  MetalTheme currentTheme = (MetalTheme)getCurrentTheme.invoke(metalLNF, new Object[0]);
                  return "Metal/" + currentTheme.getName();
              } catch(NoSuchMethodException e) {
                  // must be Java 1.4 because getCurrentTheme() method does not exist
                  // therefore the theme of interest is "Steel"
                  return "Metal/Steel";
              } catch(Exception e) {
                  e.printStackTrace();
                  return "Metal/Steel";
              }
          }
      (Incident Review ID: 311764)
      ======================================================================

      Attachments

        Activity

          People

            svioletsunw Scott Violet (Inactive)
            jleesunw Jon Lee (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: