无法检测到windows经典主题活跃

时间:2010-09-07 13:30:04

标签: java swing look-and-feel

我正在调用UIManager.getSystemLookAndFeelClassName()。 即使将当前主题设置为WindowsClassicLookAndFeel,也可以获得WindowsLookAndFeel的结果。但我期待WindowsClassicLookAndFeel。 问题是如何检测Windows经典主题现在是否处于活动状态

3 个答案:

答案 0 :(得分:14)

看起来您已经注册了专门提出这个问题的问题,现在我正在注册专门回答它!我在谷歌搜索完全不同的东西,但我很好奇并做了一些实验,这就是我发现的:

WindowsClassicLookAndFeel你是对的。此类扩展WindowsLookAndFeel但不覆盖任何内容,并且即使在Windows Classic处于活动状态时也似乎根本不使用。所以,我查看了WindowsLookAndFeel的代码,发现了一些引用包私有类XPStyle的有趣内部代码。此类似乎是单例,而getter方法getXP()仅在“XP”主题处于活动状态时才返回其实例:

/** 
 * 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;
}

有趣的是,代码再次检查WindowsClassicLookAndFeel,但我们知道不再使用它(可能已更改)......但最好的部分是检查桌面属性win.xpstyle.themeActive提取从代码中我做了以下测试:

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();
    }
}

您可以将此课程导入您的计划,并在任何时候设置您的外观和感觉后调用isWindowsClassicLAF()方法。我还举了一个例子,说明如何在运行时监听主题的更改。

这是在XP上试用和测试的。如果用户从一个XP主题更改为另一个主题,则侦听器不会触发,但如果用户从主题更改为经典,反之亦然,则会触发。

我希望有所帮助!

答案 1 :(得分:2)

我不太确定你在问什么。

如果您在询问SWING当前使用的主题/外观,请尝试 UIManager.getSystemLookAndFeelClassName()

如果您正在尝试找出Windows正在使用的主题 - 我不知道。可能不容易找到它。

编辑:快速破解可能(除了使用JNA / JNA直接查询某些Windows API,正在使用哪个主题)将创建一个新的JFrame,将其放置在某个区域,捕获该边框的一小部分,并将其与边框样本(您需要事先创建并与代码一起提供)进行比较,以便能够以编程方式比较刚刚拍摄的屏幕捕获位和您发送的所有边框图像)

答案 2 :(得分:-1)

UIManager.getLookAndFeel()返回当前安装的LaF。 getSystemLookAndFeel()返回的外观和感觉看起来像当前系统的主题,例如Solaris上的WindowsLookAndFeel和Solaris上的Linux MOtifLookAndFeel等等。