使用顶层容器

如前所述,Swing 提供了三个通常有用的顶级容器类:JFrameJDialogJApplet。使用这些类时,应牢记以下事实:

  • 要在屏幕上显示,每个 GUI 组件必须是*“包含层次结构” *的一部分。包含层次结构是一棵以顶级容器为根的组件树。我们将向您展示一下。

  • 每个 GUI 组件只能包含一次。如果某个组件已经在容器中,并且您try将其添加到另一个容器中,则该组件将从第一个容器中删除,然后添加到第二个容器中。

  • 每个顶级容器都有一个内容窗格,通常来说,该窗格包含(直接或间接)该顶级容器的 GUI 中的可见组件。

  • 您可以选择将菜单栏添加到顶级容器。按照惯例,菜单栏位于顶级容器内,但位于内容窗格之外。某些外观(例如 Mac OS 外观)使您可以选择将菜单栏放置在更适合外观的其他位置(例如屏幕顶部)。

Note:

尽管JInternalFrame模仿JFrame,但是内部框架实际上并不是顶级容器。

这是应用程序创建的框架的图片。该框架包含一个绿色的菜单栏(无菜单),并且在框架的内容窗格中包含一个大的空白,黄色标签。

一个带有框架的简单应用程序,该框架包含菜单栏和内容窗格。框架主要部分示意图

您可以在TopLevelDemo.java中找到此示例的整个源。尽管该示例在独立应用程序中使用JFrame,但相同的概念适用于JAppletJDialog

这是此示例的 GUI 的包含层次结构:

TopLeveDemo 示例的 GUI 的包含层次结构。

就像椭圆所暗示的那样,我们在此图中省略了一些细节。稍后我们将揭示缺失的细节。以下是本节讨论的主题:

顶级容器和包含层次结构

每个使用 Swing 组件的程序都至少具有一个顶级容器。此顶级容器是包含层次结构的根-该层次结构包含出现在顶级容器内的所有 Swing 组件。

通常,具有基于 Swing 的 GUI 的独立应用程序至少具有一个以JFrame为根的包含层次结构。例如,如果一个应用程序具有一个主窗口和两个对话框,则该应用程序将具有三个包含层次结构,并因此具有三个顶级容器。一个包含层次结构以JFrame作为其根,其他两个包含层次结构的JDialog对象作为其根。

基于 Swing 的 applet 至少具有一个包含层次结构,而其中一个正是由JApplet对象作为根。例如,弹出对话框的 Servlets 具有两个包含层次结构。浏览器窗口中的组件位于以JApplet对象为根的包含层次结构中。该对话框具有以JDialog对象为根的容纳层次结构。

将组件添加到内容窗格

这是前面的示例用于获取框架内容窗格并将黄色标签添加到其中的代码:

frame.getContentPane().add(yellowLabel, BorderLayout.CENTER);

如代码所示,您可以通过调用getContentPane方法找到顶级容器的内容窗格。默认的内容窗格是一个简单的中间容器,它继承自JComponent,并使用BorderLayout作为其布局 管理 器。

自定义内容窗格很容易-例如,设置布局 管理 器或添加边框。但是,这里只有一个小陷阱。 getContentPane方法返回Container对象,而不是JComponent对象。这意味着,如果要利用内容窗格的JComponent功能,则需要强制转换返回值或创建自己的组件作为内容窗格。我们的示例通常采用第二种方法,因为它更干净一些。我们有时采取的另一种方法是简单地将自定义组件添加到内容窗格,以完全覆盖内容窗格。

请注意,JPanel的默认布局 管理 器是FlowLayout;您可能需要更改它。

要使组件成为内容窗格,请使用顶级容器的setContentPane方法。例如:

//Create a panel and add components to it.
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setBorder(someBorder);
contentPane.add(someComponent, BorderLayout.CENTER);
contentPane.add(anotherComponent, BorderLayout.PAGE_END);

      
topLevelContainer.setContentPane(contentPane);

Note:

为方便起见,已将add方法及其变体removesetLayout重写为必要时转发到contentPane。这意味着你可以写

frame.add(child);

并且孩子将被添加到contentPane.

请注意,只有这三种方法可以执行此操作。这意味着getLayout()将不会返回setLayout()设置的布局。

添加菜单栏

从理论上讲,所有顶级容器都可以容纳菜单栏。但是,实际上,菜单栏通常仅出现在框架和 Servlets 中。要将菜单栏添加到顶层容器,请创建一个JMenuBar对象,并在其中填充菜单,然后调用setJMenuBarTopLevelDemo使用以下代码将菜单栏添加到其框架:

frame.setJMenuBar(greenMenuBar);

有关实现菜单和菜单栏的更多信息,请参见如何使用菜单

根窗格

每个顶级容器都依赖于一个称为* root pane *的隐式中间容器。根窗格 管理 内容窗格和菜单栏,以及其他几个容器。通常,您不需要了解根窗格即可使用 Swing 组件。但是,如果您需要拦截鼠标单击或绘制多个组件,则应该熟悉根窗格。

这是根窗格提供给框架(以及其他所有顶层容器)的组件的列表:

根窗格 管理 其他四个窗格:分层窗格,菜单栏,内容窗格和玻璃窗格。

我们已经告诉您有关内容窗格和可选菜单栏的信息。根窗格添加的其他两个组件是分层窗格和玻璃窗格。分层窗格包含菜单栏和内容窗格,并允许对其他组件进行 Z 排序。玻璃窗格通常用于拦截发生在顶级容器上的 Importing 事件,也可以用于在多个组件上绘制。

有关更多详细信息,请参见如何使用根窗格