14.1 Swing概述
Swing 是 Java 自带的画窗口工具箱:窗口(JFrame)套面板(JPanel),面板里摆组件(按钮、标签、输入框),不够用的地方用弹窗(JOptionPane)补——本节先把"脸"搭出来,下一节再让"点按钮有反应"。
一、为什么有 GUI:从黑框到窗口
前十三章,我们所有的程序都长一个样——控制台黑框框,用 System.out.println 说话,用 Scanner 听人打字。
自己学习用没问题,但想给别人用就尴尬了:总不能要求每个用户都会开命令行、都认识"请输入第 1 个数字"吧。于是有了 GUI(Graphical User Interface,图形用户界面)——程序穿上有按钮、有输入框、有窗口的"脸",用户用鼠标点点点就能干活。
| 命令行(CLI) | 图形界面(GUI) | |
|---|---|---|
| 长相 | 黑框框,一行一行字 | 窗口、按钮、输入框 |
| 操作方式 | 敲命令 | 鼠标点、键盘输 |
| 上手门槛 | 高(要记命令) | 低(看得见摸得着) |
| 开发成本 | 低,几行代码 | 高,要先"搭"再"听" |
图形界面不是新语言,只是多了几个"画东西的类"。逻辑还是老逻辑:变量、方法、集合、IO、JDBC 一个没变——只是把"println 出来"换成"摆到窗口里"。
二、AWT → Swing:工具箱的家谱
Java 画界面的工具箱有两代:
| AWT(第一代) | Swing(第二代,本课主角) | |
|---|---|---|
| 包名 | java.awt |
javax.swing |
| 画法 | 调操作系统来画按钮 | 纯 Java 自己画 |
| 外观 | Windows 上一个样、Mac 上一个样 | 跨平台长得基本一样 |
| 组件名 | Button |
JButton(多个 J) |
记法很省心:Swing 组件的名字 = AWT 名字前加个 J。看到 J 开头的界面类,就来自 javax.swing。
用 Swing 要 import javax.swing.*;——手滑导成 java.awt.* 也能编译过(AWT 里也有 Button/Frame),但那是第一代工具箱,长得丑还不统一。认准 javax.swing。
三、套娃结构:窗口 → 面板 → 组件
Swing 界面是一层一层套出来的:
JFrame(顶层容器,窗口本体)
└── JPanel(中间容器,面板——先摆好板子)
└── 组件(JButton / JLabel / JTextField…真正干活的)
JOptionPane(弹窗——编外的临时工,不进套娃,用到才弹)
- JFrame:窗口本体,带标题栏、最小化、关闭按钮。所有界面都从它开始。
- JPanel:面板,相当于窗口里的一块"板子",用来分区摆放组件(本节先认识,下节常用)。
- 三大常用组件:
JLabel—— 标签,只管显示字,不接收输入JTextField—— 输入框,让人打字JButton—— 按钮,点了才干活(怎么"点有反应"是 14.2 的事)- 往哪儿放组件就
add进谁的家里:面板 add 进窗口,组件 add 进面板。
四、JFrame 开窗五步
import javax.swing.*;
public class Demo25 {
public static void main(String[] args) {
JFrame frame = new JFrame("我的第一个窗口"); // 1. 造窗口,标题写好
frame.setSize(400, 300); // 2. 定大小(宽, 高,单位像素)
frame.setLocationRelativeTo(null); // 3. 屏幕居中;null = 相对屏幕
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 4. 点 ✕ 的行为
frame.setVisible(true); // 5. 上台露脸!
System.out.println("main 走到头了,窗口还开着");
}
}
跑起来:一个 400×300 的窗口弹出并停在屏幕中间,同时控制台打印了那句话——注意这个细节:main 方法都执行完了,窗口却没关,程序还活着( Swing 自己有线程撑着场面,12 章的知识在这儿兑现)。
五步里两步要重点讲:
① setDefaultCloseOperation —— 点 ✕ 是什么意思
窗口右上角那个 ✕,点下去程序怎么办?三档可选:
| 常量 | 含义 | 场景 |
|---|---|---|
EXIT_ON_CLOSE |
退出整个程序 | 最常用,单窗口程序选它 |
DISPOSE_ON_CLOSE |
只关这个窗口,其他窗口照常 | 多窗口程序 |
DO_NOTHING_ON_CLOSE |
点了没反应 | 自己写关闭逻辑时用 |
什么都不设置时,点 ✕ 只是"窗子看不见了",程序还在后台挂着没退(IDEA 的运行指示灯还亮着)。所以开窗必配 EXIT_ON_CLOSE,这是新手第二个最常见的坑。
② setVisible(true) 必须放在最后
窗口默认是"隐藏"的。前面四步都是在后台搭台子,setVisible(true) 才是开幕。写在前面的后果:台子还没搭完就开演,后面再 setSize、add 组件都可能不生效或者闪一下才变。
五、JOptionPane 弹窗三件套
有些一句话的交互,不值得为它开一个窗口——用弹窗:
import javax.swing.*;
public class Demo26 {
public static void main(String[] args) {
// 1. 消息框:通知一句,不要回话
JOptionPane.showMessageDialog(null, "保存成功!");
// 2. 输入框:问一句要答案,返回 String
String ageStr = JOptionPane.showInputDialog(null, "请输入你的年龄:");
int age = Integer.parseInt(ageStr); // String → int,6.1 包装类的老朋友
System.out.println("明年你就 " + (age + 1) + " 岁了");
// 3. 确认框:是 / 否 / 取消,返回 int
int choice = JOptionPane.showConfirmDialog(null, "确定删除吗?");
if (choice == JOptionPane.YES_OPTION) {
System.out.println("删了");
} else {
System.out.println("手下留情");
}
}
}
| 方法 | 作用 | 返回值 |
|---|---|---|
showMessageDialog |
通知一句(如"保存成功") | 无 void |
showInputDialog |
问一句要答案(输入框) | String——拿去算数先 parseInt |
showConfirmDialog |
确认一下(是/否/取消) | int:0 是 / 1 否 / 2 取消(常量 YES_OPTION 等) |
那个位置本来填"弹窗挂在哪个窗口上"。填 null 表示不挂在任何窗口下、独立居中弹出——单窗口程序直接 null 就行。
六、换个思路看程序:事件驱动(下节预告)
到本节为止,GUI 程序还只会"自己摆好东西"——按钮点了没反应。
因为程序的运行逻辑要换挡了:
- 以前:main 从头执行到尾,程序说了算(顺序驱动)
- 以后:程序摆好界面就"原地待命",用户点哪行哪(事件驱动)
给按钮"装耳朵"、听到点击就执行代码,靠的是事件监听——而监听器的写法,正是 4.7 函数式编程 Lambda 的老主场(ActionListener 是函数式接口)。14.2 见真章。
七、动手实验(3 个 × 30 秒)
把 Demo25 第 5 步注释掉再跑:控制台正常打印,但窗口永远不出现,而且程序不退出(还得手动停)。结论:不 visible 等于没开。
把第 4 步注释掉再跑:窗口能弹出来,点 ✕ 窗口消失了,但 IDEA 的程序没停止——它还在后台空转。这就是默认档的坑。
把 Demo26 里 Integer.parseInt(ageStr) 那行删掉,直接 ageStr + 1:得到 "18" + 1 = "181"——字符串拼接(6.2 的老账)。输入框给的永远是 String。
八、五个常见误区
import java.awt.Frame 编译能过,但那是第一代工具箱。认准 javax.swing.JFrame——Swing 类名带 J。
程序不报错、控制台一切正常,就是没窗口——最常见的"灵异事件",其实就一个词。
窗口只是隐藏,进程还挂着。开窗四件套:标题、大小、关闭行为、可见。
它永远返回 String。要算数先 Integer.parseInt()(6.1),否则就是字符串拼接。
组件要加在内容面板上(frame.getContentPane().add(...) 或先加到 JPanel 再把面板加进窗口)——套娃要一层一层套,隔层塞容易不见。
九、自测题
AWT 调操作系统画界面,各平台长相不一;Swing 纯 Java 自己画,跨平台一致。Swing 类名多一个 J,在 javax.swing 包。
JFrame(顶层容器,窗口)→ JPanel(中间容器,面板)→ 组件(JButton/JLabel/JTextField…)。JOptionPane 弹窗不进套娃,用到才弹。
new JFrame → setSize → setLocationRelativeTo(null) → setDefaultCloseOperation(EXIT_ON_CLOSE) → setVisible(true)。setVisible 必须放最后——它负责"开幕",放前面后面搭的台子可能不生效。
EXIT_ON_CLOSE 退出整个程序(最常用);DISPOSE_ON_CLOSE 只关这个窗口;DO_NOTHING_ON_CLOSE 没反应。默认档 = 窗口隐藏但进程不退,后台空转。
参考骨架:
String name = JOptionPane.showInputDialog(null, "请输入你的名字:");
int c = JOptionPane.showConfirmDialog(null, "确定是 " + name + " 吗?");
if (c == JOptionPane.YES_OPTION) {
JOptionPane.showMessageDialog(null, "你好," + name + "!");
} else {
System.out.println("取消了");
}
自检:三行主逻辑各用了哪件套?showConfirmDialog 的返回值和常量对上了吗?——这就是下节"点按钮有反应"之前的完整交互预演。
十、下一步学什么
- ☑ 14.2 Swing的常见组件 ✅ —— 点此复习:三大家族认全,组件全家福摆进注册表单
相关笔记
- 第十三章 网络编程/13.2 TCP通信:main 走完了程序还活着——GUI 的窗口也靠后台线程撑着
- 第十二章 多线程/12.2 线程的创建:窗口为什么能"常驻"—— Swing 有自己的线程
- 第四章 面向对象(下)/4.7 函数式编程:下一节事件监听的写法主场
- 第六章 Java API/6.1 包装类:showInputDialog 返回 String,parseInt 收账
- 第十一章 JDBC/11.3 JDBC编程:同样的思路——先"搭好环境"再"开始干活"