首页 > 编程语言 >Java 中文官方教程 2022 版(二十三)

Java 中文官方教程 2022 版(二十三)

时间:2024-04-12 14:55:54浏览次数:31  
标签:教程 管理器 感觉 布局 外观 2022 swing 组件 Java

原文:docs.oracle.com/javase/tutorial/reallybigindex.html

创建自定义布局管理器

原文:docs.oracle.com/javase/tutorial/uiswing/layout/custom.html

在开始创建自定义布局管理器之前,请确保没有现有的布局管理器符合您的要求。特别是像GridBagLayoutSpringLayoutBoxLayout这样的布局管理器在许多情况下都足够灵活。您还可以从其他来源找到布局管理器,比如从互联网上。最后,您可以通过将组件分组到诸如面板之类的容器中来简化布局。


注意: 本课程涵盖了手动编写布局代码,这可能具有挑战性。如果您不想学习布局管理的所有细节,您可能更喜欢使用GroupLayout布局管理器结合构建工具来布局您的 GUI。其中一个构建工具是 NetBeans IDE。否则,如果您想手动编码而不想使用GroupLayout,那么推荐使用GridBagLayout作为下一个最灵活和强大的布局管理器。


如果您有兴趣使用 JavaFX 来创建您的 GUI,请参阅在 JavaFX 中使用布局

要创建自定义布局管理器,您必须创建一个实现LayoutManager接口的类。您可以直接实现它,或者实现其子接口LayoutManager2

每个布局管理器必须至少实现LayoutManager接口所需的以下五个方法:

void addLayoutComponent(String, Component)

Container类的add方法调用。通常不将字符串与其组件关联的布局管理器在此方法中不执行任何操作。

void removeLayoutComponent(Component)

Container方法removeremoveAll调用。布局管理器重写此方法以清除与Component关联的内部状态。

Dimension preferredLayoutSize(Container)

Container类的getPreferredSize方法调用,该方法本身在各种情况下被调用。此方法应计算并返回容器的理想大小,假设其中的组件将达到或超过其首选大小。此方法必须考虑容器的内部边框,这些边框由getInsets方法返回。

Dimension minimumLayoutSize(Container)

ContainergetMinimumSize方法调用,该方法本身在各种情况下都会被调用。该方法应计算并返回容器的最小尺寸,假设其中的组件将在其最小尺寸或以上。该方法必须考虑容器的内部边框,这些边框由getInsets方法返回。

void layoutContainer(Container)

用于定位和调整容器中每个组件的大小。布局管理器的layoutContainer方法实际上不会绘制组件。它只是调用每个组件的setSizesetLocationsetBounds方法中的一个或多个来设置组件的大小和位置。

该方法必须考虑容器的内部边框,这些边框由getInsets方法返回。如果适用,它还应考虑容器的方向(由getComponentOrientation方法返回)。您不能假设在调用layoutContainer之前将调用preferredLayoutSizeminimumLayoutSize方法。

除了实现前述的五个方法外,布局管理器通常会实现至少一个公共构造函数和toString方法。

如果您希望支持组件约束、最大尺寸或对齐方式,则您的布局管理器应实现LayoutManager2接口。事实上,出于这些原因以及许多其他原因,几乎所有现代布局管理器都需要实现LayoutManager2。该接口在LayoutManager所需的五个方法基础上添加了五个方法:

  • addLayoutComponent(Component, Object)

  • getLayoutAlignmentX(Container)

  • getLayoutAlignmentY(Container)

  • invalidateLayout(Container)

  • maximumLayoutSize(Container)

这些方法中,最重要的是addLayoutComponent(Component, Object)invalidateLayout(Container)addLayoutComponent方法用于使用指定的约束对象向布局中添加组件。invalidateLayout方法用于使布局失效,因此如果布局管理器缓存了信息,则应将其丢弃。有关LayoutManager2的更多信息,请参阅LayoutManager2 API 文档。

最后,每当您创建自定义布局管理器时,都应注意保持对不再是Container子级的Component实例的引用。换句话说,布局管理器应覆盖removeLayoutComponent以清除与Component相关的任何缓存状态。

自定义布局的示例

示例CustomLayoutDemo使用了一个名为DiagonalLayout的自定义布局管理器。您可以在DiagonalLayout.java中找到布局管理器的源代码。DialogLayout以对角线方式从左到右布置组件,每行一个组件。这里是使用DialogLayout布置五个按钮的 CustomLayoutDemo 的图片。

CustomLayoutDemo 的快照

点击启动按钮以使用Java™ Web Start运行CustomLayoutDemo下载 JDK 7 或更高版本)。或者,要自行编译和运行示例,请参考示例索引。

启动 CustomLayoutDemo 示例

不使用布局管理器(绝对定位)

原文:docs.oracle.com/javase/tutorial/uiswing/layout/none.html

尽管可以不使用布局管理器,但尽可能使用布局管理器。布局管理器使得更容易调整外观和感觉依赖的组件外观,不同的字体大小,容器的大小变化以及不同的语言环境。布局管理器也可以轻松地被其他容器以及其他程序重复使用。


注意:本课程涵盖了手动编写布局代码,这可能具有挑战性。如果您不想学习布局管理的所有细节,您可能更喜欢使用GroupLayout布局管理器结合构建工具来布局您的 GUI。其中一个构建工具是 NetBeans IDE。否则,如果您想手动编码而不想使用GroupLayout,那么推荐使用GridBagLayout作为下一个最灵活和强大的布局管理器。


如果您有兴趣使用 JavaFX 创建 GUI,请参阅在 JavaFX 中使用布局

如果一个容器包含的组件的大小不受容器的大小、字体、外观和语言更改的影响,那么绝对定位可能是合理的。包含内部框架的桌面窗格属于这一类别。内部框架的大小和位置不直接取决于桌面窗格的大小。程序员确定内部框架在桌面窗格内的初始大小和位置,然后用户可以移动或调整框架的大小。在这种情况下,布局管理器是不必要的。

另一种适合使用绝对定位的情况是自定义容器,该容器执行特定于容器的大小和位置计算,并且可能需要了解容器的专门状态。这是分割窗格的情况。

创建一个没有布局管理器的容器涉及以下步骤。

  1. 将容器的布局管理器设置为 null,调用setLayout(null)

  2. 对容器的每个子元素调用Component类的setbounds方法。

  3. 调用Component类的repaint方法。

然而,使用绝对定位创建容器可能会在包含容器的窗口调整大小时出现问题。

这是一个内容窗格使用绝对定位的框架的快照。

AbsoluteLayoutDemo 的快照

点击“启动”按钮以使用Java™ Web Start运行 AbsoluteLayoutDemo(下载 JDK 7 或更高版本)。或者,要自行编译和运行示例,请参考示例索引。

启动 AbsoluteLayoutDemo 示例

其代码位于AbsoluteLayoutDemo.java中。以下代码片段显示了如何在内容窗格中创建和布局组件。

pane.setLayout(null);

JButton b1 = new JButton("one");
JButton b2 = new JButton("two");
JButton b3 = new JButton("three");

pane.add(b1);
pane.add(b2);
pane.add(b3);

Insets insets = pane.getInsets();
Dimension size = b1.getPreferredSize();
b1.setBounds(25 + insets.left, 5 + insets.top,
             size.width, size.height);
size = b2.getPreferredSize();
b2.setBounds(55 + insets.left, 40 + insets.top,
             size.width, size.height);
size = b3.getPreferredSize();
b3.setBounds(150 + insets.left, 15 + insets.top,
             size.width + 50, size.height + 20);

...*//In the main method:*
Insets insets = frame.getInsets();
frame.setSize(300 + insets.left + insets.right,
              125 + insets.top + insets.bottom);

解决常见布局问题

原文:docs.oracle.com/javase/tutorial/uiswing/layout/problems.html


注意: 本课程涵盖了手动编写布局代码,这可能具有挑战性。如果你不想学习布局管理的所有细节,可以选择使用GroupLayout布局管理器结合构建工具来布局你的 GUI。其中一种构建工具是 NetBeans IDE。否则,如果你想手动编码而不想使用GroupLayout,那么推荐使用GridBagLayout作为下一个最灵活和强大的布局管理器。


如果你有兴趣使用 JavaFX 来创建 GUI,请查看使用 JavaFX 中的布局

问题: 如何指定组件的确切尺寸?

  • 一些较现代的布局管理器提供了覆盖组件设置的尺寸的方法。检查你正在使用的布局管理器是否允许你指定组件大小。

  • 确保你真的需要设置组件的确切尺寸。每个 Swing 组件的首选尺寸都不同,取决于其使用的字体和外观。因此,通常没有必要指定 Swing 组件的确切尺寸。

  • 如果组件不受布局管理器控制,可以通过调用setSizesetBounds方法来设置其大小。否则,你需要提供尺寸提示,然后确保你使用的布局管理器尊重尺寸提示。

  • 如果你扩展了 Swing 组件类,可以通过重写组件的getMinimumSizegetPreferredSizegetMaximumSize方法来给出尺寸提示。这种方法的好处在于,每个get*Xxxx*Size方法可以通过调用super.get*Xxxx*Size()来获取组件的默认尺寸提示。然后在返回之前可以调整尺寸,如果有必要的话。这对于文本组件特别方便,其中你可能希望固定宽度,但高度由内容确定。然而,有时会在GridBagLayout和文本字段中遇到问题,如果容器的尺寸小于首选尺寸,则使用最小尺寸,这可能会导致文本字段大幅缩小。

  • 另一种给出尺寸提示的方法是调用组件的setMinimumSizesetPreferredSizesetMaximumSize方法。

  • 如果为已经可见的组件指定了新的尺寸提示,则需要在其上调用revalidate方法,以确保其包含层次结构再次布局。然后调用repaint方法。


注意: 无论您如何指定组件的大小,请确保组件的容器使用一个能够尊重组件请求大小的布局管理器。FlowLayoutGridBagLayout 布局管理器使用组件的首选大小(后者取决于您设置的约束条件),但 BorderLayoutGridLayout 通常不会。BoxLayout 布局管理器通常使用组件的首选大小(尽管组件可以更大),并且是少数几个尊重组件最大大小的布局管理器之一。


问题: 我添加了组件到容器后,组件没有显示出来。

  • 在添加组件后,您需要调用 revalidaterepaint 才能使组件显示在容器中。

问题: 我的自定义组件尺寸太小了。

  • 组件是否实现了 getPreferredSizegetMinimumSize 方法?如果是,它们是否返回了正确的值?

  • 您是否使用了一个可以利用所有可用空间的布局管理器?请参阅选择布局管理器的提示以获取一些关于选择布局管理器并指定其使用特定组件的最大可用空间的提示。

如果您在此列表中找不到您的问题,请参阅解决常见组件问题。

问题和练习:在容器内布置组件

原文:docs.oracle.com/javase/tutorial/uiswing/QandE/questions-ch4.html

问题

在以下每个问题中,选择最适合描述布局的布局管理器。假设由布局管理器控制的容器是JPanel

1. 该容器有一个组件应尽可能占据空间

Layout1-1.png Layout1-2.png

a. BorderLayout

b. GridLayout

c. GridBagLayout

d. a 和 b

e. b 和 c

2. 该容器有一行组件,应该以相同大小显示,填充容器的整个区域。

Layout2-1.png Layout2-2.png

a. FlowLayout

b. GridLayout

c. BoxLayout

d. a 和 b

3. 该容器以列形式显示多个组件,额外的空间位于前两个组件之间。

Layout3-1.png Layout3-2.png

a. FlowLayout

b. BoxLayout

c. GridLayout

d. BorderLayout

4. 该容器可以在不同时间显示三个完全不同的组件,可能取决于用户输入或程序状态。即使组件的大小不同,从一个组件切换到下一个也不应更改为组件分配的空间量。

Layout4-1.png Layout4-2.png

a. SpringLayout

b. BoxLayout

c. CardLayout

d. GridBagLayout

练习

1. 实现问题 1 中描述和显示的布局。

2. 实现问题 2 中描述和显示的布局。

3. 实现问题 3 中描述和显示的布局。

4. 实现问题 4 中描述和显示的布局。

5. 通过添加一行代码,使您为练习 2 编写的程序显示组件从右到左,而不是从左到右。

Layout2-3.png 检查您的答案。

课程:修改外观和感觉

原文:docs.oracle.com/javase/tutorial/uiswing/lookandfeel/index.html

示例索引

这节课告诉你如何改变你的 Swing 应用程序的外观和感觉。应用程序的“外观”指的是它的外观。而“感觉”指的是小部件的行为。你可以选择使用默认的 Swing 外观和感觉(比如 Metal 外观和感觉的 Ocean 主题),或者使用本地平台的外观和感觉(比如 Windows、GTK+),或者你可以自定义自己的外观和感觉。

如何设置外观和感觉

设置外观和感觉为可用外观和感觉之一的基本信息。提供了通过编程和命令行设置外观和感觉的信息。

Synth 外观和感觉

提供了如何使用 Synth 包自定义外观和感觉的信息。

Nimbus 外观和感觉

提供了如何使用 JDK 7 发布的 Nimbus 包自定义外观和感觉的信息。

如果你有兴趣使用 JavaFX 创建你的 GUI,请参阅使用 CSS 为 JavaFX 应用程序设置外观和感觉使用 JavaFX 图表

如何设置外观和感觉

原文:docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html

Swing 的架构设计使您可以更改应用程序 GUI 的“外观和感觉”(L&F)(请参阅A Swing Architecture Overview)。“外观”指的是 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 代理交互。

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

  • 可用的外观和感觉

  • 以编程方式设置外观和感觉

  • 指定外观和感觉:命令行

  • 指定外观和感觉:swing.properties

  • UI 管理器如何选择外观和感觉

  • 启动后更改外观和感觉

  • 一个示例

  • 主题

  • SwingSet2 演示程序

可用的外观和感觉

Sun 的 JRE 提供以下 L&Fs:

  1. CrossPlatformLookAndFeel—这是在所有平台上看起来相同的“Java L&F”(也称为“Metal”)。它是 Java API 的一部分(javax.swing.plaf.metal),如果您在代码中不做任何设置,则将使用默认值。

  2. SystemLookAndFeel—在这里,应用程序使用与其运行的系统相对应的 L&F。系统 L&F 在运行时确定,应用程序会询问系统返回适当 L&F 的名称。

  3. Synth——用 XML 文件创建自己的外观和感觉的基础。

  4. 多路复用—一种让 UI 方法同时委托给多个不同外观实现的方式。

对于 Linux 和 Solaris,如果安装了 GTK+ 2.2 或更高版本,则系统 L&Fs 是“GTK+”,否则是“Motif”。对于 Windows,系统 L&F 是“Windows”,模仿正在运行的特定 Windows OS 的 L&F—经典 Windows、XP 或 Vista。GTK+、Motif 和 Windows L&Fs 由 Sun 提供,并随 Java SDK 和 JRE 一起提供,尽管它们不是 Java API 的一部分。

苹果提供了自己的 JVM,其中包含他们专有的 L&F。

总之,当您使用 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 中看不到系统 L&F。它需要的 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+ L&F 只能在安装了 GTK+ 2.2 或更高版本的 UNIX 或 Linux 系统上运行,而 Windows L&F 只能在 Windows 系统上运行。与 Java(Metal)L&F 一样,Motif L&F 可在任何平台上运行。


所有 Sun 的 L&Fs 都有很多共同点。这种共同点在 API 中的 Basic 外观和感觉中定义(javax.swing.plaf.basic)。Motif 和 Windows L&Fs 分别通过扩展 javax.swing.plaf.basic 中的 UI 代理类构建(可以通过相同的方式构建自定义 L&F)。"Basic" L&F 不会在不被扩展的情况下使用。

在 API 中,您将看到四个 L&F 包:

  • javax.swing.plaf.basic—在创建自定义 L&F 时要扩展的基本 UI 代理

  • javax.swing.plaf.metal—Java L&F,也被称为跨平台 L&F("Metal" 是这个 L&F 的 Sun 项目名称)。这个 L&F 的当前默认“主题”(下面讨论)是“Ocean”,因此通常被称为 Ocean L&F。

  • javax.swing.plaf.multi—一个多路复用外观,允许 UI 方法同时委托给多个外观实现。它可以用于增强特定外观的行为,例如在 Windows 外观之上提供音频提示的外观。这是创建残障人士可访问的外观的一种方式。

  • javax.swing.plaf.synth—使用 XML 文件轻松配置的 L&F(在本课程的下一部分讨论)

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

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

一旦外部 L&F 在程序的类路径中,程序就可以像使用 Java 平台提供的任何 L&Fs 一样使用它。

以编程方式设置外观和感觉


注意: 如果要设置外观和感觉,应该在应用程序中的第一步就这样做。否则,你可能会在请求的外观和感觉之外初始化 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 {
            // Set cross-platform Java L&F (also called "Metal")
        UIManager.setLookAndFeel(
            UIManager.getCrossPlatformLookAndFeelClassName());
    } 
    catch (UnsupportedLookAndFeelException e) {
       // handle exception
    }
    catch (ClassNotFoundException e) {
       // handle exception
    }
    catch (InstantiationException e) {
       // handle exception
    }
    catch (IllegalAccessException e) {
       // handle exception
    }

    new SwingApplication(); //Create and show the GUI.
}

或者,这段代码使程序使用系统外观和感觉:

public static void main(String[] args) {
    try {
            // Set System L&F
        UIManager.setLookAndFeel(
            UIManager.getSystemLookAndFeelClassName());
    } 
    catch (UnsupportedLookAndFeelException e) {
       // handle exception
    }
    catch (ClassNotFoundException e) {
       // handle exception
    }
    catch (InstantiationException e) {
       // handle exception
    }
    catch (IllegalAccessException e) {
       // handle exception
    }

    new SwingApplication(); //Create and show the GUI.
}

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

// Set cross-platform Java L&F (also called "Metal")
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");

// Set Motif L&F on any platform
UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");

你不限于前面的参数。你可以为程序类路径中的任何外观和感觉指定名称。

指定外观和感觉:命令行

你可以通过使用-D标志设置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 文件

另一种指定当前外观和感觉的方法是使用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 管理器需要设置外观和感觉时,以下是外观和感觉确定步骤:

  1. 如果程序在需要外观和感觉之前设置了外观和感觉,UI 管理器会尝试创建指定外观和感觉类的实例。如果成功,所有组件都将使用该外观和感觉。

  2. 如果程序没有成功指定外观和感觉,那么 UI 管理器将使用swing.defaultlaf属性指定的外观和感觉。如果swing.properties文件和命令行中都指定了该属性,则以命令行定义为准。

  3. 如果这些步骤都没有导致有效的外观和感觉,Sun 的 JRE 将使用 Java 外观和感觉。其他供应商,如苹果,将使用其默认外观和感觉。

启动后更改外观和感觉

即使程序的 GUI 可见,您也可以使用setLookAndFeel更改外观和感觉。为了使现有组件反映新的外观和感觉,每个顶级容器调用一次SwingUtilitiesupdateComponentTreeUI方法。然后,您可能希望调整每个顶级容器的大小以反映其包含组件的新大小。例如:

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

一个示例

在以下示例中,LookAndFeelDemo.java,您可以尝试不同的外观和感觉。该程序创建了一个简单的 GUI,带有一个按钮和一个标签。每次单击按钮时,标签会递增。

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

    // Specify the look and feel to use by defining the LOOKANDFEEL constant
    // Valid values are: null (use the default), "Metal", "System", "Motif",
    // and "GTK"
    final static String LOOKANDFEEL = "Motif";

这里将常量设置为"Motif",这是一个可以在任何平台上运行的外观和感觉(默认为"Metal")。"GTK+"不会在 Windows 上运行,而"Windows"只会在 Windows 上运行。如果选择无法运行的外观和感觉,您将获得 Java 或 Metal 外观和感觉。

在实际设置外观和感觉的代码部分,您将看到几种不同的设置方式,如上所述:

if (LOOKANDFEEL.equals("Metal")) {
   lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
   //  an alternative way to set the Metal L&F is to replace the 
   // previous line with:
   // lookAndFeel = "javax.swing.plaf.metal.MetalLookAndFeel";

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

这是LookAndFeelDemo源文件的列表:


package lookandfeel;

import javax.swing.*;          
import java.awt.*;
import java.awt.event.*;
import javax.swing.plaf.metal.*;

public class LookAndFeelDemo implements ActionListener {
    private static String labelPrefix = "Number of button clicks: ";
    private int numClicks = 0;
    final JLabel label = new JLabel(labelPrefix + "0    ");

    // Specify the look and feel to use by defining the LOOKANDFEEL constant
    // Valid values are: null (use the default), "Metal", "System", "Motif",
    // and "GTK"
    final static String LOOKANDFEEL = "Metal";

    // If you choose the Metal L&F, you can also choose a theme.
    // Specify the theme to use by defining the THEME constant
    // Valid values are: "DefaultMetal", "Ocean",  and "Test"
    final static String THEME = "Test";

    public Component createComponents() {
        JButton button = new JButton("I'm a Swing button!");
        button.setMnemonic(KeyEvent.VK_I);
        button.addActionListener(this);
        label.setLabelFor(button);

        JPanel pane = new JPanel(new GridLayout(0, 1));
        pane.add(button);
        pane.add(label);
        pane.setBorder(BorderFactory.createEmptyBorder(
                                        30, //top
                                        30, //left
                                        10, //bottom
                                        30) //right
                                        );

        return pane;
    }

    public void actionPerformed(ActionEvent e) {
        numClicks++;
        label.setText(labelPrefix + numClicks);
    }

    private static void initLookAndFeel() {
        String lookAndFeel = null;

        if (LOOKANDFEEL != null) {
            if (LOOKANDFEEL.equals("Metal")) {
                lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
              //  an alternative way to set the Metal L&F is to replace the 
              // previous line with:
              // lookAndFeel = "javax.swing.plaf.metal.MetalLookAndFeel";

            }

            else if (LOOKANDFEEL.equals("System")) {
                lookAndFeel = UIManager.getSystemLookAndFeelClassName();
            } 

            else if (LOOKANDFEEL.equals("Motif")) {
                lookAndFeel = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
            } 

            else if (LOOKANDFEEL.equals("GTK")) { 
                lookAndFeel = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
            } 

            else {
                System.err.println("Unexpected value of LOOKANDFEEL specified: "
                                   + LOOKANDFEEL);
                lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
            }

            try {

                UIManager.setLookAndFeel(lookAndFeel);

                // If L&F = "Metal", set the theme

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

            } 

            catch (ClassNotFoundException e) {
                System.err.println("Couldn't find class for specified look and feel:"
                                   + lookAndFeel);
                System.err.println("Did you include the L&F library in the class path?");
                System.err.println("Using the default look and feel.");
            } 

            catch (UnsupportedLookAndFeelException e) {
                System.err.println("Can't use the specified look and feel ("
                                   + lookAndFeel
                                   + ") on this platform.");
                System.err.println("Using the default look and feel.");
            } 

            catch (Exception e) {
                System.err.println("Couldn't get specified look and feel ("
                                   + lookAndFeel
                                   + "), for some reason.");
                System.err.println("Using the default look and feel.");
                e.printStackTrace();
            }
        }
    }

    private static void createAndShowGUI() {
        //Set the look and feel.
        initLookAndFeel();

        //Make sure we have nice window decorations.
        JFrame.setDefaultLookAndFeelDecorated(true);

        //Create and set up the window.
        JFrame frame = new JFrame("SwingApplication");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        LookAndFeelDemo app = new LookAndFeelDemo();
        Component contents = app.createComponents();
        frame.getContentPane().add(contents, BorderLayout.CENTER);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event dispatch thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

主题

主题被引入作为轻松更改跨平台 Java(Metal)外观和感觉的颜色和字体的一种方式。在上面列出的示例程序LookAndfeelDemo.java中,您可以通过将第 23 行的THEME常量设置为三个值之一来更改金属外观和感觉的主题。

  • DefaultMetal

  • Ocean

  • Test

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

设置主题的代码部分从LookAndfeelDemo.java的第 92 行开始。请注意,您必须使用金属外观和感觉来设置主题。

 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的演示程序的demo\jfc文件夹。该程序具有丰富的图形用户界面,并允许您从菜单中更改外观。此外,如果您正在使用 Java(Metal)外观,您可以选择各种不同的主题。各种主题的文件(例如,RubyTheme.java)位于SwingSet2\src文件夹中。

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

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

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

java -jar SwingSet2.jar

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

要获得金属 L&F,请运行以下命令:

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

合成外观

原文:docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html

创建自定义外观或修改现有外观可能是一项艰巨的任务。javax.swing.plaf.synth包可用于以更少的工作量创建自定义外观。您可以通过编程方式或使用外部 XML 文件创建合成外观。以下讨论专注于使用外部 XML 文件创建合成外观。有关通过编程方式创建合成外观的讨论,请参阅 API 文档。

使用合成外观,您提供“外观”。合成本身提供“感觉”。因此,您可以将合成 L&F 视为“皮肤”。

合成架构

请回顾前一个主题,每个 L&F 都有责任为 Swing 定义的许多ComponentUI子类提供具体实现。合成 L&F 为您处理了这一切。要使用合成,您无需创建任何ComponentUI—您只需指定每个组件如何绘制,以及影响布局和大小的各种属性。

合成在比组件更细粒度的级别上运行—这个细粒度级别称为“区域”。每个组件都有一个或多个区域。许多组件只有一个区域,例如JButton。其他组件有多个区域,例如JScrollBar。由合成提供的每个ComponentUISynthStyleComponentUI定义的每个区域关联起来。例如,合成为JScrollBar定义了三个区域:轨道、拇指和滚动条本身。合成为JScrollBar定义的ScrollBarUI(为JScrollBar定义的ComponentUI子类)实现将SynthStyle与每个区域关联起来。

合成架构图。

SynthStyle提供了合成ComponentUI实现所使用的样式信息。例如,SynthStyle定义了前景色、背景色、字体信息等。此外,每个SynthStyle都有一个用于绘制区域的SynthPainter。例如,SynthPainter定义了paintScrollBarThumbBackgroundpaintScrollBarThumbBorder两种方法,用于绘制滚动条拇指区域。

在合成中,每个ComponentUI都使用SynthStyleFactory获取SynthStyles。有两种定义SynthStyleFactory的方法:通过 Synth XML 文件或以编程方式。以下代码展示了如何加载指定合成外观的 XML 文件——在幕后,这将创建一个从 XML 文件中填充SynthStylesSynthStyleFactory实现:

  SynthLookAndFeel laf = new SynthLookAndFeel();
  laf.load(MyClass.class.getResourceAsStream("laf.xml"), MyClass.class);
  UIManager.setLookAndFeel(laf);

编程路线涉及创建一个返回 SynthStylesSynthStyleFactory 实现。以下代码创建了一个为按钮和树返回不同 SynthStyles 的自定义 SynthStyleFactory

 class MyStyleFactory extends SynthStyleFactory {
     public SynthStyle getStyle(JComponent c, Region id) {
         if (id == Region.BUTTON) {
             return buttonStyle;
         }
         else if (id == Region.TREE) {
             return treeStyle;
         }
         return defaultStyle;
     }
 }
 SynthLookAndFeel laf = new SynthLookAndFeel();
 UIManager.setLookAndFeel(laf);
 SynthLookAndFeel.setStyleFactory(new MyStyleFactory());

XML 文件

Synth XML 文件的 DTD 解释可以在javax.swing.plaf.synth/doc-files/synthFileFormat.html找到。

当加载 Synth 外观时,只有那些有定义(绑定到区域的“style”,如下所述)的 GUI 组件(或区域)才会被呈现。对于任何组件都没有默认行为——没有在 Synth XML 文件中定义样式,GUI 就是一块空白画布。

要指定组件(或区域)的呈现方式,您的 XML 文件必须包含一个

标签:教程,管理器,感觉,布局,外观,2022,swing,组件,Java
From: https://www.cnblogs.com/apachecn/p/18131222

相关文章

  • Java 中文官方教程 2022 版(十六)
    原文:docs.oracle.com/javase/tutorial/reallybigindex.html如何使用编辑窗格和文本窗格原文:docs.oracle.com/javase/tutorial/uiswing/components/editorpane.html两个Swing类支持样式文本:JEditorPane及其子类JTextPane。JEditorPane类是Swing样式文本组件的基础,并提供......
  • Java 中文官方教程 2022 版(十七)
    原文:docs.oracle.com/javase/tutorial/reallybigindex.html如何使用菜单原文:docs.oracle.com/javase/tutorial/uiswing/components/menu.html菜单提供了一种节省空间的方式,让用户从几个选项中选择一个。用户可以使用其他组件进行一对多选择,包括组合框、列表、单选按钮、微......
  • MySQL数据库下载及安装教程
    MySQL数据库下载及安装教程(最最新版)一、下载mysql数据库二、安装Mysql三、验证是否安装成功(一)、命令提示符cmd窗口验证(二)、MySQL控制台验证一、下载mysql数据库进入MySQL官方网站(https://www.mysql.com/downloads/),按下图顺序点击进入下载页面。 注意:这里MSIInstal......
  • .NET Emit 入门教程:第六部分:IL 指令:7:详解 ILGenerator 指令方法:分支条件指令
    前言:经过前面几篇的学习,我们了解到指令的大概分类,如:参数加载指令,该加载指令以 Ld开头,将参数加载到栈中,以便于后续执行操作命令。参数存储指令,其指令以St开头,将栈中的数据,存储到指定的变量中,以方便后续使用。创建实例指令,其指令以New开头,用于在运行时动态生成并初始化对......
  • Java 中文官方教程 2022 版(十八)
    原文:docs.oracle.com/javase/tutorial/reallybigindex.html如何使用旋转器原文:docs.oracle.com/javase/tutorial/uiswing/components/spinner.html旋转器类似于组合框和列表,允许用户从一系列值中选择。与可编辑的组合框类似,旋转器允许用户输入值。与组合框不同,旋转器没有可......
  • Java 中文官方教程 2022 版(十三)
    原文:docs.oracle.com/javase/tutorial/reallybigindex.html部署JavaWebStart应用程序原文:docs.oracle.com/javase/tutorial/deployment/deploymentInDepth/createWebStartLaunchButtonFunction.html您可以使用部署工具包脚本的createWebStartLaunchButton函数部署Java......
  • 2023蓝桥杯 java A组 小蓝的旅行计划
    最小堆(优先队列)和区间树(线段树,红黑树)的结合java中有自己实现这两种数据结构的对象(1)最小堆(优先队列)PriorityQueue<int[]>minHeap=newPriorityQueue<>(newComparator<int[]>(){//int[]三个元素第一个cost第二个lim第三个tag @Override publicintcompare(int......
  • Java 中文官方教程 2022 版(十四)
    原文:docs.oracle.com/javase/tutorial/reallybigindex.html设置包版本信息原文:docs.oracle.com/javase/tutorial/deployment/jar/packageman.html您可能需要在JAR文件的MANIFEST.MF中包含包版本信息。您可以使用MANIFEST.MF中的以下头部提供此信息:清单中的头部......
  • Java 中文官方教程 2022 版(五)
    原文:docs.oracle.com/javase/tutorial/reallybigindex.html多态性原文:docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html多态性的词典定义指的是生物学中的一个原则,即一个生物体或物种可以具有许多不同的形式或阶段。这个原则也可以应用于面向对象编程和像Ja......
  • 【软件】Charles激活码计算器(Go & Java)
    ✨Charleshttps://www.charlesproxy.com/✨在线激活https://www.zzzmode.com/mytools/charles/✨激活码计算器(Go)在线激活的地址中提供了激活码计算器的代码防止在线激活跑路特此保存packagemainimport( "bytes" "encoding/binary" "fmt" "math/rand" "ti......