杰瑞科技汇

Java Swing程序设计如何快速入门?

目录

  1. 核心概念:什么是 Swing?
  2. 第一个 Swing 程序:Hello World
  3. Swing 架构:MVC 设计模式
  4. 常用 Swing 组件详解
    • 容器类
    • 基础组件
    • 布局管理器
  5. 事件处理
  6. 高级主题
    • 多线程与 SwingWorker
    • 自定义绘制
  7. 开发工具与最佳实践
  8. 总结与学习资源

核心概念:什么是 Swing?

Swing 是 Java 基础类库的一部分,它提供了一套丰富的 GUI 组件(如按钮、文本框、菜单等),它的主要特点包括:

Java Swing程序设计如何快速入门?-图1
(图片来源网络,侵删)
  • 轻量级组件:Swing 组件是用纯 Java 编写的,不依赖于本地操作系统的 GUI 元素,这使得 Swing 应用程序在不同平台上具有一致的外观和感觉。
  • 可插拔外观:你可以轻松地更改应用程序的外观,使其看起来像 Windows、macOS、GTK 或使用 Java 自身的 Metal 外观。
  • 丰富的事件模型:通过监听器机制,可以响应用户的各种操作(如点击、输入、选择等)。
  • 强大的组件库:从简单的按钮到复杂的表格、树和文本编辑器,Swing 提供了几乎所有 GUI 开发所需的基础组件。

第一个 Swing 程序:Hello World

让我们从一个最简单的窗口开始,理解创建一个 Swing 应用程序的基本步骤。

import javax.swing.*; // 导入 Swing 的所有核心类
public class HelloWorldSwing {
    // 1. 创建并显示 GUI,为了线程安全,这个方法应该在事件分发线程上调用。
    private static void createAndShowGUI() {
        // 2. 创建一个顶级窗口(JFrame)
        JFrame frame = new JFrame("HelloWorldSwing");
        // 3. 当用户关闭窗口时,程序退出
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 4. 添加一个标签到窗口中
        JLabel label = new JLabel("Hello, World!");
        frame.getContentPane().add(label);
        // 5. 调整窗口大小以适应其内容
        frame.pack();
        // 6. 让窗口在屏幕上可见
        frame.setVisible(true);
    }
    public static void main(String[] args) {
        // 7. 在事件分发线程上创建和显示 GUI
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

代码解释:

  1. *`import javax.swing.;`**: 导入 Swing 包,这是所有 Swing 组件的来源。
  2. JFrame frame = new JFrame("HelloWorldSwing");: 创建一个 JFrame 实例,这是应用程序的主窗口,字符串是窗口的标题。
  3. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);: 设置窗口的默认关闭操作,如果不设置,关闭窗口只是隐藏它,程序后台进程仍在运行。EXIT_ON_CLOSE 表示关闭窗口时退出整个应用程序。
  4. JLabel label = new JLabel("Hello, World!");: 创建一个 JLabel(标签)组件,用于显示静态文本。
  5. frame.getContentPane().add(label);: 获取 JFrame 的内容面板,并将标签添加到其中,所有组件都必须添加到一个容器中。
  6. frame.pack();: 自动调整窗口的大小,使其刚好能容纳所有已添加的组件。
  7. frame.setVisible(true);: 将窗口设置为可见,在此之前,窗口是不可见的。
  8. SwingUtilities.invokeLater(...): 这是 Swing 编程的黄金法则! 所有与 GUI 创建和更新相关的操作都必须在 事件分发线程 上执行。invokeLater 方法确保 createAndShowGUI() 中的代码会在 EDT 上安全地运行,避免了多线程操作 GUI 可能导致的线程安全问题。

Swing 架构:MVC 设计模式

许多 Swing 组件都采用了 Model-View-Controller (MVC) 设计模式:

  • Model (模型): 负责存储数据。JList 的模型是一个 ListModel,它包含了列表中的所有数据。
  • View (视图): 负责数据的可视化呈现。JList 组件本身就是视图,它根据模型数据显示出列表。
  • Controller (控制器): 负责处理用户输入并更新模型,当用户选择列表中的某一项时,控制器会更新模型的选中状态,视图会随之重新绘制。

这种模式的好处是 数据与显示分离,你可以改变数据(模型),而视图会自动更新;或者你可以改变组件的外观(视图),而数据(模型)保持不变。

Java Swing程序设计如何快速入门?-图2
(图片来源网络,侵删)

常用 Swing 组件详解

A. 容器类

容器是用来放置其他组件的组件。

  • JFrame: 顶级窗口,通常作为应用程序的主窗口。
  • JPanel: 通用轻量级容器,它没有边框,常用于对其他组件进行分组或作为自定义绘制的画布。
  • JDialog: 模态或非模态的对话框窗口。
  • JScrollPane: 提供滚动条的面板,当其内部组件过大时,可以通过滚动条查看。

B. 基础组件

  • JLabel: 显示文本或图像。
  • JButton: 点击按钮触发动作。
  • JTextField: 单行文本输入框。
  • JTextArea: 多行文本区域,不支持自动换行(除非放在 JScrollPane 中)。
  • JPasswordField: 密码输入框,输入的字符会显示为掩码(如 )。
  • JCheckBox: 复选框,可多选。
  • JRadioButton: 单选按钮,需要与 ButtonGroup 配合使用以确保同一组内只有一个被选中。
  • JComboBox: 下拉列表框。
  • JList: 列表组件,可以显示一列项目。
  • JTable: 表格组件,用于显示二维数据。
  • JTree: 树形组件,用于展示分层数据。

C. 布局管理器

布局管理器负责决定容器中组件的大小和位置。绝对定位(null 布局) 在复杂的 GUI 中很难维护,因此强烈建议使用布局管理器。

  • BorderLayout: 将容器分为五个区域:NORTH, SOUTH, EAST, WEST, CENTERJFrame 的默认布局。
  • FlowLayout: 将组件从左到右、从上到下依次排列,像文字一样。JPanel 的默认布局。
  • GridLayout: 将容器划分为一个网格,每个组件占据一个格子。
  • BoxLayout: 允许组件在垂直或水平方向上依次排列。
  • GridBagLayout: 最强大也最复杂的布局管理器,允许组件跨越多行多列,并提供精细的大小和对齐控制。

示例:使用 BorderLayoutFlowLayout

import javax.swing.*;
import java.awt.*;
public class LayoutExample {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("布局示例");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(400, 200);
            // 使用 BorderLayout 作为主框架的布局
            frame.setLayout(new BorderLayout(5, 5)); // 水平和垂直间距为5像素
            // 顶部面板,使用 FlowLayout
            JPanel topPanel = new JPanel(new FlowLayout());
            topPanel.add(new JButton("按钮 1"));
            topPanel.add(new JButton("按钮 2"));
            frame.add(topPanel, BorderLayout.NORTH);
            // 中间面板
            JLabel centerLabel = new JLabel("这是中心区域", SwingConstants.CENTER);
            frame.add(centerLabel, BorderLayout.CENTER);
            // 底部面板
            JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
            bottomPanel.add(new JButton("确定"));
            bottomPanel.add(new JButton("取消"));
            frame.add(bottomPanel, BorderLayout.SOUTH);
            frame.setVisible(true);
        });
    }
}

事件处理

Swing 使用 监听器 模式来处理事件,基本流程是:

  1. 获取事件源:比如一个 JButton
  2. 创建监听器对象:实现一个特定的监听器接口(如 ActionListener)。
  3. 将监听器注册到事件源:调用事件源的 addXXXListener() 方法。

示例:按钮点击事件

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class EventExample {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("事件处理示例");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new FlowLayout());
            JButton clickButton = new JButton("点击我");
            JLabel statusLabel = new JLabel("等待点击...");
            // 1. 创建监听器对象(匿名内部类)
            ActionListener buttonListener = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // 当按钮被点击时,此方法会被调用
                    statusLabel.setText("按钮被点击了!");
                    System.out.println("按钮在事件源: " + e.getSource() + " 上被点击。");
                }
            };
            // 2. 将监听器注册到按钮
            clickButton.addActionListener(buttonListener);
            frame.add(clickButton);
            frame.add(statusLabel);
            frame.pack();
            frame.setVisible(true);
        });
    }
}

高级主题

A. 多线程与 SwingWorker

重要原则: 永远不要在事件分发线程 上执行耗时操作(如网络请求、文件读写、复杂计算),否则,GUI 会冻结,无法响应用户输入。

解决方案是使用 SwingWorker,它是一个抽象类,专门用于在后台线程中执行耗时任务,并在任务完成后安全地更新 GUI。

SwingWorker 的工作流程:

  1. doInBackground() 方法中执行耗时任务。
  2. process() 方法中(可选),可以定期发布中间结果并更新 GUI。
  3. done() 方法中,在任务完成后更新 GUI。

B. 自定义绘制

当标准组件无法满足你的需求时(如绘制自定义图形、图表、游戏),你可以通过继承 JComponentJPanel 并重写其 paintComponent(Graphics g) 方法来实现自定义绘制。

关键点:

  • 始终调用 super.paintComponent(g);:这是为了保证 Swing 能够正确地绘制组件的背景等。
  • paintComponent 中进行所有绘制:不要在构造函数或其他方法中直接绘制,因为该方法会在组件需要重绘时被自动调用(如窗口大小改变、被其他窗口遮挡后重新显示)。
import javax.swing.*;
import java.awt.*;
public class CustomDrawing extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); // 必须首先调用
        // 将 Graphics 对象转换为更强大的 Graphics2D
        Graphics2D g2d = (Graphics2D) g;
        // 设置抗锯齿,使图形更平滑
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 绘制一个红色填充的矩形
        g2d.setColor(Color.RED);
        g2d.fillRect(50, 50, 100, 80);
        // 绘制一个蓝色边框的椭圆
        g2d.setColor(Color.BLUE);
        g2d.setStroke(new BasicStroke(3)); // 设置线条宽度
        g2d.drawOval(200, 50, 100, 80);
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("自定义绘制");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new CustomDrawing());
            frame.setSize(400, 200);
            frame.setVisible(true);
        });
    }
}

开发工具与最佳实践

  • 开发工具
    • IDE (集成开发环境):IntelliJ IDEA 和 Eclipse 都对 Swing 开发提供了非常好的支持,包括可视化界面设计器(如 IntelliJ 的 GUI Designer)。
    • 可视化设计器:可以像拖拽控件一样快速构建界面,并自动生成代码,非常适合初学者和快速原型开发。
  • 最佳实践
    1. 始终使用 SwingUtilities.invokeLater:创建和更新 GUI 的唯一入口。
    2. 使用布局管理器:避免使用绝对定位,让你的 GUI 具有更好的可移植性和可维护性。
    3. 分离逻辑与视图:将业务逻辑代码与 GUI 创建代码分离开,使用 MVC 模式或至少将它们放在不同的类中。
    4. 为组件命名:给按钮、文本框等组件起有意义的名字,便于管理和调试。
    5. 使用 Action 接口:对于菜单项和工具栏按钮,使用 Action 接口可以让你将一个动作与一个图标、文本和快捷键绑定在一起,并在多处复用。

总结与学习资源

Java Swing 是一个成熟且功能强大的 GUI 工具包,虽然它的 API 有些古老,但其核心思想(事件驱动、MVC)至今仍是 GUI 编程的基础。

学习资源:

  • 官方文档Java Swing Tutorial (Oracle) - 最权威、最全面的教程。
  • 书籍:《Java Swing (David Geary 和 James Elliott 著)》是经典的 Swing 参考书。
  • 在线教程:像 BaeldungMadhusudan's Blog 等网站有很多实用的 Swing 教程和示例代码。
  • 开源项目:在 GitHub 上寻找使用 Swing 开发的开源项目,阅读源码是提升技能的绝佳方式。

从创建一个简单的窗口开始,逐步尝试添加不同的组件、布局和事件处理,你很快就能掌握 Java Swing 程序设计的精髓,祝你编程愉快!

分享:
扫描分享到社交APP
上一篇
下一篇