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

fla*_*and 8 java swing look-and-feel

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

Bof*_*ain 14

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

你是对的WindowsClassicLookAndFeel.此类扩展WindowsLookAndFeel但不覆盖任何内容,即使Windows Classic处于活动状态,也似乎根本不使用.所以,我查看了代码WindowsLookAndFeel并找到了一些引用package-private类的有趣内部代码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;
}
Run Code Online (Sandbox Code Playgroud)

有趣的是,代码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();
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以将此类导入到程序中,并isWindowsClassicLAF()在任何时候设置外观后调用该方法.我还举了一个例子,说明如何在运行时监听主题的更改.

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

我希望有所帮助!


Ted*_*dil 2

我不太确定你在问什么。

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

如果您想找出 Windows 正在使用哪个主题 - 我不知道。可能不太容易发现这一点。

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