【问题标题】:can't detect that windows classic theme active无法检测到 Windows 经典主题处于活动状态
【发布时间】:2010-09-07 13:30:04
【问题描述】:

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

【问题讨论】:

  • 我不知道答案,但提供答案的人似乎甚至没有阅读这个问题。 Windows XP、Vista 和 7 有其标准主题,但也可以使其看起来像 Windows 2000(经典主题)。问题是如何检测用户将 Windows 设置为哪些。
  • @Ricky Clarkson:从这个问题我了解到他说他将“主题”设置为WindowsClassicLookAndFeel,这是 java 中的一个 LaF,并想看看它当前是否已安装。

标签: java swing look-and-feel


【解决方案1】:

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

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 主题更改为另一个,则不会触发侦听器,但如果用户从一个主题更改为 Classic,反之亦然。

希望对你有帮助!

【讨论】:

    【解决方案2】:

    我不太确定你在问什么。

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

    如果您想找出 Windows 使用的主题 - 我不知道。可能不太容易找到。

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

    【讨论】:

    • 是的,类似这样,但是有 com.sun.java.swing.plaf.windows.WindowsLookAndFeel 和 com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel,但是 UIManager.getSystemLookAndFeelClassName( ) 仅返回 com.sun.java.swing.plaf.windows.WindowsLookAndFeel 即使应用了经典 Windows 主题。
    • 你给出了一个 javadoc 的链接,甚至没有阅读该方法正在做什么。
    • @tulskiy fland 最近重新表述了他的问题,所以我只能猜测他的要求。因此,我的回答没有多大意义了。
    【解决方案3】:

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

    【讨论】:

    • 它没有回答,OP如何检测是否安装了经典主题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    相关资源
    最近更新 更多