该教程适用于JDK 8。本页面中描述的示例和实践不利用后续版本中引入的改进,可能使用不再可用的技术。
有关Java SE 9和后续版本中更新的语言特性的摘要,请参阅Java语言变更。
有关所有JDK版本的新功能、增强功能和已删除或不建议使用的选项的信息,请参阅JDK发行说明。
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提供以下外观:
CrossPlatformLookAndFeel
—这是“Java外观”(也称为“Metal”),在所有平台上看起来相同。它是Java API的一部分(javax.swing.plaf.metal
),如果您在代码中不执行任何操作来设置不同的外观,它将成为默认外观。
SystemLookAndFeel
—在这种情况下,应用程序使用与其运行的系统本地的外观。系统外观在运行时确定,应用程序会询问系统返回适当外观的名称。
Synth—使用XML文件创建自定义外观的基础。
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
。
所有Sun的外观都有很多共同之处。这种共同之处在API的Basic
外观中定义(javax.swing.plaf.basic
)。Motif和Windows外观是通过扩展javax.swing.plaf.basic
中的UI delegate类来构建的(可以通过相同的方式构建自定义外观)。"Basic"外观在未被扩展的情况下不会被使用。
在API中,您将看到四个外观包:
javax.swing.plaf.basic
—用于创建自定义外观时扩展的基本UI Delegate
javax.swing.plaf.metal
—Java外观,也称为跨平台外观("Metal"是该外观的Sun项目名称)。当前默认的"主题"(下面讨论)是"Ocean",因此通常被称为Ocean外观。
javax.swing.plaf.multi
—一种多路复用外观,允许UI方法同时委托给多个外观实现。它可以用于增强特定外观的行为,例如在Windows外观之上提供音频提示的外观。这是创建辅助访问外观的一种方式。
javax.swing.plaf.synth
—使用XML文件轻松配置的外观(在本课程的下一节中讨论)
您不仅限于Java平台提供的外观。您可以使用任何在程序类路径中的外观。外部外观通常以一个或多个JAR文件提供,您可以在运行时将它们添加到程序的类路径中。例如:
java -classpath .;C:\java\lafdir\customlaf.jar YourSwingApplication
一旦外部外观位于程序的类路径中,您的程序就可以像使用Java平台提供的任何外观一样使用它。
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
另一种指定当前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管理器需要设置一个L&F时,以下是外观确定步骤:
swing.defaultlaf
属性指定的L&F。如果该属性在swing.properties
文件和命令行中都有指定,则以命令行定义为准。即使在程序的GUI可见之后,你仍可以使用setLookAndFeel
更改L&F。为了使现有组件反映新的L&F,请对每个顶级容器调用SwingUtilities
的updateComponentTreeUI
方法一次。然后,你可能希望调整每个顶级容器的大小以反映其包含组件的新大小。例如:
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的主题:
DefaultMetal
Ocean
Test
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()); }
当您下载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