can't detect that windows classic theme active
Asked Answered
L

3

9

I am calling UIManager.getSystemLookAndFeelClassName(). And get as result WindowsLookAndFeel, even when setting current theme to WindowsClassicLookAndFeel. But I expect WindowsClassicLookAndFeel. Question is how can I detect that windows classic theme is now active

Linkous answered 7/9, 2010 at 13:30 Comment(2)
I don't know the answer, but the people providing answers don't seem to even read the question. Windows XP, Vista and 7 have their standard theme, but can also be made to look like Windows 2000 (the classic theme). The question is how to detect which of those the user has set Windows to.Watereddown
@Ricky Clarkson: from the question I understand that he says he sets the "theme" to WindowsClassicLookAndFeel which is a LaF in java and wants to see if it is currently installed.Nationalism
B
14

It looks like you signed up specifically to ask this question, and now I'm signing up specifically to answer it! I was Googling for something completely different but I was intrigued and did some experimenting, and here's what I found:

You're right about the WindowsClassicLookAndFeel. This class extends WindowsLookAndFeel but doesn't override anything, and doesn't appear to be used at all, even when Windows Classic is active. So, I looked into the code of WindowsLookAndFeel and found some interesting internal code that references the package-private class XPStyle. This class appears to be a singleton and the getter method, getXP(), only returns its instance if the 'XP' theme is active:

/** 
 * Get the singleton instance of this class
 *
 * @return the singleton instance of this class or null if XP styles
 * are not active or if this is not Windows XP
 */
static synchronized XPStyle getXP() {
    if (themeActive == null) {
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        themeActive =
            (Boolean)toolkit.getDesktopProperty("win.xpstyle.themeActive");
        if (themeActive == null) {
            themeActive = Boolean.FALSE;
        }
        if (themeActive.booleanValue()) {
            GetPropertyAction propertyAction =
                new GetPropertyAction("swing.noxp");
            if (AccessController.doPrivileged(propertyAction) == null &&
                ThemeReader.isThemed() &&
                !(UIManager.getLookAndFeel()
                  instanceof WindowsClassicLookAndFeel)) {

                xp = new XPStyle();
            }
        }
    }
    return xp;
}

Interestingly, the code checks for the WindowsClassicLookAndFeel again but we know that this is no longer used (perhaps it's changed)... But the best part is the check for the desktop property win.xpstyle.themeActive Extracting this from the code, I made the following test:

package test;

import java.awt.Toolkit;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.UIManager;

public class WindowsClassicThemeDetector {

    public static boolean isWindowsLAF() {
        return UIManager.getLookAndFeel().getID().equals("Windows");
    }

    public static boolean isWindowsClassicLAF() {
        return isWindowsLAF()
                && !(Boolean) Toolkit.getDefaultToolkit().getDesktopProperty(
                        "win.xpstyle.themeActive");
    }

    public static void main(String... args) throws Exception {
        // Apply the system look and feel (which will be Windows)
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

        // Check the initial theme state on startup
        System.out.println(UIManager.getLookAndFeel().getClass());
        System.out.println("Windows classic is initially: " + isWindowsClassicLAF());

        // Register a listener in case the theme changes during runtime.
        Toolkit.getDefaultToolkit().addPropertyChangeListener("win.xpstyle.themeActive",
                new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        System.out.println("Windows classic is now: " + isWindowsClassicLAF());
                    }
                });

        // Wait until user presses ENTER in the console and then exit.
        System.in.read();
    }
}

You can import this class into your program and call the isWindowsClassicLAF() method after setting your Look&Feel at any point. I've also given an example of how you can listen out for changes to the theme at run-time.

This is tried and tested on XP. If the user changes from one XP theme to another, the listener doesn't fire, but if the user changes from a theme to Classic, or vice-versa, it will.

I hope that helps!

Bovine answered 8/12, 2010 at 11:16 Comment(0)
M
2

I'm not quite sure what you are asking.

If you are asking which theme/look and feel SWING is currently using, try UIManager.getSystemLookAndFeelClassName().

If you are trying to find out which theme Windows is using - I don't know. Probably not quite easy to find that out.

Edit: A quick hack might be (apart from using JNA/JNA to query some Windows API directly which theme is being used) would be creating a new JFrame, place it in some area, capture a small part of that border and compare it with samples of borders (which you need to create beforehand and ship with your code, as to be able to programmatically compare the just-taken-screen-capture-bit and all border-images you ship)

Misstep answered 7/9, 2010 at 13:37 Comment(3)
yes, something like this, but there is com.sun.java.swing.plaf.windows.WindowsLookAndFeel and com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel, but UIManager.getSystemLookAndFeelClassName() returns only com.sun.java.swing.plaf.windows.WindowsLookAndFeel even when classic windows theme applied.Linkous
You give a link to a javadoc without even reading what the method is doing.Nationalism
@tulskiy fland recently rephrased his question, so I could only guess what he was asking for. Hence my answer doesn't make much sense anymore.Misstep
N
-1

UIManager.getLookAndFeel() returns currently installed LaF. getSystemLookAndFeel() returns look and feel that would look as a current system's theme, e.g. WindowsLookAndFeel on windows GTKLookAndFeel on Linux MOtifLookAndFeel on Solaris etc.

Nationalism answered 7/9, 2010 at 15:18 Comment(1)
It doesn't answers, how OP can detect if classic theme is installed.Chitterlings

© 2022 - 2024 — McMap. All rights reserved.