☕ 第十四章 图形用户界面

14.1 Swing概述

📄 一句话概括

Swing 是 Java 自带的画窗口工具箱:窗口(JFrame)套面板(JPanel),面板里摆组件(按钮、标签、输入框),不够用的地方用弹窗(JOptionPane)补——本节先把"脸"搭出来,下一节再让"点按钮有反应"。


一、为什么有 GUI:从黑框到窗口

前十三章,我们所有的程序都长一个样——控制台黑框框,用 System.out.println 说话,用 Scanner 听人打字。

自己学习用没问题,但想给别人用就尴尬了:总不能要求每个用户都会开命令行、都认识"请输入第 1 个数字"吧。于是有了 GUI(Graphical User Interface,图形用户界面)——程序穿上有按钮、有输入框、有窗口的"脸",用户用鼠标点点点就能干活。

命令行(CLI) 图形界面(GUI)
长相 黑框框,一行一行字 窗口、按钮、输入框
操作方式 敲命令 鼠标点、键盘输
上手门槛 高(要记命令) 低(看得见摸得着)
开发成本 低,几行代码 高,要先"搭"再"听"
📝 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 开窗五步

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 表示不挂在任何窗口下、独立居中弹出——单窗口程序直接 null 就行。

六、换个思路看程序:事件驱动(下节预告)

到本节为止,GUI 程序还只会"自己摆好东西"——按钮点了没反应。

因为程序的运行逻辑要换挡了:

给按钮"装耳朵"、听到点击就执行代码,靠的是事件监听——而监听器的写法,正是 4.7 函数式编程 Lambda 的老主场(ActionListener 是函数式接口)。14.2 见真章。

七、动手实验(3 个 × 30 秒)

🧪 实验 1:忘写 setVisible 会怎样

把 Demo25 第 5 步注释掉再跑:控制台正常打印,但窗口永远不出现,而且程序不退出(还得手动停)。结论:不 visible 等于没开。

🧪 实验 2:不设 EXIT_ON_CLOSE 会怎样

把第 4 步注释掉再跑:窗口能弹出来,点 ✕ 窗口消失了,但 IDEA 的程序没停止——它还在后台空转。这就是默认档的坑。

🧪 实验 3:输入框直接算数会怎样

把 Demo26 里 Integer.parseInt(ageStr) 那行删掉,直接 ageStr + 1:得到 "18" + 1 = "181"——字符串拼接(6.2 的老账)。输入框给的永远是 String。

八、五个常见误区

⚠️ 误区 1:导错包,用成了 AWT

import java.awt.Frame 编译能过,但那是第一代工具箱。认准 javax.swing.JFrame——Swing 类名带 J。

⚠️ 误区 2:忘写 setVisible(true)

程序不报错、控制台一切正常,就是没窗口——最常见的"灵异事件",其实就一个词。

⚠️ 误区 3:不设 EXIT_ON_CLOSE,点 ✕ 程序不退

窗口只是隐藏,进程还挂着。开窗四件套:标题、大小、关闭行为、可见。

⚠️ 误区 4:showInputDialog 的返回值直接当数字用

它永远返回 String。要算数先 Integer.parseInt()(6.1),否则就是字符串拼接。

⚠️ 误区 5:把组件 add 给了 JFrame 却不显示

组件要加在内容面板上(frame.getContentPane().add(...) 或先加到 JPanel 再把面板加进窗口)——套娃要一层一层套,隔层塞容易不见。

九、自测题

❓ Q1:Swing 和 AWT 最核心的区别是什么?

AWT 调操作系统画界面,各平台长相不一;Swing 纯 Java 自己画,跨平台一致。Swing 类名多一个 J,在 javax.swing 包。

❓ Q2:Swing 的三层套娃分别是什么?

JFrame(顶层容器,窗口)→ JPanel(中间容器,面板)→ 组件(JButton/JLabel/JTextField…)。JOptionPane 弹窗不进套娃,用到才弹。

❓ Q3:JFrame 开窗五步是哪五步?哪步不能放最后?

new JFrame → setSize → setLocationRelativeTo(null) → setDefaultCloseOperation(EXIT_ON_CLOSE) → setVisible(true)。setVisible 必须放最后——它负责"开幕",放前面后面搭的台子可能不生效。

❓ Q4:点 ✕ 的三档分别什么意思?默认档的坑在哪?

EXIT_ON_CLOSE 退出整个程序(最常用);DISPOSE_ON_CLOSE 只关这个窗口;DO_NOTHING_ON_CLOSE 没反应。默认档 = 窗口隐藏但进程不退,后台空转。

❓ Q5:(毕业题)写一个"自我介绍"小程序:弹输入框问姓名,再弹确认框问"确定是 XX 吗?",点是就弹消息框"你好,XX!",否则在控制台打印"取消了"。

参考骨架:

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 的返回值和常量对上了吗?——这就是下节"点按钮有反应"之前的完整交互预演。

十、下一步学什么


相关笔记