文档

Java™教程
隐藏目录
如何制作框架(主窗口)
路径:使用Swing创建GUI
课程:使用Swing组件
章节:如何使用不同的组件

如何创建框架(主窗口)

Frame(框架)是一个顶层窗口,具有标题和边框。框架的大小包括为边框指定的任何区域。可以使用getInsets方法获取边框区域的尺寸。由于边框区域包括在框架的整体大小中,边框实际上遮挡了框架的一部分,限制了可用于渲染和/或显示子组件的区域,该区域为矩形,其左上角位置为(insets.left, insets.top),大小为width - (insets.left + insets.right)height - (insets.top + insets.bottom)

框架是使用JFrame类实现的窗口,它具有边框、标题和支持关闭或最小化窗口的按钮组件。具有GUI的应用程序通常包含至少一个框架。Applet有时也会使用框架。

要创建一个依赖于另一个窗口的窗口(例如,在另一个窗口最小化时消失),请使用dialog而不是frame。要在另一个窗口内显示一个窗口,请使用内部框架

创建和显示框架

下面是FrameDemo演示应用程序创建的非常简单的窗口的图片。你可以在FrameDemo.java中找到源代码。你可以运行FrameDemo下载JDK 7或更高版本)。

一个非常无聊的框架

以下FrameDemo代码显示了如何创建和设置一个框架。


//1. 创建框架。
JFrame frame = new JFrame("FrameDemo");

//2. 可选:在框架关闭时发生什么?
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//3. 创建组件并将它们放入框架中。
//...创建 emptyLabel...
frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);

//4. 调整框架的大小。
frame.pack();

//5. 显示框架。
frame.setVisible(true);

以下是关于代码的一些详细信息:

  1. 代码的第一行使用一个允许你设置窗体标题的构造函数创建了一个窗体。另一个常用的JFrame构造函数是无参数构造函数。
  2. 接下来的代码指定了当用户关闭窗体时发生的情况。 EXIT_ON_CLOSE操作在用户关闭窗体时退出程序。这种行为对于这个程序是适当的,因为程序只有一个窗体,关闭窗体会使程序无用。

    有关更多信息,请参见响应窗口关闭事件

  3. 代码的下一部分向窗体的内容面板添加了一个空标签。如果您对内容面板以及如何向其添加组件还不熟悉,请阅读向内容面板添加组件

    对于具有菜单的窗体,通常会使用setJMenuBar方法在此处添加菜单栏。有关详细信息,请参见如何使用菜单

  4. pack方法调整窗体的大小,使其所有内容都处于其首选大小或更大。一个替代pack的方法是通过调用setSizesetBounds(它还设置了窗体的位置)来明确地设置窗体大小。一般来说,使用pack优于调用setSize,因为pack将窗体的布局管理器设置为窗体大小,并且布局管理器很擅长调整以适应影响组件大小的平台依赖性和其他因素。

    此示例未设置窗体位置,但可以使用setLocationRelativeTosetLocation方法很容易地设置位置。例如,以下代码将窗体居中显示:

    frame.setLocationRelativeTo(null);
    
  5. 调用setVisible(true)使窗体显示在屏幕上。有时可能会看到使用show方法。这两种用法是等效的,但为了一致性起见,我们使用setVisible(true)

指定窗口装饰

默认情况下,窗口装饰由本机窗口系统提供。但是,您可以请求外观和感觉为窗体提供装饰。您还可以指定窗体根本没有窗口装饰,这是一个可以单独使用的功能,或者用于提供您自己的装饰,或者与全屏独占模式一起使用。

除了指定提供窗口装饰的对象之外,您还可以指定用于表示窗口的图标。此图标的使用方式取决于提供窗口装饰的窗口系统或外观。如果窗口系统支持最小化,那么该图标将用于表示最小化的窗口。大多数窗口系统或外观还会在窗口装饰中显示该图标。一个典型的图标大小为16x16像素,但某些窗口系统使用其他尺寸。

下面的快照显示了三个外观完全相同的窗口,除了它们的窗口装饰不同。通过每个窗口中按钮的外观,您可以看出它们都使用了Java外观。第一个使用的是窗口系统提供的装饰,恰好是Microsoft Windows,但也可以是任何其他运行Java平台的系统。第二个和第三个使用的是Java外观提供的窗口装饰。第三个窗口使用了Java外观的窗口装饰,但具有自定义图标。

由窗口系统提供的窗口装饰的窗口 由外观提供的窗口装饰的窗口 具有自定义图标的窗口
由外观提供的窗口装饰 由窗口系统提供的窗口装饰 自定义图标;由外观提供的窗口装饰

下面是一个创建具有自定义图标和由外观提供的窗口装饰的窗口的示例:

//请求由外观提供的窗口装饰。
JFrame.setDefaultLookAndFeelDecorated(true);

//创建窗口。
JFrame frame = new JFrame("一个窗口");

//将窗口图标设置为从文件加载的图像。
frame.setIconImage(new ImageIcon(imgURL).getImage());

如前面的代码片段所示,您必须在创建希望影响其装饰的窗口之前调用setDefaultLookAndFeelDecorated方法。您使用setDefaultLookAndFeelDecorated设置的值将用于所有随后创建的JFrame。您可以通过调用JFrame.setDefaultLookAndFeelDecorated(false)切换回使用窗口系统装饰。某些外观可能不支持窗口装饰;在这种情况下,将使用窗口系统的装饰。

上述示例中创建的窗口的完整源代码在FrameDemo2.java中。除了显示如何选择窗口装饰,FrameDemo2还展示了如何禁用所有窗口装饰,并给出了一个定位窗口的示例。它包括两个方法,用于创建用作图标的Image对象 - 一个是从文件加载的,另一个是从头绘制的。


试一试: 
  1. 点击“启动”按钮,使用Java™ Web Start下载JDK 7或更高版本)来运行Frame Demo。或者,如果您想要自己编译和运行示例,请参考示例索引启动FrameDemo2示例

  2. 打开两个窗口,都使用外观提供的装饰,但使用不同的图标。
    Java外观会在其窗口装饰中显示图标。根据您的窗口系统,在窗口最小化时,该图标可能用于代表窗口的其他位置。
  3. 打开一个或多个具有窗口系统装饰的窗口。
    查看您的窗口系统是否以不同的方式处理这些图标。
  4. 打开一个或多个没有窗口装饰的窗口。
    尝试不同类型的窗口,看看窗口装饰、窗口系统和框架图标如何交互。

响应窗口关闭事件

默认情况下,当用户关闭屏幕上的框架时,框架会被隐藏。虽然是不可见的,但框架仍然存在,程序可以再次将其显示出来。如果您希望有不同的行为,那么您需要注册一个处理窗口关闭事件的窗口监听器,或者使用setDefaultCloseOperation方法指定默认的关闭行为。您甚至可以两者都使用。

setDefaultCloseOperation的参数必须是以下值之一,前三个值在WindowConstants接口中定义(由JFrameJInternalPaneJDialog实现):

DO_NOTHING_ON_CLOSE
当用户请求关闭窗口时不执行任何操作。相反,程序应该使用一个窗口监听器,在其windowClosing方法中执行其他操作。
HIDE_ON_CLOSEJDialogJFrame的默认值)
关闭窗口时隐藏窗口。这会将窗口从屏幕上移除,但仍然可以显示。
DISPOSE_ON_CLOSEJInternalFrame的默认值)
关闭窗口时隐藏并释放窗口。这会将窗口从屏幕上移除,并释放其使用的任何资源。
EXIT_ON_CLOSE(在JFrame类中定义)
退出应用程序,使用System.exit(0)。这仅适用于应用程序。如果在小程序中使用,可能会抛出SecurityException


注意: 

DISPOSE_ON_CLOSE 如果只有一个窗口在屏幕上,则可能与 EXIT_ON_CLOSE 有相似的结果。更具体地说,当 Java 虚拟机 (VM) 中的最后一个可显示窗口被关闭时,VM 可能会终止。有关详细信息,请参见AWT 线程问题


默认的关闭操作在任何窗口监听器处理窗口关闭事件之后执行。所以,例如,假设您指定默认的关闭操作是销毁一个框架。您还实现了一个窗口监听器,用于测试该框架是否是最后一个可见的,如果是,则保存一些数据并退出应用程序。在这些条件下,当用户关闭一个框架时,窗口监听器将首先被调用。如果它没有退出应用程序,那么默认的关闭操作 - 销毁框架 - 将会被执行。

有关处理窗口关闭事件的更多信息,请参见如何编写窗口监听器。除了处理窗口关闭事件外,窗口监听器还可以对其他窗口状态更改做出反应,例如图标化和激活。

Frame API

以下表列出了常用的 JFrame 构造方法和方法。您可能想要调用的其他方法由 java.awt.Framejava.awt.Windowjava.awt.Component 类定义,JFrame 是它们的子类。

因为每个 JFrame 对象都有一个根面板,所以框架支持在框架子组件前面插入输入和绘制行为,将子组件放置在不同的“层”上,并支持 Swing 菜单栏。这些主题在 使用顶级容器 中介绍,并在 如何使用根面板 中详细解释。

使用框架的 API 分为以下几类:

创建和设置框架JFrame()
JFrame(String)void setDefaultCloseOperation(int)
int getDefaultCloseOperation() WindowConstantsJFrameEXIT_ON_CLOSEJFramevoid setIconImage(Image)
Image getIconImage()
(在Frame中)java.awt.Imagejavax.swing.ImageIconjavax.swing.Iconvoid setTitle(String)
String getTitle()
(在Frame中)void setUndecorated(boolean)
boolean isUndecorated()
(在Frame中)全屏独占模式static void setDefaultLookAndFeelDecorated(boolean)
static boolean isDefaultLookAndFeelDecorated()JFrame
设置窗口大小和位置
方法 目的
void pack()
(在Window中)
调整窗口大小,以使其所有内容的大小都至少达到其首选大小。
void setSize(int, int)
void setSize(Dimension)
Dimension getSize()
(在Component中)
设置或获取窗口的总大小。setSize方法的整数参数分别指定宽度和高度。
void setBounds(int, int, int, int)
void setBounds(Rectangle)
Rectangle getBounds()
(在Component中)
设置或获取窗口的大小和位置。对于setBounds方法的整数版本,窗口的左上角位于第一个和第二个参数指定的x, y位置,并具有由最后两个参数指定的宽度和高度。
void setLocation(int, int)
Point getLocation()
(在Component中)
设置或获取窗口左上角的位置。参数分别为xy值。
void setLocationRelativeTo(Component)
(在Window中)
将窗口定位在指定组件的中心。如果参数为null,则窗口将居中显示在屏幕上。要正确居中窗口,应在设置窗口大小后调用此方法。
与根窗格相关的方法
方法 用途
void setContentPane(Container)
Container getContentPane()
设置或获取窗体内容面板。内容面板包含窗体内可见的GUI组件。
JRootPane createRootPane()
void setRootPane(JRootPane)
JRootPane getRootPane()
创建、设置或获取窗体根窗格。根窗格管理窗体的内部,包括内容面板、玻璃窗格等。
void setJMenuBar(JMenuBar)
JMenuBar getJMenuBar()
设置或获取窗体菜单栏,用于管理窗体的一组菜单。
void setGlassPane(Component)
Component getGlassPane()
设置或获取窗体玻璃窗格。您可以使用玻璃窗格来拦截鼠标事件或在程序GUI上绘制。
void setLayeredPane(JLayeredPane)
JLayeredPane getLayeredPane()
设置或获取窗体分层窗格。您可以使用分层窗格将组件放置在其他组件的上方或下方。

使用框架的示例

本教程中的所有独立应用程序都使用JFrame。下表列出了一些示例,并告诉您每个示例在哪里讨论。

示例 描述位置 备注
FrameDemo 示例解释 显示一个带有一个组件的基本框架。
FrameDemo2 指定窗口装饰 允许您创建具有不同窗口装饰的框架。
Framework 探讨了创建和销毁窗口、实现菜单栏以及退出应用程序的内容。
LayeredPaneDemo 如何使用分层窗格 演示了如何使用分层窗格(但不包括框架分层窗格)。
GlassPaneDemo 玻璃面板 演示了使用框架玻璃面板的用法。
MenuDemo 如何使用菜单 展示了如何将JMenuBar放入JFrame中。

上一页: 如何使用格式化文本字段
下一页: 如何使用内部框架