在Java中,顶层窗口(就是没有包含在其他窗口中的窗口)被称为框架(frame)。在AWT库中有一个称为Frame的类,用于描述顶层窗口。这个类的Swing版本名为JFrame,它扩展于Frame类。JFrame是极少数几个不绘制在画布上的Swing组件之一。因此,它的修饰部件(按钮、标题栏、图标等)由用户的窗口系统绘制,而不是由Swing绘制。
警告:绝大多数Swing组件类都以“J”开头,例如,JButton、JFrame等。在Java中有Button和Frame这样的类,但它们属于AWT组件。如果偶然地忘记书写“J”,程序仍然可以进行编译和运行,但是将Swing和AWT组件混合在一起使用将会导致视觉和行为的不一致。
在本节中,将介绍有关Swing的JFrame的常用方法。程序清单1给出了一个在屏幕中显示一个空框架的简单程序,如图1所示。
图1最简单的可见框架
程序清单1simpleframe/SimpleFrameTest.java
下面逐行地讲解一下这个程序。
Swing类位于javax.swing包中。包名javax表示这是一个Java扩展包,而不是核心包。出于历史原因Swing类被认为是一个扩展。不过从1.2版本开始,在每个JavaSE实现中都包含它。
在默认情况下,框架的大小为0×0像素,这种框架没有什么实际意义。这里定义了一个子类SimpleFrame,它的构造器将框架大小设置为×像素。这是SimpleFrame和JFrame之间唯一的差别。
在SimpleFrameTest类的main方法中,我们构造了一个SimpleFrame对象使它可见。
在每个Swing程序中,有两个技术问题需要强调。
首先,所有的Swing组件必须由事件分派线程(eventdispatchthread)进行配置,线程将鼠标点击和按键控制转移到用户接口组件。下面的代码片断是事件分派线程中的执行代码:
这一内容将在后续详细讨论。现在,只需要简单地将其看作启动一个Swing程序的神奇代码即可。
注释:许多Swing程序并没有在事件分派线程中初始化用户界面。在主线程中完成初始化是通常采用的方式。遗憾的是,由于Swing组件十分复杂,JDK的程序员无法保证这种方式的安全性。虽然发生错误的概率非常小,但任何人不愿意成为遭遇这个问题的不幸者之一。即使代码看起来有些神秘,也最好能够保证其正确性。
接下来,定义一个用户关闭这个框架时的响应动作。对于这个程序而言,只让程序简单地退出即可。选择这个响应动作的语句是
在包含多个框架的程序中,不能在用户关闭其中的一个框架时就让程序退出。在默认情况下,用户关闭窗口时只是将框架隐藏起来,而程序并没有终止(在最后一个框架不可见之后,程序再终止,这样处理比较合适,而Swing却不是这样工作的)。
简单地构造框架是不会自动地显示出来的,框架起初是不可见的。这就给程序员了一个机会,可以在框架第一次显示之前往其中添加组件。为了显示框架,main方法需要调用框架的setVisible方法。
注释:在JavaSE5.0以前的版本中,可以使用JFrame类从超类Window继承show方法。Window类的超类是Component,其中也有一个show方法。在JavaSE1.2中不提倡使用Component.show。如果想要显示一个组件,建议调用setVisible(true)。然而,JavaSE1.4以前的版本,并没有反对使用Window.show方法。事实上,这个方法很实用,它可以让窗口可见,且置于其他窗口的前面。遗憾的是,由于不提倡使用它,随之也失去了这一好处,JavaSE5.0也不赞成使用show显示窗口。
在初始化语句结束后,main方法退出。需要注意,退出main并没有终止程序,终止的只是主线程。事件分派线程保持程序处于激活状态,直到关闭框架或调用System.exit方法终止程序。
图1中显示的是运行程序清单1的结果,它只是一个很枯燥的顶层窗口。
在这个图中看到的标题栏和外框装饰(比如,重置窗口大小的拐角)都是由操作系统绘制的,而不是Swing库。在Windows、GTK或Mac下运行同样的程序,将会得到不同的框架装饰。Swing库负责绘制框架内的所有内容。在这个程序中,只用默认的背景色填充了框架。
注释:可以调用frame.setUndecorated(true)关闭所有框架装饰。