PLAF Detection Workaround for Ocean Metal and Windows XP

Currently, Swing has a couple of bugs which hinder PLAF detection on the client. In particular, Windows and Metal suffer from ambiguity in their UIManagers. In GlazedLists it's important that we inspect the PLAF precisely so that the pixel-perfect sort arrow icons that Jesse made are chosen correctly. Jesse wrote a couple of methods that workaround these bugs a while ago. In some recent refactorings, I extracted these into a better home and had a chance to look them over. I think them worthy of mention to help others who may have related problems.


There are now two types of Metal, Ocean and Steel. Unfortunately, the result of calling UIManager.getLookAndFeel().getName() is "Metal" for both. However, Ocean only exists on Java 5 so here's the workaround exploiting the new getCurrentTheme() method added in Java 5:

public static String getMetalTheme() {
    try {
        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) {
        return "Metal/Steel";


There are two types of Windows themes as well called XP and Classic. Just as with Metal, the result of calling UIManager.getLookAndFeel().getName() is "Windows" for both. Here's a workaround derived from code in the XPStyle class:

public static String getWindowsTheme() {
    String classic = "Classic Windows";
    String xp = "Windows XP";

    // theme active property must be "Boolean.TRUE";
    String themeActiveKey = "win.xpstyle.themeActive";
    Boolean themeActive = (Boolean)java.awt.Toolkit.getDefaultToolkit().getDesktopProperty(themeActiveKey);
    if(themeActive == null) return classic;
    if(!themeActive.booleanValue()) return classic;

    // no "swing.noxp" system property
    String noXPProperty = "swing.noxp";
    if(System.getProperty(noXPProperty) != null) return classic;

    // l&f class must not be "WindowsClassicLookAndFeel"
    String classicLnF = "";
    if(UIManager.getLookAndFeel().getClass().getName().equals(classicLnF)) return "Classic Windows";

    // must be XP
    return xp;