IFrame 跟上潮流
简介: IFrame 是一种应用程序窗口体系结构,它可以有自定义颜、自定义边框、自定义形状、自定义组件、甚至透明性。有了 JFrame,就不需要在应用程序中总是使用乏味的、老的 JFram 了。在本文中,IT 专家 Michael Aberethy 介绍了 IFrame 类,并展示了如何用它将标准 JFrame 应用程序窗口立刻转换为先进的 IFrame。
Java 1.0 开始,UI 开发人员就一直在寻自定义应用程序窗口的方法。在引入了 Swing 后,这个问题愈发突出了,因为开发人员可以创建具有令人惊叹的更复杂的、更高级 widget,但是却受到它所在的 Frame 或者 JFrame 和它们的特定于操作系统的外观的限制。常常可以看到应用程序在框架边框内部看起来很好,但是 Microsoft Windows 的蓝标题栏却大刹风景的情况。更糟的是,应用程序有 70 年代的 Motif 外观,但却使用了 Microsoft Windows 的颜光滑渐变的标题栏。
JFrame 的外观问题
如图 1 所示的这些外观问题,展现了 UI 开发人员所面临的许多问题:应用程序在各个平台
上看起来是不一样的,因为 JFrame 的属性(标题栏颜、边框、形状等)无法使用公共外观,它们是特于定操作系统的。

1. JFrame 的外观是如何变化的
Metal 外观
Motif 外观
Windows 外观
解决方案看起来很很明显:一个独立于操作系统的框架,它具有 JFrame 提供的所有功能——注册到 OS 窗口管理器、调整大小 / 重绘管理、最大化 / 最小化 / 恢复,同时又可以设置这些组件的外观。Java 1.3 提供了 JFrame 的功能,但牺牲了定制能力。
Java 1.4 中,Sun Frmae 类中引入了一个新的 setUndecorated()函数,它走到了另
一个极端——它可以自定义框架中的所有内容,但是缺少了 Java 1.3 中大多数特定于操作的好处。
IFrame 类是对这个问题的期待已久的解决方案。通过弥合这两个问题之间的距离,IFrame 提供了一个使用简单、同时又很强大的解决方案,可以根据需要对框架进行或多或少的自定义,同时不会牺牲使用 JFrame 时所习惯的任何特定于操作系统的功能。不用再守着同样的陈旧的蓝标题栏、同样的陈旧的三个窗口按钮和同样的陈旧的斜面边框。虽然对于普通应用程序来说,JFrame 仍然很有用,但是有些应用程序需要比它所能提供的更多的功能,如:
所有具有自定义外观的应用程序。
所有用于体现公司的某种品牌形象的应用程序。
所有需要对其窗口具有更多控制的应用程序。
IFrame 通过提供一个容易使用的 API 而突破了 JFrame 的限制,这个 API 可以生成具有任何状态的框架、可以有任何颜和状态的标题栏、可用于更多功能的标题栏按钮、具有
任何颜和大小的边框、按钮旁边的组件和标题栏中的标签及甚至是透明性。
本文介绍 IFrame 框架。首先描绘这个体系结构中的每一个类及其作用。当然,学习如何使用 IFrame 的最好方法是使用例子,所以我举了四个使用 IFrame 的应用程序的例子,它们具有不同的复杂性。阅读了本文及学习 IFrame 体系结构后,应当能够让应用程序窗口从乏味窗口(图 2)变为炫目窗口(图 3)。

2. 使用 IFrame 之前

3. 使用 IFrame 之后
IFrame 体系结构
IFrame 体系结构非常容易和直观,这可以从图 4 展示的类图中看出来。用于作为应用程序
窗口的主类是 IFrameIFrame 包含类 IBorderPanel的一个到多个实例,这个类的子类包括 IWindowTitleBar IContentPane IBorderPanels通过触发 WindowChangeEvents IFrame 通信,IFrame 对它进行处理并作出响应。
通过分析体系结构中每一个组件,就会清楚为了定制自己的 IFrame,需要在什么地方和什么时候改写默认功能。

4. IFrame 体系结构

IFrame
IFrame是用于创建自定义框架的主类。除了从 IFrame的父类改变button按钮的形状 JFrame 继承的方法外, IFrame还增加了几个 public 方法,可以用来改变 框架的基本外观组件。
IFrame 的默认行为与 JFrame 一样,所以 JFrame 和默认 IFrame 可以互换。不过,通过调用 IFrame 中可以使用的几个 public 方法,可以只用几行代码迅速改变窗口的外观。
注: JFrame 对应的 getContentPane() setContentPane() 的位置上应当使用 IFrame getIContentPane() setIContentPane() 方法。在 IFrame 中添加的所有组件都应当调用 IContentPane().add()。用 getContentPane() IFrame 中添加组件或者用 setContentPane() 设置内容窗格会导致不可预测的、并且很可能是错误的行为。
IBorderComponent
IBorderComponent是在 IFrame 中加入的所有可以控制 Windows 的位置和调整大小的 JPanel 的父类。乍看之下,最可能的子类是 IWindowTitleBar IContentPane,因为它们看起来是惟一进行调整大小和移动的类。不过在当前的应用程序中,有许多是用应用程序
窗口内的组件调整应用程序窗口大小或者移动它的。例如,所有 Microsoft Office 应用程序现在都在应用程序窗口右下角有一个小的 widget,可以用来调整大小(可以去自己试一试)。所以如果设计一个包含所有类型的调整大小和移动窗口的 widget,那么所要做的就是继承 IBorderComponent,这些 widget 就会具有与用 IWindowTitleBar IContentPane得到的同样的移动和调整大小的能力。
IWindowTitleBar
自定义框架的大部分工作都是在 IWindowTitleBar中进行的。与 IFrame 一样, IWindowTitleBar有许多 public 方法,不用继承它或者自己编写方法就可以改变标题栏的属性。虽然用这些方法可以容易地对外观进行改变,但是所有高级的设计都应当继承 IWindowTitleBar以使用 paintComponent(),这个方法可以做出更复杂的标题栏。(关于复杂的标题栏以及它是如何继承 IWindowTitleBar的内容,请参阅下面 3。)
除了改变标题栏的背景颜, IWindowTitleBar还提供了许多功能,可以用来控制标题栏中的 IWindowButtons。在默认情况下, IWindowTitleBar 包含 Microsoft Windows 应用程序中可以看到的三个标准窗口按钮,但是可以容易地删除它们或者添加自己的具有不同功能
的窗口按钮。可以改变按钮的大小和颜,如果创建高级的窗口按钮,那么可以继承 IWindowButton以绘制所希望的任何形状和颜方案(尽管改变 JButton 的外观超出了本文的范围)。
也许自定义 IWindowTitleBar的最有技巧性的方面是管理边框。在默认情况下,窗口标题栏是标准的矩形边框,但是如果创建一个具有非标准边框的复杂标题栏(请参阅 4),那么必须继承 IWindowTitleBar并覆盖 isMouseOnBorder() isInsideTitleBar(),以自己管理边框。
IContentPane
IContentPane提供了在其中加入所有应用程序组件的基本容器,很像 JFrame 中的 JFcontentPane。因为它也继承了 IBorderComponent,所以在默认情况下它也管理自己的边框。 IContentPane边框的默认实现也是矩形。要想得到非矩形的复杂边框,需要继承 IContentPane并通过 重载 isMouseOnBorder()自己处理边框。
IWindowButton
IWindowButton提供了出现在标准 Microsoft Windows JFrame 标题栏中的三个按钮(最小化、还原和关闭)的默认实现,但是它们还为想要在标题栏中创建和添加的所有自定义窗口按钮提供了基类。如果希望在标题栏中加入第四个按钮(如果认为自己比 Microsoft 更了解情况),那么可以继承 IWindowButton 重载 paintComponent()。不过,对于创建自定义按钮的介绍不在本文的范围之内。
WindowChangeEvent/WindowChangeListener
Swing 为窗口中会发生的几乎所有事情提供了事件。有大约 15 种事件和处理窗口事件的相应方法。但是,就算有了所有这些事件,Swing 也没有包括窗口可以生成的所有事件,最明显的是特定于操作系统的事件。最后,使用 WindowChangeEvent WindowChangeListener类,可以确保接收窗口会发生的 所有事件。
WindowChangeEvent处理所有窗口变化的情况(因而类的名字变化)。它可以改变其大小、在屏幕上定位、恢复状态或者最小化 / 最大化状态。将这五个事件加上 15 种已有的事件,就包括了所有基本情况。现在窗口中发生的所有事情都可以掌握了。
例子
现在可以编写几行代码并改变应用程序窗口的整个外观、亲自体验 IFrame 的强大功能了。记住,IFrame 可以很简单,也可以很复杂,完全取决于您的需要。
在这一节,我将完成几个展示开始使用 IFrame 所需要完成的基本步骤的例子。学习这些例子并在自己的计算机中运行它们,会看到仅凭阅读说明或者 API 所想像不到的效果。运行所有四个例子并分析每个例子的代码,我相信您将会理解为什么 IFrame 可以成为应用程序中一个强大的工具。
所有例子都包含在 com.amples包中,可以从 参考资料 www.ibm/developerworks/cn/java/j-iframe/#resources#resources中下载这个包,它们都有可以运行的 main()方法。它们是用 JDK 1.4 编写的。