文档

Java™ 教程
隐藏目录
如何设置外观
指南:使用Swing创建GUI
课程:修改外观和风格

如何设置外观和风格

Swing的架构设计使您可以更改应用程序GUI的“外观和感觉”(L&F)(请参阅Swing架构概述)。 “外观”指的是GUI小部件的外观(更正式地说,JComponents),而“感觉”指的是小部件的行为方式。

Swing的架构通过将每个组件分成两个不同的类来实现多个L&Fs:一个JComponent子类和一个相应的ComponentUI子类。例如,每个JList实例都有一个ListUI的具体实现(ListUI扩展了ComponentUI)。在Swing的文档中,ComponentUI子类被称为各种名称--“UI”,“组件UI”,“UI代理”和“外观和感觉代理”都用来标识ComponentUI子类。

大多数开发人员不需要直接与UI代理进行交互。在大多数情况下,UI代理由JComponent子类在关键功能方面内部使用,JComponent子类提供了所有访问UI代理的封装方法。例如,所有JComponent子类中的绘制都委托给UI代理。通过委托绘制,'外观'可以根据L&F的不同而变化。

每个L&F负责为Swing定义的每个ComponentUI子类提供具体的实现。例如,Java外观和感觉创建MetalTabbedPaneUI的一个实例来为JTabbedPane提供L&F。实际的UI代理的创建由Swing来处理--在大多数情况下,您不需要直接与UI代理进行交互。

本节的其余部分讨论以下主题:

可用的外观

Sun的JRE提供以下外观:

  1. CrossPlatformLookAndFeel—这是“Java外观”(也称为“Metal”),在所有平台上看起来相同。它是Java API的一部分(javax.swing.plaf.metal),如果您在代码中不执行任何操作来设置不同的外观,它将成为默认外观。

  2. SystemLookAndFeel—在这种情况下,应用程序使用与其运行的系统本地的外观。系统外观在运行时确定,应用程序会询问系统返回适当外观的名称。

  3. Synth—使用XML文件创建自定义外观的基础。

  4. Multiplexing—一种将UI方法委托给多个不同的外观实现的方式。

对于Linux和Solaris,系统外观是“GTK+”,如果安装了GTK+ 2.2或更高版本,否则为“Motif”。对于Windows,系统外观是“Windows”,它模仿运行的Windows操作系统的外观,可以是经典的Windows、XP或Vista外观。GTK+、Motif和Windows外观由Sun提供并随Java SDK和JRE一起发布,尽管它们不是Java API的一部分。

Apple提供了其自己的JVM,其中包含其专有的外观。

总之,当您使用SystemLookAndFeel时,您将看到以下内容:

平台 外观
Solaris、带有GTK+ 2.2或更高版本的Linux GTK+
其他Solaris、Linux Motif
IBM UNIX IBM*
HP UX HP*
经典Windows Windows
Windows XP Windows XP
Windows Vista Windows Vista
Macintosh Macintosh*

*由系统供应商提供。

您在API中看不到系统外观。它所需的GTK+、Motif和Windows包随Java SDK一起提供,具体如下:

com.sun.java.swing.plaf.gtk.GTKLookAndFeel
com.sun.java.swing.plaf.motif.MotifLookAndFeel
com.sun.java.swing.plaf.windows.WindowsLookAndFeel

请注意路径中包括java,而不是javax


注意: GTK+外观只能在已安装GTK+ 2.2或更高版本的UNIX或Linux系统上运行,而Windows外观只能在Windows系统上运行。与Java(Metal)外观一样,Motif外观可以在任何平台上运行。

所有Sun的外观都有很多共同之处。这种共同之处在API的Basic外观中定义(javax.swing.plaf.basic)。Motif和Windows外观是通过扩展javax.swing.plaf.basic中的UI delegate类来构建的(可以通过相同的方式构建自定义外观)。"Basic"外观在未被扩展的情况下不会被使用。

在API中,您将看到四个外观包:

您不仅限于Java平台提供的外观。您可以使用任何在程序类路径中的外观。外部外观通常以一个或多个JAR文件提供,您可以在运行时将它们添加到程序的类路径中。例如:

java -classpath .;C:\java\lafdir\customlaf.jar YourSwingApplication

一旦外部外观位于程序的类路径中,您的程序就可以像使用Java平台提供的任何外观一样使用它。

以编程方式设置外观


注意: 如果你要设置外观和感觉(L&F),你应该在应用程序的最开始阶段进行设置。否则,你可能会在不论你请求的外观和感觉是什么的情况下初始化Java的外观和感觉。当静态字段引用Swing类时,这可能会无意中发生,从而导致加载外观和感觉。如果还没有指定外观和感觉,JRE的默认外观和感觉将被加载。对于Sun的JRE,默认外观和感觉是Java的外观和感觉,对于Apple的JRE,是Apple的外观和感觉,依此类推。

Swing组件使用的外观和感觉是通过javax.swing包中的UIManager类来指定的。每当创建一个Swing组件时,组件都会向UI管理器请求实现组件外观和感觉的UI代理。例如,每个JLabel构造函数都会向UI管理器查询适合该标签的UI代理对象。然后,它使用该UI代理对象来实现所有的绘图和事件处理。

要通过编程方式指定外观和感觉,可以使用UIManager.setLookAndFeel()方法,并将适当的LookAndFeel子类的完全限定名称作为其参数。例如,下面代码中的加粗部分使程序使用跨平台的Java外观和感觉:

public static void main(String[] args) {
    try {
            // 设置跨平台的Java外观和感觉(也称为"Metal")
        UIManager.setLookAndFeel(
            UIManager.getCrossPlatformLookAndFeelClassName());
    } 
    catch (UnsupportedLookAndFeelException e) {
       // 处理异常
    }
    catch (ClassNotFoundException e) {
       // 处理异常
    }
    catch (InstantiationException e) {
       // 处理异常
    }
    catch (IllegalAccessException e) {
       // 处理异常
    }
        
    new SwingApplication(); //创建并显示GUI。
}

另外,下面的代码使程序使用系统的外观和感觉:

public static void main(String[] args) {
    try {
            // 设置系统的外观和感觉
        UIManager.setLookAndFeel(
            UIManager.getSystemLookAndFeelClassName());
    } 
    catch (UnsupportedLookAndFeelException e) {
       // 处理异常
    }
    catch (ClassNotFoundException e) {
       // 处理异常
    }
    catch (InstantiationException e) {
       // 处理异常
    }
    catch (IllegalAccessException e) {
       // 处理异常
    }

    new SwingApplication(); //创建并显示GUI。
}

你也可以使用外观和感觉的实际类名作为UIManager.setLookAndFeel()的参数。例如:

// 设置跨平台的Java外观和感觉(也称为"Metal")
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");

或者

// 在任何平台上设置Motif外观和感觉
UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");

你不限于前面的参数。你可以为程序类路径中的任何L&F指定名称。

指定外观:命令行

你可以使用-D标志在命令行中指定L&F,设置swing.defaultlaf属性。例如:

java -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel MyApp

java -Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel MyApp

指定外观:swing.properties文件

另一种指定当前L&F的方法是使用swing.properties文件设置swing.defaultlaf属性。这个文件可能需要你自己创建,它位于Sun的Java发布版的lib目录中(其他Java供应商可能使用不同的位置)。例如,如果你使用javaHomeDirectory\bin中的Java解释器,那么swing.properties文件(如果存在)就在javaHomeDirectory\lib中。下面是一个swing.properties文件的示例内容:

# Swing properties
swing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel

UI管理器选择外观的步骤

当UI管理器需要设置一个L&F时,以下是外观确定步骤:

  1. 如果程序在需要外观之前设置了L&F,则UI管理器尝试创建指定外观类的实例。如果成功,所有组件都使用该L&F。
  2. 如果程序没有成功指定L&F,则UI管理器使用swing.defaultlaf属性指定的L&F。如果该属性在swing.properties文件和命令行中都有指定,则以命令行定义为准。
  3. 如果这些步骤都没有得到有效的L&F,则Sun的JRE使用Java的L&F。其他供应商,如Apple,将使用它们的默认L&F。

在启动后更改外观

即使在程序的GUI可见之后,你仍可以使用setLookAndFeel更改L&F。为了使现有组件反映新的L&F,请对每个顶级容器调用SwingUtilitiesupdateComponentTreeUI方法一次。然后,你可能希望调整每个顶级容器的大小以反映其包含组件的新大小。例如:

UIManager.setLookAndFeel(lnfName);
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();

一个示例

在下面的示例中,LookAndFeelDemo.java,您可以尝试不同的外观和风格。该程序创建一个简单的GUI,其中包含一个按钮和一个标签。每次单击按钮,标签都会递增。

您可以通过更改第18行的LOOKANDFEEL常量来更改外观和风格。前面几行的注释告诉您可以接受哪些值:

// 通过定义LOOKANDFEEL常量来指定要使用的外观和风格
// 可接受的值为:null(使用默认值),"Metal","System","Motif",
// 和 "GTK"
final static String LOOKANDFEEL = "Motif";

这里将常量设置为"Motif",它是一个在任何平台上都可以运行的外观和风格(默认情况下也是如此,"Metal")。"GTK+"无法在Windows上运行,而"Windows"只能在Windows上运行。如果您选择了一个无法运行的外观和风格,您将获得Java或Metal外观和风格。

在实际设置外观和风格的代码部分,您将看到几种不同的设置方式,如上面所讨论的:

if (LOOKANDFEEL.equals("Metal")) {
   lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
   // 设置Metal外观和风格的另一种方式是将上一行替换为:
   // lookAndFeel = "javax.swing.plaf.metal.MetalLookAndFeel";

您可以通过注释/取消注释这两种替代方案来验证两个参数是否有效。

这是LookAndFeelDemo源文件的列表:


    

主题

主题是一种用于轻松更改跨平台Java(Metal)外观的颜色和字体的方法。在上面列出的示例程序LookAndfeelDemo.java中,您可以通过将第23行的THEME常量设置为以下三个值之一来更改Metal L&F的主题:

Ocean比纯Metal外观略柔和,自Java SE 5以来一直是Metal(Java)L&F的默认主题。尽管它的名称是DefaultMetal,但它不是Metal的默认主题(在Java SE 5之前是,这解释了它的名称)。Test主题是在TestTheme.java中定义的主题,您必须使用LookAndfeelDemo.java进行编译。正如其编写方式,TestTheme.java设置了三个主要颜色(结果有些奇怪)。您可以修改TestTheme.java来测试任何喜欢的颜色。

设置主题的代码部分位于LookAndfeelDemo.java的第92行开始处。请注意,您必须使用Metal L&F来设置主题。

 if (LOOKANDFEEL.equals("Metal")) {
    if (THEME.equals("DefaultMetal"))
       MetalLookAndFeel.setCurrentTheme(new DefaultMetalTheme());
    else if (THEME.equals("Ocean"))
       MetalLookAndFeel.setCurrentTheme(new OceanTheme());
    else
       MetalLookAndFeel.setCurrentTheme(new TestTheme());
                     
    UIManager.setLookAndFeel(new MetalLookAndFeel()); 
 }      

SwingSet2演示程序

当您下载JDK和JavaFX演示和示例包并打开时,其中包含一个名为SwingSet2的演示程序,该程序具有丰富的图形用户界面,并允许您从菜单中更改外观。此外,如果您正在使用Java(Metal)外观,则可以选择多种不同的主题。各种主题的文件(例如RubyTheme.java)位于SwingSet2\src文件夹中。

这是"Ocean"主题,它是跨平台Java(Metal)外观的默认主题:

这是"Steel"主题,它是跨平台Java(Metal)外观的原始主题:

要在已安装JDK的系统上运行SwingSet2演示程序,请使用以下命令:

java -jar SwingSet2.jar

这将给您提供默认的Ocean主题。

要获取金属外观,请运行以下命令:

java -Dswing.metalTheme=steel -jar SwingSet2.jar

上一页: 修改外观和感觉
下一页: Synth外观和感觉