Swing之EventQueue简介

Swing MVC体系结构浅析 Swing MVC体系结构浅析1 Swing与MVC<br /><br />  Swing组件设计使用了著名的MVC模型-视图-控制器体系结构。为了了解MVC体系结构与Swing组件的关系,我们来看一下如何设计一个表示按钮的组件,因为按钮的各个部分可以与MVC体系结构的3个部分对应起来。<br />  按钮在任意给定时刻,可处于启用和无效两种状态之一。很显然,按钮只有处于启用状态时才会响应点击。记录按钮状态是很有用的,视图需要根据按钮的状态进行不同的渲染。按钮的所有状态就是MVC体系结构的模型部分。模型还包 阅读详情

    在Swing的GUI程序中,EventQueue是一个重要的部分,它负责所有AWTEvent(以及其子类)的分发

    EventQueue简单工作原理

    简单来讲,在EventQueue中有一个dispatchThread,这是一个线程类,负责事件的分发,当Queue中有事件的时候,它会摘取前面的事件并分发给相应的对象进行处理,等处理完之后再获取下一个,当Queue中没有事件的时候,线程等待。

    当有事件触发时,系统会调用EventQueue的push方法将AWTEvent添加到EventQueue的最后,同时唤醒dispatchThread。 

    为什么界面会死掉

    所以可以看到,Swing的事件分发实际上是同步的,并且都是在dispatchThread这个线程中处理的,也就是说是一个事件一个事件处理的,如果有某一个事件处理的时间非常长的时侯,其他事件就会被堵塞在那里,从现象上看得话,就是界面会死掉,如果界面被其他窗口覆盖之后再回到前面的时侯,会变成一片灰色,这是因为PaintEvent被堵塞而不能被分发出去的缘故。

    为什么Modal Dialog(Frame)弹出的时候界面不会死

    当在处理事件的时侯如果弹出一个Modal Dialog,那么处理方法会停在那里并等待Modal Dialog销毁,这个时候按照上面的分析,dispatchThread也会停在那里,这样的话其他事件也不会被分发,那么界面也应该会死掉才对。实际上在等待Modal Dialog销毁的过程中,如果能够保证事件可以顺利地分发出去的话,界面当然就不会死。先来看这个例子。

import javax.swing.JDialog;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.EventQueue;
import java.awt.AWTEvent;
import java.awt.ActiveEvent;
import java.awt.event.PaintEvent;
import java.awt.Component;
import java.awt.MenuComponent;

public class TestEvent {
    public static void main(String[] args) {
        final JDialog dlg = new JDialog();
        dlg.setTitle("Test Event Queue");
        JButton btn = new JButton("Test");
        dlg.getContentPane().add(btn);
        btn.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                long now = System.currentTimeMillis();
                EventQueue theQueue = dlg.getToolkit().getSystemEventQueue();
                System.out.println("at least 5000 millis");
                while (System.currentTimeMillis() - now < 5000l) {
                    try {
                        // This is essentially the body of EventDispatchThread
                        AWTEvent event = theQueue.getNextEvent();
                        Object src = event.getSource();
                        if (event instanceof ActiveEvent) {
                            ((ActiveEvent) event).dispatch();
                        }
                        else if (src instanceof Component) {                           ((Component) src).dispatchEvent(event);
                        }
                        else if (src instanceof MenuComponent) {
                            ((MenuComponent) src).dispatchEvent(event);
                        }
                    }
                    catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
                System.out.println("end");
            }
        });
        dlg.pack();
        dlg.show();
    }
}

在上面的例子中,当Button的Action被触发,actionPerformed方法执行的时候,会首先帮助EventQueue分发事件,直到最少5秒之后返回,这时可以看到这个事件处理方法至少执行了5秒钟,但是在这个过程中Dialog仍然可以正常工作,只是因为在这5秒之中并非是Sleep,而是在帮助EventQueue分发事件,如果代码改成
    Thread.sleep(5000);
的话,界面将会死掉。

public class TestEvent {
    public static void main(String[] args) {
        final JDialog dlg = new JDialog();
        dlg.setTitle("Test Event Queue");
        JButton btn = new JButton("Test");
        dlg.getContentPane().add(btn);
        btn.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                long now = System.currentTimeMillis();
                EventQueue theQueue = dlg.getToolkit().getSystemEventQueue();
                System.out.println("at least 5000 millis");
                while (System.currentTimeMillis() - now < 5000l) {
                    try {
                        // This is essentially the body of EventDispatchThread
                        AWTEvent event = theQueue.getNextEvent();
                        Object src = event.getSource();
                        if (event instanceof ActiveEvent) {
                            ((ActiveEvent) event).dispatch();
                        }
                        else if (src instanceof Component) {                           ((Component) src).dispatchEvent(event);
                        }
                        else if (src instanceof MenuComponent) {
                            ((MenuComponent) src).dispatchEvent(event);
                        }
                    }
                    catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
                System.out.println("end");
            }
        });
        dlg.pack();
        dlg.show();
    }
}

在上面的例子中,当Button的Action被触发,actionPerformed方法执行的时候,会首先帮助EventQueue分发事件,直到最少5秒之后返回,这时可以看到这个事件处理方法至少执行了5秒钟,但是在这个过程中Dialog仍然可以正常工作,只是因为在这5秒之中并非是Sleep,而是在帮助EventQueue分发事件,如果代码改成
    Thread.sleep(5000);
的话,界面将会死掉。

    所以在Modal Dialog弹出的时候,实际上只要在show方法中能够实现类似上面的代码,保证事件可以正常的分发(同时截获父窗口的一些事件,过滤掉一些触发Action的事件),那么父窗口的界面就不会死掉。

    当事件处理方法很长时间才能做完该怎么办

    当事件处理方法需要很长时间才能执行完的话,如果需要保证界面不死的话,还是只能用多线程,虽然上面的方法实现了事件处理的时候界面不死,但是这和一般的事件处理是有不同的,上面的方法实际上在处理的时候什么都没有做,而我们一般需要有自己的操作(比如访问数据库,访问网络,读写操作等需要很长时间才能处理完的工作),不可能做到一边在操作一边处理Event分发,这个时候只有新建一个线程才是正道。

关于EventQueue的一些方法

    Window.getToolkit().getSystemEventQueue();
    获取系统的EventQueue

    SwingUtilities.isEventDispatchThread();
    当前线程是否为EventDispatchThread

    EventQueue.push(EventQueue queue);
    将一个EventQueue作为当前EventQueue的nextQueue,实际上事件是由最后一个EventQueue来分发的

    EventQueue.getNextEvent();
    获取下一个事件,如果没有,则等到有再返回

   EventQueue.postEvent(AWTEvent theEvent);
   添加一个Event

  不过关于很多EventQueue和EventDispatchThread的方法都被封装在其实现里面,对外不可视,导致不可能对其进行一些修改,有点不爽。另外在EventQueue中的AWTEvent一般都是给最上层对象的,比如最上层的JDialog或者JFrame,然后由JDialog或者JFrame分发给其他的Component,不过我不知道怎么可以从AWTEvent事件找到真正的拥有者,这一点比较郁闷

Swing组建中EventQueue的使用 NULL 博文链接:https://futeng.iteye.com/blog/1733683 立即下载

相关推荐

Cursor+Apifox MCP Server实战:5分钟搞定API自动化测试用例生成

本文详细介绍了如何利用Cursor IDE与Apifox MCP Server,在5分钟内将API文档自动转化为高质量的自动化测试用例。通过配置MCP Server建立数据桥梁,开发者可直接用自然语言指令,让AI基于真实接口规范生成可立即执行的pytest测试代码,大幅提升接口测试效率,特别适合快节奏的SaaS项目。

ooo22的博客 534

GUI编程基础02Swing(了解)

文章目录GUI编程基础02事件监听 GUI编程基础02事件监听 事件监听:当某个事件发生时,该干什么? import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class TestAction { public st

asdfghjkl_zth的博客 935

告别手动维护!教你用SAP BAPI批量更新生产订单BOM组件(CO02工单)

本文详细介绍了如何利用SAP BAPI实现生产订单BOM组件的批量更新,解决传统手工操作(如CO02工单)效率低下的问题。通过核心函数解析和批量处理框架设计,帮助用户大幅提升工作效率,降低错误率,适用于物料主数据变更、季节性配方调整等场景。

weixin_30844577的博客 561

java中EventQueue的作用_Swing之EventQueue简介

在Swing的GUI程序中,EventQueue是一个重要的部分,它负责所有AWTEvent(以及其子类)的分发EventQueue简单工作原理1)简单来讲,在EventQueue中有一个dispatchThread,这是一个线程类,负责事件的分发,当Queue中有事件的时候,它会摘取前面的事件并分发给相应的对象进行处理,等处理完之后再获取下一个,当Queue中没有事件的时候,线程等待。2)当有事...

weixin_30677191的博客 3562

8.5/Q1,Charls最新高分文章解读!

8 257名受试者中,672人(8.14%)在9年内发生过卒中。在调整的多因素cox回归模型中,TyG和ABSI仍然是卒中的预测因素,TyG的HR为1.25(95%CI:1.06~1.47),ABSI的HR为1.33(95%CI:1.06~1.68)。TyG和ABSI联合诊断效能最高(AUC:0.579,95%CI:0.553~0.597),而TyG(AUC:0.566,95%CI:0.544~0.587)和ABSI(AUC:0.533,95%CI:0.524~0.597)的诊断效能最低。

gsky_sci的博客 1016

Claude Code插件安装与VSCode深度集成实战指南

Claude Code是一款专为IDE设计的AI编程助手插件,其核心价值在于将自然语言意图转化为可运行代码,从而优化开发者认知带宽分配。它依赖Node.js运行时、git版本上下文和VSCode编辑器API三者协同工作,技术原理涉及本地进程通信、权限策略绕过、上下文感知补全等关键机制。该工具显著提升工程效率,适用于CLI开发、EXIF元数据处理、异步逻辑生成等典型JavaScript/TypeScript应用场景。本文聚焦Claude Code插件在VSCode中的真实落地链路,覆盖Windows/macO

weixin_34006468的博客 474

java swing的EventQueue解析

学习swing的笔记,关于为何在main方法中调用EventQueue的方法来运行swing的解读

qq_51453077的博客 475

Android13 CarPowerManagementService onApPowerStateChange流程分析

如下为CarPower上电的流程图:下面我们从代码角度分析:在CPMS的init方法中会调用onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, CarPowerManager.STATE_WAIT_FOR_VHAL); 设置ApPowerState为STATE_WAIT_FOR_VHAL: 在onApPowerStateChange中调用PowerHandler 的handlePowerStateChange方法: 在handlePowerStateChang

liuning1985622的博客 925

java基础学习总结——java.awt.EventQueue.invokeLater干什么用的

在Java中Swing是线程不安全的,是单线程的设计,这样的造成结果就是:只能从事件派发线程访问将要在屏幕上绘制的Swing组件。事件派发线程是调用paint和update等回调方法的线程,它还是事件监听器接口中定义的事件处理方法,例如,ActionListener中的actionPerformed方法在事件派发线程中调用。  Swing是事件驱动的,所以在回调函数中更新可见的GUI是很自然的事

yiziweiyang的专栏 3458

#Linux内存管理# 用一个案例详细介绍ARMv7-A架构 缺页中断处理的原理

跳转到异常向量:根据 异常向量表基地址(通常配置在 VBAR 寄存器中,例如 0xFFFF0000) + 数据中止异常的偏移量 0x10,跳转到数据中止异常的处理程序入口点 0xFFFF0010(实践中,这个入口通常是一条跳转到更复杂处理函数的指令)。malloc 通常不会立即分配物理内存页,它只是在内核为该进程维护的虚拟地址空间中找到一段足够大的空闲虚拟地址区域(比如 0x00008000 - 0x00008FFF),标记为已用,并返回起始地址(例如 0x00008000)给程序。

sinat_37817094的博客 993

如何有效爬取“好大夫”评论数据?技术实现与合规性分析

本文探讨了爬取好大夫在线医生评论数据的技术与合规性问题。分析了好大夫平台评论数据的价值和特点,指出其动态加载和反爬机制的挑战。技术上,推荐使用Selenium模拟浏览器行为获取数据,并提供了分页爬取、代理IP、验证码识别等解决方案。同时强调必须遵守平台的爬虫策略,关注用户协议和隐私保护法规,建议通过官方API或授权方式获取数据。文章还讨论了数据清洗存储方法,并提醒注意数据伦理和最小化抓取原则。本文为医疗数据爬取提供了技术实现和合规性指导的平衡方案。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1053

细说Java GUI:AWT,SWT,Swing

历史 Internet上有许多围绕这一争论的故事。你可能已经听说过它们中的大多数了,其中之一有助于让你理清头绪,让我们就从这里开始,Amy Fowler是Swing阵营的一个倡导者。 回到上个世纪90年代,曾几何时有3家庞大的Smalltalk公司——IBM、Parc-Place和 Digitalk。在90年代初期3家公司的市场份额大致相等,生活是美好的。Parc-Place采用仿窗口部件(emulated widgets)的设计(即Swing的设计),IB...

顺其自然~专栏 2258

使用 MATLAB/Simulink 对一个开关磁阻电机进行建模

*开关磁阻电机(Switched Reluctance Motor, SRM)**是一种新型的无刷电机,以其简单的机械结构、宽广的调速范围和较高的效率在工业应用中得到了广泛关注。SRM的独特之处在于其定子和转子均为凸极结构,并且通过改变绕组电流的方向来实现转矩的产生和控制。本教程将详细介绍如何使用对一个开关磁阻电机进行建模,并探讨其基本控制策略,特别是针对双凸极结构的SRM。本文介绍了如何使用构建一个开关磁阻电机的双凸极结构模型,并探讨了其基本控制策略。

amy_mhd的博客 203

什么是 EventQueue.invokeLater,需要用吗?

起因:什么是 EventQueue.invokeLater,需要用吗?在上一节中,给出了一个简单的Java图像文件查看器viewer的源代码,其中有一段代码为:EventQueue.invokeLater(new Runnable() { public void run() { JFrame frame = new ImageViewerFrame(); frame.setT...

m0_37732829的博客 1万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

EventQueue事件

当在其他线程中执行费时的业务处理时,

tan313的专栏 2248

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

关于使用EventQueue.invokeLater的原因

EventQueue.invokeLater(new Runnable() { public void run() { JFrame frame = new ImageViewerFrame(); frame.setTitle("ImageViewer"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); .

黄佳俊的博客 842

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Java Swing 中使用 EventQueue

public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { new Loginform().setVisible(true); ...

weixin_30746117的博客 576

[转帖]Swing中的EventQueue

最近在看多线程的东西,Swing中的EventQueue负责所有AWTEvent(以及其子类)的分发,以后如果要定义自己的ProgressBar可能会用到,先记下来。 EventQueue简单工作原理 简单来讲,在EventQueue中有一个dispatchThread,这是一个线程类,负责事件的分发,当Queue中有事件的时候,它会摘取前面的事件并分发给相应的对象进行处理,等处理完之后再获取下...

daniel.wuz 260

Java | 为什么要加EventQueue.invokeAndWait

集合上网搜索的各种结果,做个总结什么的: 第一:java的GUI都是的单线程,应该使用事件调度线程去执行,如果没意思使用事件调度线程的话,可能造成死锁。但是在小的程序中,这种现象(死锁)不会发生的;大的应用程序中才会出现这种现象! 第二:public class EventQueueextends ObjectEventQueue 是一个与平台无关的类,它将来自于底层同位体类和受信任的应用程序类的事件列入队列。 第三:在Java中Swing是线程不安全的,是单线程的设计,这样的造成结果就是:只能从事件

黄佳俊的博客 389

java.awt.eventqueue_java.awt.EventQueue.invokeLater解释

我很好奇为什么我们必须使用它java.awt.EventQueue.invokeLater来控制挥杆部件。为什么我们不能在普通线程中这样做?幕后到底发生了什么?从我注意到的情况(如果有),JFrame可以在不出现任何错误的情况下从主线程将可见性设置为true或false,并且它确实起作用。那么我到底通过使用实现了java.awt.EventQueue.invokeLater什么呢?我也完全知道我可...

weixin_33196106的博客 764

EventQueue.invokLater学习

在写Java swing程序的时候遇到了一个EventQueue.invokLater,用来创建一个线程,展示新窗体的,之前写窗体程序都是直接实例化窗体对象,没有使用过这个方法,所以在这里总结一下EventQueue.invokLater的使用。 一、EventQueue.invokLater是什么?为什么要是用它?  ①在JDK手册中查询到的内容如下: EventQueue是一个与平台无关

Tiger_shl的博客 2239

JAVA awt eventqueue_如何用自己的实现替换AWT EventQueue

小心java 1.7。有一个错误。由rancidfishbreath发布的解决方案对于java 1.6来说是完美的,但是导致Swing应用程序永远不会退出java 1.7。在JDK 1.7下,你必须在Event Dispatch线程中安装新的EvenQueue ...并在JDK 1.6之外安装它... ...写一次,到处运行;-)这是一个通用的解决方案......希望,1.8不会改变它;-)imp...

weixin_31992389的博客 324

使用eventqueue.invokelater()好处、原因

EventQueue.invokeLater(new Runnable() {             public void run() {                 try {                 Array1 frame = new Array1();                     frame.setVisible(true);             

sinolzeng的专栏 1万+

javax.swing

提供一组“轻量级”(全部是 Java 语言)组件,尽量让这些组件在所有平台上的工作方式都相同。(1)swing:https://baike.so.com/doc/6758892-10428879.html (2)swing之eventqueue简介:http://www.360doc.com/content/12/1022/01/820209_242886827.shtml (2)awt:htt

baidu_36583119的博客 727

Exception in thread “AWT-EventQueue-0“ java.lang.NullPointerException

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。bookType.setModel(newDefaultComboBoxModel(newString[]{“小说”,“玄幻”,“文学”,“历史”,“经济”}));“编号”,“名称”,“作者”,“出版社”,“价格”,“类型”...

m0_67393686的博客 1332

Swing JFrame使用实例

import java.awt.EventQueue; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JOptionPane; public class MyFrame extends JFrame{ priv...

qq_29280699的博客 332
上一篇: 在Swing的JEditorPane控件中实现超级链接的CSS定义
overcast
博客等级 码龄25年 3粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值