65.9K
CodeProject 正在变化。 阅读更多。
Home

Java 外观主题

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.60/5 (35投票s)

2002年7月5日

6分钟阅读

viewsIcon

315151

downloadIcon

7385

用丰富多彩且可定制的主题增强您的 Swing 应用程序的视觉吸引力。

Themes for your Swing application

引言

除了增强的外观和高级功能之外,Swing 最棒的事情之一就是其可插拔的外观(PLAF)。PLAF 架构允许无缝地更改应用程序的外观以及应用程序与用户的交互方式。但是,设计和开发 PLAF 要详尽且复杂得多。另一方面,主题提供了一种更改 Swing 应用程序外观的简单替代方法。主题更容易实现,并且它们通过使用默认的 Java 外观来增强应用程序 UI 的视觉吸引力。

主题机制允许开发人员轻松指定外观(L&F)使用的默认颜色、字体和图标。它允许开发人员编写自己的主题;让他们可以选择按照自己想要的方式展示应用程序 GUI,而不是依赖系统提供的默认值。

本文讨论了如何为 Swing 的默认“Metal”外观使用不同的主题。“Metal”外观,也称为 Java 外观,在所有 Java 2 平台上都得到支持。

Metal 主题

Swing 的 Metal 外观的默认主题是“Steel”。“Steel”主题背后的类是 - javax.swing.plaf.metal.DefaultMetalTheme,它扩展了 abstract 基类 MetalThemeDefaultMetalTheme 类覆盖了所有必需的方法,这些方法为 Java 外观(又名 Metal L&F)提供了其默认的“Steel”主题。此类实现了各种方法,其形式为 getXXX(),例如 getMenuTextFont()getPrimary1()getSecondary1() 等。这些方法返回主题用于 GUI 的默认主颜色、次颜色和各种字体。

任何打算为其 UI 使用自己主题的应用程序都可以通过子类化 DefaultMetalTheme 类,仅覆盖必需的方法。

此应用程序提供了两种使用这些主题的方法。一种是内置主题,另一种是自定义主题,允许从特定格式编写的属性文件中读取主题。自定义主题方法提供了更大的灵活性和便利性,可以在不更改编译代码的情况下部署各种主题。这两种方法都使用一个类,该类是 DefaultMetalTheme 的子类。

内置主题

除了 Java 的默认“Steel”主题之外,此应用程序还使用了另外两个内置主题 - White Satin 和 Moody Blues。这些内置主题实现为类。它们各自都扩展了 DefaultMetalTheme 类。MoodyBlueTheme 类的代码如下所示

import javax.swing.plaf.*;
import javax.swing.plaf.metal.*;

public class MoodyBlueTheme extends DefaultMetalTheme
{
    public String getName() { return "Moody Blues"; }
    
          // blue shades
    private final ColorUIResource primary1     = 
           new ColorUIResource(0x0, 0x33, 0x99);
    private final ColorUIResource primary2     = 
           new ColorUIResource(0xD0, 0xDD, 0xFF);
    private final ColorUIResource primary3     = 
           new ColorUIResource(0x0, 0x99, 0xFF); 
    
    private final ColorUIResource secondary1   = 
           new ColorUIResource(0x6F, 0x6F, 0x6F);
    private final ColorUIResource secondary2   = 
            new ColorUIResource(0x9F, 0x9F, 0x9F);
    private final ColorUIResource secondary3   = 
           new ColorUIResource(0x1f, 0x7f, 0xDC);
    
          // the functions overridden from the base 
          // class => DefaultMetalTheme
    
    protected ColorUIResource getPrimary1() { return primary1; }  
    protected ColorUIResource getPrimary2() { return primary2; } 
    protected ColorUIResource getPrimary3() { return primary3; } 
    
    protected ColorUIResource getSecondary1() { return secondary1; }
    protected ColorUIResource getSecondary2() { return secondary2; }
    protected ColorUIResource getSecondary3() { return secondary3; }
}

Moody Blues 主题仅更改了默认 Java 外观的默认主色和次色。您也可以覆盖字体方法来更改字体,正如 White Satin 主题中所举例说明的那样。

一旦用户从“主题”菜单中选择了一个特定的主题,就会创建一个该特定主题类的对象,并更新整个 UI 以反映新主题。这方面的代码可以这样写

   // user selects theme - Moody Blues 
MetalTheme theme = new MoodyBlueTheme();  
   // set the chosen theme
MetalLookAndFeel.setCurrentTheme(theme);
   // Show name of the theme as window title
this.setTitle(theme.getName());

try
{
    UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
    SwingUtilities.updateComponentTreeUI(this);
}
catch(Exception e)
{
    System.out.println(e);
}

自定义主题

自定义主题由 CustomTheme 类处理。该类也扩展了 DefaultMetalTheme 类,但与内置主题类有显著不同。它从特定格式的 Java 属性文件主题文件中读取主题属性。与内置主题一样,该类也覆盖了 DefaultMetalTheme 的各种方法来返回主颜色、次颜色和字体。它与内置主题类的不同之处在于颜色和字体的创建。该类读取指定的主题文件,解析颜色和字体,然后将它们适当地存储。该类的一些代码如下所示。

构造函数

CustomTheme 类的构造函数最初将颜色和字体设置为默认值,这些默认值与 DefaultMetalTheme 类相同。然后它从主题文件的输入流中读取这些值。

public CustomTheme(InputStream is)
{
    defaultColors();    
    defaultFonts();
    loadProperties(is);
}

读取自定义主题文件

主题文件存储为特定格式的 Java 属性文件。此主题文件的格式在应用程序的“帮助”中有说明。此外,一个示例主题文件 - “gray.theme”与此应用程序一起提供。使用此格式创建自己的主题非常简单明了。

CustomTheme 类的方法 loadProperties(InputStream is) 从主题文件的输入流中读取颜色和字体,并相应地设置主颜色、次颜色和可配置字体的.如果主题文件中缺少任何值,则使用 DefaultMetalTheme 的默认值,如构造函数中所设置的。该方法的代码片段如下所示。

private void loadProperties(InputStream is)
{
    Properties prop = new Properties();
        // load the Properties
    try{
          prop.load(is);
    }catch(IOException e)
    {
          System.out.println(e);    
    }
        // get theme name
    String szTemp = prop.getProperty("name");
    if(null != szTemp)
    {
          szThemeName = szTemp;
    }
    
        // get primary colors    
    szTemp = prop.getProperty("primary1");
    if(null != szTemp)
    {
          primary1 = parseColor(szTemp);
    }
    
        // read more properties
        // ....................................
}

解析颜色和字体

该类的另外两个函数 parseColor(String color)parseFont(String font) 分别从主题属性文件中读取的字符串构造 ColorUIResourceFontUIResource 类的对象。

将选定的主题反映到 UI 的过程对于自定义主题也是相同的,这已经在前面讨论过了。

装饰性框架和对话框

应用程序的 main() 方法中添加了以下几行,为应用程序的框架和对话框提供了装饰性的边框和窗口标题。可以在本文开头提供的快照中看到装饰性框架和对话框。但是,这仅适用于 JDK 1.4。

    // For JDK 1.4 only. 
    // Comment these lines for JDK 1.2 & 1.3
    
JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);

如果您使用的是 JDK 1.2 或 JDK 1.3,您将不得不注释掉这两行才能编译代码而没有任何错误。其余代码无需其他更改。在注释掉这两行之后,我已成功编译并执行了使用 JDK 1.2 和 JDK 1.3 的代码。显然,框架和对话框的装饰性外观将不可见。

本文提供的演示项目是使用 JDK 1.4 开发的,您需要兼容的 JVM 版本才能运行它。如果您使用的是 MS Windows,可以通过双击“theme.jar”文件来运行演示。

其他资源

在开发此应用程序时,我参考了 JDK 1.4 工具包中提供的演示代码。以下是一些您可能会发现有趣且有用的其他资源

历史

  • 2002 年 7 月 5 日:初始版本

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.