【IT168 技术文章】为应用程序创建一个图形用户界面(graphical user interface(GUI))的过程需要多个开发者和设计师紧密配合以达成设定好的目标。即使在配合最严密的产品小组中,这个过程也经常因为缺乏共同语言而受到影响,这种情况会导致错误理解、基础的简单任务的重复和不理想的结果。
在本文中,我们会讨论设计师和开发者是怎样受益于在 GUI 开发中结合 Java 布局管理器的。Swing 类库包括几个布局管理器,从非常简单的 FlowLayout 管理器到更复杂和灵活的 GridBagLayout 管理器。从我们的经验看,使用布局管理器能够帮助我们在设计和开发过程中得到一致,因为每个布局管理器带来了一组独特的、定义好的设计可能性,开发小组很容易实现这些可能性。
我们会使用一个 GUI 示例,并采用从最简单到最复杂的形式,最简单的形式中 GUI 构建不使用任何布局管理器,最复杂的形式中会使用高级的布局管理器,用来管理控件、列和 GUI 窗口中多余空间的分配。在文章结尾时,您应该会很好地理解布局管理器可以怎样积极地影响 GUI 设计,从而影响 GUI 开发过程。
设计和开发过程
在典型的 GUI 设计和开发过程中,设计师负责创建一系列图形以表示 GUI 的每个屏幕。通常是在一张白色书写板或一张纸上绘出这些图形,然后在一个如 Photoshop 或 Visual Basic 的绘图工具中做成模型。设计师在界面中使用字体、颜色和控件的布局,直到他或她对结果满意为止。这个做成模型的 GUI 就变成交给开发者或开发小组的规范的一部分,他们的任务是实现设计师理想中的 GUI。
在很多情况下,设计师的模型给开发者或开发小组带来很多问题,原因通常是一系列错误的假定。我们首先会讨论这些常见的假定,然后看看 Java 布局管理器能够怎样帮助我们解决它们。
导致错误设计的常见假定情况
首先,设计师可能假定如按钮和标签的控件中包含的字符串文字在大小上一致。如果要向不同国家或地区的用户配置这个应用程序,那么用户可见的字符串就很可能被翻译成那个国家或地区的语言。如果(这是很可能的)翻译过后的字符串的长度和设计师指定的长度不同,较长的字符串就会被控件截断,较短的字符串就会在两头加上多余的空格。
第二,设计师可能假定控件整体窗口的大小。用户经常希望能调整窗口的大小,将窗口调大以使用更大的区域,或将窗口调小从而同时使用更多可见的应用程序窗口。在两种情况中,应该对 GUI 控件的位置和大小都进行调整,从而最好地利用新的空间。当窗口扩展时,虽然用户可能不会希望控件按钮(它包含固定的文字字符串)增大,他们可能希望一个元素(如列表或表)增大,从而显示更多的行和更宽的列。
第三,设计师可能假定原型机上控件的外观会扩展到每个最终用户的机器。Java 语言承诺实现的一件事就是跨平台兼容性。为了达到这一点,“Java 基础类”(Java Foundation Classes(JFC))提供了一套可以运行在不同平台和操作系统上的 GUI 控件。为实现基本的如按钮和文本框的控件,开发者可以依赖“抽象窗口工具包”(Abstract Window Toolkit(AWT))类库。AWT 让 Java 语言能够在每个系统上使用本地(或重量级)窗口小部件(widget),但它只能提供基本的用户界面体验。
对于将使用树列表、表、工具栏、带图形的按钮和其它复杂控件的应用程序,开发者就要转向 JFC 和 Swing 类库。Swing 通过创建画布和实际地建立每个带有低级绘图和鼠标 API 调用的控件实现可移植性。因为没有使用本地窗口小部件,这被称为 轻量级或 模拟窗口小部件工具包。每个控件的实际绘图延迟到一个被称为 外观和感觉的对象。外观和感觉尽力模仿本机控件的外观和特征,所以用户在从本机应用程序切换到 Java 应用程序时会感到有一点不同。
不同的外观和感觉对控件的定位和绘图有很大区别,所以在 Windows 外观和感觉中有同一种外观的 GUI 以 Motif 或 Macintosh 的外观和感觉运行时会有非常不同的外观。没有考虑到这一点而设计和开发的 GUI 在您的 Windows 原型中可能看起来不错,但运行在另一个操作系统(如 Linux 或 Macintosh)上可能看起来很差。
解决这些假定的问题
前三个假定可以通过以一种单独的语言,用不可调整大小的窗口和固定的外观和感觉发布应用程序来避免。然而,显示设置提出的完全是另外一个问题。在部署应用程序的机器上,这些设置和原型机上的设置不一样。例如,用户可以在整个系统设置字体和字体大小以适合他(或她)的可访问性首选项。在这种情况下,用户可见字符串的长短和接收输入(如文本框)的控件会和设计时的不一样。
控件、窗口和字体根据系统的不同而改变,所以您在建立 GUI 时应该牢记这些变量,并根据它们对其作巧妙的调整。Web 应用程序设计师和开发者必须使用的最重要的概念是可流动性。以静态的模型设计 Java GUI 将弄巧成拙;相反,您必须在一个框架中工作,控件的位置和大小由很多变换的变量来管理。
在下面的几节中,我们会使用一个包括一个窗口和几个控件的简单的 GUI。我们会从一个不使用布局管理器的 GUI 设计开始。
不使用布局管理器操作控件
一个 GUI 包括一个有很多控件的顶层窗口。每个控件是一个 Java 类( java.awt.Component 的一个子类)的一个实例。控件的示例有文本框、标签、按钮和列表。最外层的控件,即有标题条和最小化和最大化按钮的控件,是 java.awt.Window 的一个子类。每一个控件都通过给定一个既包括长和宽,又包括 x 和 y 位置的长方形来定位。除了 Window 本身,每个控件有一个父控件。
图 1 展示了我们在本文中要一直使用的 GUI 的最初形式。
图 1. 一个简单的 GUI

清单 1 中是创建图 1 所示窗口的代码。第一行是创建 Frame ,它是最外面窗口要使用的类。下面一行将 frame 的布局管理器设置为空。因为我们没有使用布局管理器,所以控件必须在 frame 内给自己定位。接下来,创建两个按钮并将其添加到 frame,给定其位置和大小。这里的 x 和 y 位置分别是 10,30 和 70,30。座标 x 从左到右,座标 y 从上到下。
清单 1. 有两个按钮的简单 GUI
2 frame.setLayout(null);
3 frame.setBounds(100,100,150,70);
4 Button button1 = new Button("Next");
5 frame.add(button1);
6 button1.setBounds(10,30,50,25);
7 Button button2 = new Button("Previous");
8 frame.add(button2);
9 button2.setBounds(70,30,50,25);
10 frame.setVisible(true);
11
固定座标的问题
根据绝对座标对控件定位(称为 绝对定位)的代码的问题是:标签内的字符串可能被翻译成另一种语言,或者用户可能调整了窗口的大小。在两种情况下,按钮都会保持固定在它们最初的位置。图 2 展示了结果,您可以看到当把 GUI 从英语翻译成法语时会发生什么,还有当用户调整窗口大小时会发生什么。
图 2 在简单 GUI 中使用固定坐标的结果

为了解决这个问题,我们将使用最简单的布局管理器 ― 流程布局管理器。