12.1 GUI 事件处理

article/2025/6/23 2:47:21

  Swing简介

  1. 不同于 AWT 使用重量级组件(每个组件对应有一个本地窗口系统资源),Swing 提供了轻量级组件,它们不是直接映射到本地窗口系统组件上,而是绘制出来的。因此,Swing 组件可以在不同的平台上保持一致的外观和感觉,并且更加灵活。

  2. JComponent:Swing 中的所有组件都继承自 JComponent 类,而 JComponent 又间接继承自 AWT 的 Container 类。这意味着 Swing 可以利用 AWT 的一些基础设施,比如事件模型和布局管理器。

  3. 增强的功能:Swing 在 AWT 的基础上增加了许多新的功能和组件,如表格(JTable)、树(JTree)、选项卡面板(JTabbedPane)等高级组件。

  4. 事件处理模型:Swing 继承并扩展了 AWT 的事件处理模型。虽然两者使用相似的监听器接口来处理用户交互,但 Swing 引入了一些额外的功能,例如更精细的事件类型和支持键盘导航等特性。

一、Box和BoxLayout详解

BoxBoxLayout是Swing提供的两种与布局相关的类,它们提供了一种简单的方法来创建线性布局(水平或垂直方向)。

  • BoxLayout:是一个布局管理器,它可以沿容器的水平轴(X轴)或垂直轴(Y轴)布置组件。通过设置不同的轴向,你可以创建出水平或垂直排列的组件布局。

  • Box:是一个特殊的容器,它使用BoxLayout作为其布局管理器。Box类提供了两个静态方法来创建水平或垂直盒子:

    • Box.createHorizontalBox():创建一个水平盒子,即内部组件沿水平方向排列。
    • Box.createVerticalBox():创建一个垂直盒子,即内部组件沿垂直方向排列。

Box类还提供了一些方便的方法来添加具有一定功能的不可见组件,比如用于增加间隔的胶水(createGlue())和刚性区域(createRigidArea(Dimension d)),这有助于调整布局中的空白部分和组件之间的距离。

使用BoxLayout时,可以通过调用容器对象的setLayout(new BoxLayout(container, axis))方法来设置布局,其中axis参数应为BoxLayout.X_AXIS(水平布局)或BoxLayout.Y_AXIS(垂直布局)。

案例:

import javax.swing.*;
import java.awt.*;public class BoxLayoutExample {public static void main(String[] args) {// 创建并设置主窗口JFrame frame = new JFrame("Box Layout Example");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(300, 200);// 创建一个垂直Box容器Box verticalBox = Box.createVerticalBox();// 添加第一个标签JLabel label1 = new JLabel("这是第一个标签:");verticalBox.add(label1);// 添加一个文本框,并在其前后添加一些垂直胶水以增加间隔JTextField textField = new JTextField();verticalBox.add(Box.createVerticalStrut(5)); // 在组件前添加间隔verticalBox.add(textField);verticalBox.add(Box.createVerticalStrut(10)); // 在组件后添加更大的间隔// 添加第二个标签JLabel label2 = new JLabel("这是第二个标签:");verticalBox.add(label2);// 添加一个按钮,并在其前后添加一些垂直胶水以增加间隔JButton button = new JButton("点击我");verticalBox.add(Box.createVerticalStrut(5));verticalBox.add(button);verticalBox.add(Box.createVerticalStrut(10));// 将垂直Box容器添加到主窗口frame.add(verticalBox, BorderLayout.CENTER);// 显示窗口frame.setVisible(true);}
}

在 Java 的 GUI 编程中,事件处理机制是实现用户交互的核心部分。AWT(Abstract Window Toolkit)和 Swing 它们都使用基于 事件监听器模型(Event Listener Model) 来处理用户操作,比如点击按钮、输入文本、鼠标移动等。


二、Java GUI 事件处理的基本概念

1. 事件源(Event Source)

指的是产生事件的对象,例如一个按钮(JButton)、文本框(JTextField)或窗口(JFrame)。

2. 事件对象(Event Object)

当事件发生时,系统会创建一个事件对象,其中包含了事件的相关信息。例如:

  • ActionEvent:表示动作事件(如按钮被点击)
  • MouseEvent:表示鼠标事件
  • KeyEvent:表示键盘事件
  • WindowEvent:表示窗口事件(打开、关闭等)

3. 监听器接口(Listener Interface)

监听器是一个实现了特定接口的对象,用于接收并处理事件。每种事件类型都有对应的监听器接口,例如:

  • ActionListener:用于响应动作事件
  • MouseListener:用于响应鼠标事件
  • KeyListener:用于响应键盘事件
  • WindowListener:用于响应窗口事件

4. 注册监听器

通过调用事件源的方法将监听器注册到事件源上,例如:

button.addActionListener(myActionListener);

三、常见的事件类型和监听器接口

事件类型对应的监听器接口常见方法示例
ActionEventActionListeneractionPerformed()
MouseEventMouseListenermouseClicked(), mousePressed(), mouseReleased(), mouseEntered(), mouseExited()
KeyEventKeyListenerkeyPressed(), keyReleased(), keyTyped()
WindowEventWindowListenerwindowClosing(), windowOpened(), windowClosed() 等
ItemEventItemListeneritemStateChanged()
TextEventTextListenertextValueChanged()

四、事件处理的几种方式

方法一:匿名内部类(最常用)

JButton button = new JButton("Click me");button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("按钮被点击了!");}
});

方法二:Lambda 表达式(Java 8+ 推荐)

button.addActionListener(e -> {System.out.println("按钮被点击了!");
});

方法三:实现监听器接口的类

适用于多个组件共享同一个监听器逻辑的情况。

public class MyActionListener implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("事件触发:" + e.getActionCommand());}
}// 使用
button.addActionListener(new MyActionListener());

方法四:适配器类(Adapter Class)

对于有多个方法的监听器接口(如 MouseListener),可以继承其适配器类,只重写感兴趣的方法。

panel.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {System.out.println("鼠标点击位置:" + e.getX() + ", " + e.getY());}
});

五、常见控件与事件绑定示例

1. JButton 与 ActionEvent

JButton button = new JButton("提交");
button.addActionListener(e -> JOptionPane.showMessageDialog(null, "提交成功!"));

2. JTextField 与 KeyEvent

textField.addKeyListener(new KeyAdapter() {@Overridepublic void keyReleased(KeyEvent e) {System.out.println("你输入的是:" + textField.getText());}
});

3. JCheckBox 与 ItemEvent

checkBox.addItemListener(e -> {if (e.getStateChange() == ItemEvent.SELECTED) {System.out.println("复选框被选中");} else {System.out.println("复选框被取消选中");}
});

4. JFrame 与 WindowEvent

frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.out.println("窗口正在关闭...");System.exit(0);}
});

六、控件和常用事件对应的监听接口

组件常用事件监听器接口
JButtonActionEventActionListener
JMenuItemActionEventActionListener
JTextFieldActionEvent/KeyEventActionListener/KeyListener
JCheckBoxItemEventItemListener
JFrameWindowEventWindowListener
JPanelMouseEventMouseListener
JScrollPaneAdjustmentEventAdjustmentListener

以下是一些 Swing 独有(或主要用于 Swing) 的事件监听接口及其用途:

事件监听接口监听对象主要作用
ListSelectionListenerJListListSelectionModel监听列表中选中项的变化
TreeSelectionListenerJTree监听树中节点的选择变化
TableColumnModelListenerJTable 的列模型监听表格列的变化(如宽度调整、移动等)
TableModelListenerJTable 的数据模型表格数据发生变化时触发
ChangeListenerJSliderJSpinnerJTabbedPaneButtonGroup 等值或状态发生变化时触发
DocumentListenerJTextFieldJTextArea 的 Document 对象文本内容发生插入、删除、更改时触发
CaretListenerJTextComponent 子类(如 JTextFieldJTextArea监听文本光标位置变化
MenuListenerJMenu菜单打开/关闭/取消选择时触发
HyperlinkListenerJEditorPaneJTextPane监听超链接点击事件
InternalFrameListenerJInternalFrame内部窗口创建、激活、关闭等事件

例子:

import javax.swing.*;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;public class CaretListenerExample {public static void main(String[] args) {// 创建主窗口JFrame frame = new JFrame("CaretListener 示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(400, 300);frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));// 创建一个文本框JTextField textField = new JTextField(20);// 创建一个文本区域JTextArea textArea = new JTextArea(5, 30);textArea.setLineWrap(true);textArea.setWrapStyleWord(true);// 创建一个标签用于显示光标位置JLabel caretPositionLabel = new JLabel("光标位置:未开始");// 添加 CaretListener 到文本框textField.addCaretListener(new CaretListener() {@Overridepublic void caretUpdate(CaretEvent e) {int pos = textField.getCaretPosition();caretPositionLabel.setText("文本框中光标位置:" + pos);}});// 添加 CaretListener 到文本区域textArea.addCaretListener(new CaretListener() {@Overridepublic void caretUpdate(CaretEvent e) {int pos = textArea.getCaretPosition();caretPositionLabel.setText("文本区域中光标位置:" + pos);}});// 添加组件到窗口中frame.add(new JLabel("文本框:"));frame.add(textField);frame.add(Box.createVerticalStrut(20)); // 添加垂直间距frame.add(new JLabel("文本区域:"));frame.add(new JScrollPane(textArea));frame.add(caretPositionLabel);// 显示窗口frame.setLocationRelativeTo(null); // 居中显示frame.setVisible(true);}
}


http://www.hkcw.cn/article/nYtfcHpcFP.shtml

相关文章

冲入起火麦地抢收司机称举手之劳 网友赞救火英雄

冲入起火麦地抢收司机称举手之劳 网友赞救火英雄!6月1日,一段视频在网上引起广泛关注。视频中,远处麦田浓烟滚滚,火焰借风力蔓延。这时,一台收割机朝着浓烟方向驶去,在麦田中快速开辟出一条隔火带。视频中,收割机司机的妻子大声呼喊:“别离火那么近!往外走点!”她还对…

稳定币概念集体大涨 政策利好密集释放

受全球多地稳定币监管政策进展提振,相关概念股近日表现活跃。截至发稿,连连数字(02598.HK)、OSL集团(00863.HK)分别上涨57.88%、3.10%。香港特别行政区政府5月30日在宪报刊登《稳定币条例》,标志着该条例正式生效,进一步完善了香港的数字资产监管框架。此前5月21日,香港立…

从0开始学vue:pnpm怎么安装

一、什么是 pnpm? pnpm(Performant npm)是新一代 JavaScript 包管理器,优势包括: 节省磁盘空间:通过硬链接和符号链接实现高效存储安装速度更快:比 npm/yarn 快 2-3 倍内置工作区支持&#xf…

【笔记】在 MSYS2 MINGW64 环境中安装常用开发依赖包

📝 在 MSYS2 MINGW64 环境中安装常用开发依赖包 ✅ 目标说明 在 MSYS2 的 MINGW64 工具链环境中,安装 Python 开发所需的基础依赖库和工具。 这些包括: 编译工具(GCC)Python 包管理器(pip、setuptools、wh…

基于springboot的家政服务预约系统

博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了六年的毕业设计程序开发,开发过上千套毕业设计程序,没有什么华丽的语言&#xff0…

“对等关税”要黄了吗 特朗普政府上诉反击

近期,美国政坛围绕关税的斗争不断升级。5月28日,美国国际贸易法院裁定特朗普利用《国际紧急经济权力法》越权加征关税无效。这意味着特朗普今年2月对中国、墨西哥和加拿大征收的关税将被视为违法。对此,特朗普团队随即提出上诉。5月29日,美国联邦巡回上诉法院批准特朗普政府…

警方通报男子将女童拖进小巷 嫌疑人已被拘留

6月3日,湖南娄底市公安局娄星分局通报了一起事件。5月20日下午,嫌疑人刘某某(男,38岁)酒后在娄底市娄星区涟滨中街附近拖拽一名6岁女童进入居民区巷子。幸亏居民及时制止并报警。警方迅速赶到现场将刘某某控制。经侦查,刘某某涉嫌寻衅滋事已被拘留,并将依法追究其刑事责…

郑钦文晋级法网8强,发文晒满背泥泞照祝大小朋友勇敢追梦

法网女单第四轮,郑钦文总比分2-1战胜萨姆索诺娃。赛后郑钦文发文送出儿童节祝福:人都应该有梦,有梦就别怕痛,是一颗宝石就该闪烁祝所有的大朋友小朋友们节日快乐,勇敢追梦。其中有一张照片郑钦文满背泥泞,心疼又佩服!责任编辑:zx0002

国足将于5日迎18强赛“生死战” 背水一战求生机

中国青年报报道,北京时间今天中午,国足一行从上海驻地出发前往印尼雅加达,备战2026美加墨世界杯亚洲区18强赛小组赛第9轮客场赛事。除因伤无法随队出征的前锋刘若钒外,25名球员将乘坐傍晚航班前往印尼。这场关键比赛将于6月5日21时45分在雅加达格罗拉蓬卡诺体育场举行,如果…

特朗普回应科罗拉多州“恐袭”事件 谴责并要求严惩

美国总统特朗普在社交媒体上发文表示,美国绝不会容忍6月1日在科罗拉多州博尔德发生的可怕袭击。他指责嫌疑人是通过拜登政府“荒谬的开放边境政策”进入美国,这项政策严重损害了国家利益。特朗普强调,该嫌疑人必须被驱逐出境,并且恐怖主义行为将受到法律的全面追究。他认为…

《酱园弄》第一部定档 全明星阵容引期待

《酱园弄》第一部定档 全明星阵容引期待。你是否还记得1945年的民国旧事,那些尘封在岁月里的悬案奇闻,如今被搬上了大银幕。《酱园弄》第一部《酱园弄・悬案》定档6月21日,带着满满的期待与未知,缓缓向我们走来,它能否成为下一个票房爆款,引发众人热议。章子怡、雷佳音、…

【机器学习基础】机器学习入门核心算法:多分类与多标签分类算法

多分类与多标签分类算法 一、单标签分类问题1. 单标签二分类2. 单标签多分类 二、多标签分类问题 (Multi-Label Learning - MLL)1. 定义与特点2. 解决策略 三、实现与应用总结 在机器学习领域,分类任务是核心问题之一。根据预测目标的性质,主要分为单标签…

PH热榜 | 2025-05-31

1. Perplexity Labs 标语:让你的项目比以往任何时候都更快地变为现实。 介绍:Perplexity Labs可以帮助您完成各种工作和个人项目。无论是制定营销计划、分析商业财务,还是安排一周的餐饮计划,Perplexity Labs都是将您最佳创意变…

消费者网络购物意向分析:调优逻辑回归LR与决策树模型在电商用户购买预测中的应用及特征重要性优化

全文链接:tecdat.cn/?p42358 分析师:Li Ting 在数字化商业浪潮中,精准把握消费者网络购物意向已成为电商企业提升竞争力的核心命题(点击文末“阅读原文”获取完整智能体、代码、数据、文档)。 本文改编自团队为某电商…

CppCon 2014 学习:Decomposing a Problem for Parallel Execution

学会如何拆分问题,使其能够高效地分配到多个核心上并行处理 把一个大问题拆成多个小任务让这些任务能独立运行在多个 CPU 核心上充分利用多核架构提升性能和吞吐量同时避免任务间过多依赖或冲突,保证并行效率星星计数问题 一个相对简单的问题&#xff0…

审计 - 风险应对 - 控制测试

1.控制测试的概念和程序 控制测试定义是指用于评价内部控制在防止或发现并纠正认定层次重大错报方面的运行有效性的审计程序审计程序询问、观察、检查和重新执行 2 控制测试的要求 1).控制测试并非在任何情况下都需要实施。 2).当存在下列情形之一时…

抠图P图秀v7.8.19

抠图 P 图秀是一款图片编辑应用程序,主要功能是帮助用户对图片进行抠图和 P 图操作。 抠图 P 图秀是一款图片编辑应用程序,主要功能是帮助用户对图片进行抠图和 P 图操作。以下是抠图 P 图秀的简要介绍: 1. 抠图功能:通过智能算法…

MonitorSDK_前端错误收集(重点阐述VueReact错误监测)

Promise中错误监测 前端错误收集方式 Vue中错误 Vue 全局错误处理器 app.config.errorHandler 详解 🔧 app.config.errorHandler 详解 📌 定义 app.config.errorHandler 是 Vue 应用实例的配置项之一,允许开发者定义一个函数来处理应用中的…

PCIe— Configuration

前言 设备初始化时, Configuration 状态在 2.5GT/s 速率下配置链路以及通道 编号。5GT/s 和 8GT/s 速率时,设备也可能从 Recovery 状态进⼊ Configuration 状态。此时状态转换的主要⽬的是为了进⾏多通道设备的 链路位宽动态转换。动态转换仅⽀…

山东一10岁男童在家门口走失 家属急寻线索

6月1日,有网友发布视频称山东省滕州市姜屯镇黄坡村一名10岁男孩赵某超走失。孩子家属十分焦急,希望通过网络社交媒体寻求帮助。当天下午,赵某超的外公王先生透露,通过查看家门口监控发现,孩子于5月31日下午5时左右走失。当时孩子先是在家门口消失了几分钟,然后返回了一次…