JavaGUI编程:从坐标系统到顶级容器的全面指南
立即解锁
发布时间: 2025-08-21 00:56:25 阅读量: 3 订阅数: 12 


Java编程艺术:从初学者到大师的进阶指南
### Java GUI编程:从坐标系统到顶级容器的全面指南
#### 1. GUI的数学基础:坐标系统
创建GUI本质上是一种创造错觉的艺术。当我们用鼠标按下窗口中的按钮看到它“凹陷”,说一个窗口因为“在前面”而遮挡了另一个窗口的部分,或者说一个图标“透明”因为能看到它“后面”的内容时,我们都在欣然接受这种错觉。屏幕上的GUI元素看似真实可触,我们很难不把它们当作“对象”,但实际上它们不过是计算机屏幕画布上的像素坐标和颜色。
计算机屏幕可以看作是一个二维笛卡尔坐标系,有水平的x轴和垂直的y轴。原点 (x = 0, y = 0) 位于屏幕的左上角。距离以像素为单位测量,x轴坐标向右递增,y轴坐标向下递增,这与我们在代数课上学到的有所不同,但对于逐像素绘制屏幕的计算机来说是自然的,就像我们看书一样,从左到右、从上到下。
下面是标准数学坐标系和计算机屏幕坐标系的对比:
| 坐标系类型 | 原点位置 | x轴正方向 | y轴正方向 |
| ---- | ---- | ---- | ---- |
| 标准数学坐标系 | 通常在中心 | 向右 | 向上 |
| 计算机屏幕坐标系 | 左上角 | 向右 | 向下 |
为了更直观地说明差异,方程 y = x + 5 在两种坐标系中的图形如下:
- 标准代数坐标系
- 标准计算机屏幕坐标系
#### 2. 组件及其边界
GUI组件(如窗口和按钮)通常占据矩形区域,因此它们的确切大小和位置可以由其左上角的x和y坐标、宽度和高度来确定。这四个值共同定义了组件的边界。就像计算机屏幕有坐标系一样,所有GUI组件也都有自己的坐标系。每个组件都将其左上角视为本地原点,x坐标向右递增,y坐标向下递增。组件的边界总是相对于其容器的坐标系来表示。
例如,一个窗口的边界为 x = 100, y = 275, 宽度 = 600, 高度 = 350,其边界是屏幕坐标,因为屏幕包含该窗口。而窗口内的“Click Me”按钮,其边界为 x = 125, y = 125, 宽度 = 300, 高度 = 100,其边界是窗口坐标,因为窗口包含该按钮。
#### 3. 顶级容器
为了使应用程序具有GUI,它至少必须有一个在计算机屏幕上可见的窗口。大多数应用程序都在窗口的范围内运行。不同应用程序和平台的窗口外观可能有所不同,但它们基本上都是屏幕上的一个矩形区域,用于显示程序输出并接受用户输入。
在Java中,所有类型的窗口都是 `java.awt.Window` 的实例或子类。组件是 `java.awt.Component` 的实例或子类,在屏幕上有可见表示,可能会也可能不会响应用户输入,如按钮、复选框和文本区域。容器是 `java.awt.Container` 的实例或子类,它只是一个可以“包含”其他组件的组件。因此,窗口既是组件(因为有可见表示),又是容器(因为可以包含其他组件)。窗口是顶级容器,因为它直接位于用户的桌面上,不能被其他容器包含。
AWT提供了三种类型的窗口:`Window`、`Frame` 和 `Dialog`。Swing提供了 `JWindow`、`JFrame` 和 `JDialog`,它们分别继承自对应的AWT类,其层次结构如下:
```mermaid
graph TD;
java.lang.Object --> java.awt.Component;
java.awt.Component --> java.awt.Container;
java.awt.Container --> java.awt.Window;
java.awt.Window --> javax.swing.JWindow;
java.awt.Window --> java.awt.Frame;
java.awt.Frame --> javax.swing.JFrame;
java.awt.Window --> java.awt.Dialog;
java.awt.Dialog --> javax.swing.JDialog;
```
#### 4. 不同类型的顶级容器
- **Window和JWindow**:`Window` 是没有边框和菜单栏的顶级容器,本身只是一个填充了默认背景颜色、供应用程序使用的矩形屏幕区域。`java.awt.Window` 是所有顶级容器的根类。`JWindow` 是 `Window` 的Swing版本,外观看似简单,除了其他未提及的组件外,它包含一个名为内容面板的容器,负责管理应用程序特定的内容。当我们向 `JWindow` 中添加内容(按钮、文本区域、图片等)时,实际上必须将它们添加到这个内容面板中。
- **Frame和JFrame**:`Frame` 通常就是我们所说的“窗口”,它通常包括关闭框、标题栏、可拖动以调整大小的边框和可选的菜单栏。`JFrame` 是 `Frame` 的Swing版本,同样有一个负责管理应用程序特定内容的内容面板。由于 `JFrame` 提供的窗口装饰以及它不依赖于先前创建的窗口,它是大多数GUI应用程序的起点。
- **Dialog和JDialog**:`Dialog` 是顶级窗口,通常用于从用户那里获取某种形式的输入。它和 `Frame` 类似,有标题、边框和可选的菜单栏,但它依赖于父 `Frame` 或 `Dialog`。当其父窗口隐藏或关闭时,`Dialog` 也会隐藏或关闭。此外,`Dialog` 可以是模态的,这意味着在 `Dialog` 关闭之前,它可以阻止用户对应用程序其他部分的输入。`JDialog` 是 `Dialog` 的Swing版本,结构与 `JFrame` 相同。
#### 5. 第一个GUI程序
让我们来编写一个简单的GUI应用程序,这个程序将是“最小化”且“行为良好”的。“最小化”意味着它将显示用户可以与之交互的最简单界面,“行为良好”意味着它将以适当的方式响应用户输入。
以下是示例代码:
```java
package chap12;
import javax.swing.JFrame;
public class TestFrame {
public static void main(String[] arg) {
JFrame frame = new JFrame("Introduction to Swing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(200, 100, 300, 200);
frame.setVisible(true);
}
}
```
编译和执行该示例的命令如下:
```
javac -d classes -sourcepath src src/chap12/TestFrame.java
java -cp classes chap12.TestFrame
```
运行这个示例后,你会看到一个窗口,点击窗口装饰(关闭框、最小化和最大化按钮),调整窗口大小,这个窗口在所有方面的行为都与你计算机上的标准窗口相同,无论使用的是什么操作系统。
#### 6. 代码解释
- **第6行**:使用 `JFrame` 是因为它提供了操作系统的标准装饰窗口,并且完全支持Swing的组件架构。我们向构造函数传递一个字符串参数,以便 `JFrame` 可以在其标题栏中显示标题。一个行为良好的程序通常会在其创建的窗口上显示标题,以将它们与其他应用程序创建的窗口区分开来。
- **第7行**:由于我们的程序只创建一个窗口,当用户尝试关闭窗口时退出应用程序是预期的行为。因此,我们调用 `frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)`。可用的默认关闭操作选项如下:
- `EXIT_ON_CLOSE` - 退出应用程序;
- `DO_NOTHING_ON_CLOSE` - 不做任何操作;
- `HIDE_ON_CLOSE` - 使窗口不可见,但将其保留在内存中以便重新显示;
- `DISPOSE_ON_CLOSE` - 销毁窗口并释放相关内存。
你可以尝试修改第7行的代码,使用不同的选项,观察程序行为的变化。
- **第8行**:我们的程序设置了窗口的边界,而不是依赖于平台默认值。`JFrame` 从 `java.awt.Component` 继承了 `setBounds()` 方法,该方法的参数以像素为单位,并且在组件容器的坐标系中解释,这里的容器是计算机屏幕。宽度和高度参数包括框架的边框装饰,因此内容面板比其总边界略小。你可以注释掉第8行,重新编译并运行程序,观察结果。也可以更改边界参数,看看会发生什么,例如给某个参数赋负值,或者将宽度和高度设置为零。
- **第9行**:调用 `JFrame.setVisible(true)` 使窗口可见。
#### 7. 顶级容器的API
顶级容器的API包含大量方法,仅 `java.awt.Window` 就定义或重写了51个不同的方法,再加上从 `Container`、`Component` 和 `Object` 继承的方法,总共有约
0
0
复制全文
相关推荐










