无法检测到 Windows 经典主题处于活动状态

发布于 2024-09-17 16:04:57 字数 184 浏览 7 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

香橙ぽ 2024-09-24 16:06:30

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

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.

浅浅 2024-09-24 16:05:55

我不太确定你在问什么。

如果您询问 SWING 当前使用的是哪个主题/外观和感觉,请尝试
UIManager.getSystemLookAndFeelClassName()

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

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

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)

转身泪倾城 2024-09-24 16:05:40

看来你是专门报名来问这个问题的,现在我是专门报名来回答这个问题的!我在谷歌上搜索了一些完全不同的东西,但我很感兴趣并做了一些实验,这就是我的发现:

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

您可以将此类导入到您的程序中,并在设置 Look&Feel 后随时调用 isWindowsClassicLAF() 方法。我还给出了一个示例,说明如何在运行时侦听主题的更改。

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

我希望这有帮助!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文