7.2 创建一个Frame
一个顶层的窗体(也就是一个不包括在另一个窗体内的窗体)在Java中叫做一个frame;对于这个顶层窗体,AWT库中有一个类叫Frame。这个类的Swing版本叫做JFrame并且扩展了Frame类。
JFrame是为数不多的不在画布上画的Swing组件。因此,象按钮,标题栏,图标等装饰物是靠用户的窗口系统来画,而不是Swing.
注意:大多数Swing组件类以”J”开头:JButton,JFrame等。也有象Button,Fram这样的类,但他们是AWT组件。如果你不小心丢了个”J”,你的程序可能仍可以编译和运行,但Swing和AWT组件的混合会导致视觉和行为上的不一致。
在这一节中,我们将讨论使用一个Swing JFrame的最常用的方法。Example7-1列出了一个在屏幕上显示一个空frame的的简单程序。
Swing类在javax.swing包里。包的名字javax表明这不是一个核心包,而是一个Java扩展包。Swing类确实是java1.1的附加物。因为Swing类并不是作为核心层次的一部分,这使得加载Swing类到一个java1.1兼容的浏览器成为可能。(浏览器的安全管理器不允许加载任何以”java.”开头的包)。在java2平台上,Swing包不再只是一个附加物,而成为核心层次的一部分。任何与java2兼容的java实现都应该提供Swing类。然而,javax这个名字仍与java1.1代码兼容。(实际上,Swing包起初被独立出来成为com.sun.java.swing,后来杂java2早期的beta版里被基本上移到java.awt.swing,然后又在java2的后期beta版回到com.sun.java.swing在,最终,在java程序员的推动下,终于在Javax.swing找到它的位置)
默认地,一个frame有一个无用的0*0象素的大小。我们定义了一个子类SimpleFrame,它的构造函数设置size成300*200。在SimpleFrameTest类的main方法中,我们一开始构造了一个SimpleFrame对象。
接着,我们定义了当用户关闭这个frame时应该发生什么。在这个程序里,我们希望程序退出。我选择这个行为,我们使用了这句:frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
在其他有多个frames的程序里,你可能不想只因为用户关闭其中一个frame就退出程序。默认地,当用户关闭它时,一个frame隐藏自己,但程序并不终止。
简单地构造一个frame并不会自动显示它。Frames以不可见的姿态开始他们的生命周期。这在它第一次显示出来前给了程序员机会往frame里添加组件。为了显示frame,main方法调用了frame的setVisible方法。
最后,main方法终止。注意main()方法的终止并没有终止程序,而只是main线程。显示frame激活一个用户接口线程来保持程序仍活着。
注意:在jdk5.0以前,可以使用JFrame的继承自基类Window的show方法。Window类有一个基类Componet,它也有一个show方法。Component.show方法在jdk1.2里被禁止了。它希望你调用setVisible(true)而不是显示一个componet。然而,直到jdk1.4,Window.show方法也没有被禁止。实际上,它很有用,使得窗体可见并置于最前端。可悲的是,这个好处由于禁止政策而失去了。Jdk5.0禁止了window的show方法。
这个程序运行的结果只是一个枯燥的顶层窗体。标题栏以及旁边的修饰物例如最大小化按钮,是由操作系统而不是Swing库画出来的。如果你在X Windows上运行相同的程序,这些修饰物将不同。frame里面画所有的东西是由Swing库画的。在这个程序中,它只是用一个默认的背景色来填充frame.
注意:对于jdk1.4,你可以通过frame.setUndecorated(true)来隐藏这些修饰物。
注意:在前面我们写了两个类,一个定义了frame类,一个包含了用来创建和显示fram对象的main方法。你将会经常看到有些程序里main方法会融合进一个类中,例如:
从某种意义上来说在frame类中使用main方法来启动程序更简单。你不必引进另一个辅助类。然而,
很多程序员认为这种代码风格让人迷惑。因此,我们更愿意把定义用户接口的类和启动程序的类分离开。