invokeLater和invokeAndWait

SwingUtilities的invokeLater和invokeAndWait Swing程序的线程处理 前言 因为很多人会见到一些源代码中调用SwingUtilities的invokeLater或者invokeAnd-Wait方法,但是却不理解它们到底起到了什么作用,本文的目标就是让你理解这两个方法的意义。本文是swing编程基础且不可越过的一节。而且,如你所见,本文的副标题是“Swing程序的线程处理”,其实这是对本文内容更好的概括。 事件派 阅读详情

本人最近想写一个仿QQ,初学Swing对线程机制不太了解,所以在网上搜集了一些资料,结合自己的一些代码和想法,现将Swing线程机制以及invokeLater和invokeAndWait的学习所得分享给大家,文中不免有借鉴别人的“名言”,还请谅解。

Swing线程机制

 

 

首先swing是单线程的,这个是这篇文章的前提,也是意义所在,当swing界面程序启动的时候,会启动3个进程,
1
、主线程
2
、系统工具包线程:负责捕获操作系统事件,然后将事件转换成swing的事件,然后发送到事件派发线程EDT
3
、事件派发线程(EDT):将事件派发到各个组件,并负责调用绘制方法更新界面

所有的事件,例如键盘,鼠标事件,都会由工具包线程转换成swing事件,然后放到事件队列EventQueue中,而这个EventQueue的派发机制是由EDT来管理的。

所以任何修改组件状态的方法都应该在EDT中执行,包括构造方法。Swing这样的构造原理经常会造成的情况就是,在EDT中执行长时间的事件,使EDT不能及时响应更新界面的事件,就是所说的界面卡住,这种不光是新手就是比较熟练的程序员也会犯的一个错误。所以必须避免在EDT中执行长时间的操作,而避免的方法就是多线程,启动另外的线程来处理冗长的操作,比如操作数据库,读写文件等,在这过程中可能要更新界面来给用户以提示,比如显示一个进度条,过一段事件更新一下界面,但是在EDT以外的线程中更新界面都是无效的,这在前面已经说过,要更新界面就要将对界面的更新操作放到EDT中,但是事件又是在另外的线程中执行的,要解决这个问题就要使用SwingUtilities提供的一个方法了 invokeLater,

Java代码 
  1. public void actionPerformed(ActionEvent e){  
  2.     new Thread(new Runnable(){  
  3.             //do something  
  4.             SwingUtilities.invokeLater(new Runnable(){  
  5.                 pulic void run(){  
  6.                     //update the GUI  
  7.                 }      
  8.         });  
  9.     }).start;  
  10. }  

 
这个方法的作用就是将一个更新界面的任务放到EDT中,EDT会在适当的时候进行调用以更新界面。invokeLater负责创建一个含有Runnable的特定事件,并让其在EDT中排队等待调用,当被调用时就会运行Runnable中的run方法进行派发。

 

invokeLater和invokeAndWait的区别

 

与invoikeLater一样,invokeAndWait也把可运行对象排入事件派发线程的队列中,invokeLater在把可运行的对象放入队列后就返回,而invokeAndWait一直等待知道已启动了可运行的run方法才返回。如果一个操作在另外一个操作执行之前必须从一个组件获得信息,则invokeAndWait方法是很有用的。

一般我们用到invokeLater,都是为了执行事件派发线程中的代码,将一段更新UI事件的代码派发到EventQueue中,但是我们可以从事件派发线程中调用invokeLater,却不能从事件派发线程中调用invokeAndWait,下面我们用代码来例证它们的不同:

 

SwingConsole.java文件:

Java代码 
  1. package swing.utilities;  
  2. import javax.swing.*;  
  3. public class SwingConsole {  
  4.     public static void run(final JFrame f, final int width, final int height){  
  5.     SwingUtilities.invokeLater(new Runnable(){  
  6.         public void run(){  
  7.         f.setTitle(f.getClass().getSimpleName());  
  8.         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  9.         f.setSize(width, height);  
  10.         f.setVisible(true);  
  11.         }  
  12.     });  
  13.     }  
  14. }  

 TestAction.java文件:

Java代码 
  1. import java.awt.BorderLayout;  
  2. import java.awt.FlowLayout;  
  3. import java.awt.event.ActionEvent;  
  4. import java.awt.event.ActionListener;  
  5. import javax.swing.*;  
  6. import swing.utilities.SwingConsole;  
  7.   
  8. public class TestAction extends JFrame {  
  9.     private static final long serialVersionUID = -7462155330900531124L;  
  10.     private JButton jb1 = new JButton("确定");  
  11.     private JTextField txt = new JTextField(10);  
  12.   
  13.     public TestAction() {  
  14.     jb1.addActionListener(new ActionListener() {  
  15.         public void actionPerformed(ActionEvent e) {  
  16.         String name = ((JButton) e.getSource()).getText();  
  17.         txt.setText(name);  
  18.         }  
  19.     });  
  20.     setLayout(null);  
  21.     add(txt);  
  22.     add(jb1);  
  23.     txt.setBounds(50, 100, 200, 30);  
  24.     jb1.setBounds(270, 100, 70, 30);  
  25.     }  
  26.   
  27.     public static void main(String[] args) {  
  28.     SwingUtilities.invokeLater(new Runnable() {  
  29.         public void run() {  
  30.         SwingConsole.run(new TestAction(), 500, 500);  
  31.         }  
  32.     });  
  33.   
  34.     }  
  35.   
  36. }  

 我们在启动main线程的时候就把整个SwingConsole派发到EventQueue中,而本身SwingConsole已经处在EventQueue中,我们调用invokeLater没问题,运行正常!

 

再看我们修改之后的:

 

SwingConsole.java文件:

Java代码 
  1. package swing.utilities;  
  2. import java.lang.reflect.InvocationTargetException;  
  3.   
  4. import javax.swing.*;  
  5. public class SwingConsole {  
  6.     public static void run(final JFrame f, final int width, final int height){  
  7.     try {  
  8.         SwingUtilities.invokeAndWait(new Runnable(){  
  9.             public void run(){  
  10.             f.setTitle(f.getClass().getSimpleName());  
  11.             f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  12.             f.setSize(width, height);  
  13.             f.setVisible(true);  
  14.             }  
  15.         });  
  16.     } catch (InterruptedException e) {  
  17.         throw new RuntimeException(e);  
  18.     } catch (InvocationTargetException e) {  
  19.         throw new RuntimeException(e);  
  20.     }  
  21.     }  
  22. }  

TestAction.java文件:

与前面一样

 

运行结果,出现异常:Exception in thread "AWT-EventQueue-0" java.lang.Error: Cannot call invokeAndWait from the event dispatcher thread

在这里,我们把SwingConsole中的invokeLater改成了invokeAndWait,而之前SwingConsole已经处在EventQueue中了。

 

所以我们可以总结出它们的不同:可以从事件派发线程中调用invokeLater,却不能从事件派发线程中调用invokeAndWait,从事件派发线程调用invokeAndWait的问题是:invokeAndWait锁定调用它的线程,直到可运行对象从事件派发线程中派发出去并且该可运行的对象的run方法激活,如果从事件派发线程调用invoikeAndWait,则会发生死锁的状况,因为invokeAndWait正在等待事件派发,但是,由于是从事件派发线程中调用invokeAndWait,所以直到invokeAndWait返回后事件才能派发。

 

在这里我们还可以看到,在main函数里,我们在一开始就把整个操作都置于EventQueue中,这样虽然安全,但是不适合新手,因为新手很容易犯刚才那样的错误,一不小心就用了invokeAndWait而产生死锁。对于swing中的线程,我也还没有找到理想的处理机制,所以暂时就先到此,以后有经验才跟大家分享吧。

win x64下安装oracle 12c出现[INS-30131]报错的解决方案 问题:  win x64下安装oracle 12c出现[INS-30131]报错的解决方案 安装oracle11g碰到“无法访问临时位置”的问题,详细信息如下: INS-30131] 执行安装程序验证所需的初始设置失败。 原因 - 无法访问临时位置。   操作 - 请确保当前用户具有访问临时位置所需的权限。   附加信息:  - 所有节点上的框架设置检查都失败   阅读详情

相关推荐

Keil MDK v6迁移指南:从AC5到AC6的编译器升级与工程适配

编译器是嵌入式开发的底层基石,决定了代码的执行效率与工程的可维护性。随着ARM工具链向LLVM/Clang架构演进,Arm Compiler 6(AC6)正逐步取代经典的AC5,成为Keil MDK的核心编译引擎。AC6在C11标准支持、代码优化、诊断信息及LTO链接优化上全面超越AC5,但迁移过程中往往伴随内联汇编重写、类型检查严格化、库兼容性等问题。理解编译器差异、掌握CMSIS-Toolbox的工程描述机制,能帮助嵌入式工程师在Cortex-M系列项目中平滑过渡。本文结合Cortex-M4量产工程实战

weixin_29189363的博客 236

Swing线程机制以及invokeLater和invokeAndWait

本人最近想写一个仿QQ,初学Swing对线程机制不太了解,所以在网上搜集了一些资料,结合自己的一些代码和想法,现将Swing线程机制以及invokeLater和invokeAndWait的学习所得分享给大家。 Swing线程机制 首先swing是单线程的,这个是这篇文章的前提,也是意义所在,当swing界面程序启动的时候,会启...

cantellow 466

WPS专业版自带字体

WPS专业版其中一个好处就是自带了部分有版权的字体,就算你安装了没买授权,他也会给你在系统里面安装上这些字体,至于没授权继续用合不合规我不知道。但是带来的实实在在的好处就是有些子他支持的全啊。 /usr/share/fonts/wps-office/FZWBK.TTF: 方正魏碑_GBK,FZWeiBei\-S03:style=Regular /usr/share/fonts/wps-office/FZFSK.TTF: 方正仿宋_GBK,FZFangSong\-Z02:style=Regular /us

chenqioulin的博客 5697

事件分发线程

《FilthyRichClients》读书笔记-SwingのEDT 《FilthyRichClients》读完了前几个章节,现将我的体会结合工作以来从事Swing桌面开发的经验,对本书的一些重要概念进行一次分析,对书中的一些遗漏与模糊的地方及时补充,同时使读者消除长期以来“Swing性能低、界面丑陋”诸如此类的旧观念。读书笔记仅谈谈我对Swing的理解,难免会犯错误,还望广大读者指教。 ...

nettianjie的博客 473

【学习笔记】《基于φ-OTDR的分布式扰动传感系统定位算法研究-北交-通信与信息系统-吴》重点笔记

一、绪论 1.1 引言 光纤传感器的优点:跟电子传感器相比较,光纤传感器有诸多独特的优势:对电磁干扰免疫;具有很好的绝缘性和耐腐蚀性;灵敏度高,可测量微弱信息;可实现大范围监测和分布式传感,仅需一根传感光纤,更为经济便捷;传感光纤体积小、重量轻、可形变,适用于一些特殊应用场所;还有无需供电、耐高温、便于组网等等优点 光纤传感器的感知信号的方法:当探测光入射到光纤中时会发生散射并产生各种散射光...

qq_36045093的博客 2万+

Lumerical官方案例、FDTD时域有限差分法仿真学习(三)——环形谐振器(Ring resonator)之第二&第三部分

二、使用 MODE 的参数提取和蒙特卡罗 三、最终参数提取

weixin_45719141的博客 1万+

java edt,java – 从EDT调用invokeAndWait

我有一个问题跟随我的previous problem.我也有代码基地的其他地方的代码SwingUtillities.invokeAndWait,但当我删除这个gui不刷新.如果我不删除它我得到的错误是:Exception in thread "AWT-EventQueue-0" java.lang.Error: Cannot call invokeAndWait from the event di...

weixin_39556891的博客 206

LiteratureReading:[2022] Reformer: The Efficient Transformer

所属机构:加州大学伯克利分校(U.C. Berkeley)和谷歌研究(Google Research)。电子邮件:kitaev@cs.berkeley.edu所属机构:谷歌研究(Google Research)。电子邮件:lukaszkaiser@google.com所属机构:谷歌研究(Google Research)。电子邮件:levskaya@google.com大型Transformer模型在许多任务上通常能够达到最先进的结果,但训练这些模型可能非常昂贵,尤其是在处理长序列时。

有朋自远方来,不亦乐乎。 1211

Swing进度条

读条进度,直接从public static void main可以正常显示,但是actionPerformed触发则不行 Swing的JFrame为什么同样情况不刷新_哔哩哔哩_bilibilij 对比见p1 解决视频p2 解决办法 参考 https://www.cnblogs.com/qingxinblog/articles/3293303.html https://blog.youkuaiyun.com/sujianxin2012/article/details/45921087 调用对象 调用

walkuere的博客 394

Part03 数据结构

本文介绍了CSP-S初赛中常见的高级数据结构及其实现,包括: 线性结构:双端栈、双端队列、单调队列、优先队列和ST表,重点分析了它们的特点、时间复杂度及典型应用场景。 集合与森林:并查集(带路径压缩和按秩合并)和树的孩子兄弟表示法,展示了多叉树转化为二叉树存储的方法。 特殊树结构:包括二叉堆、树状数组、线段树和字典树,详细说明了它们的构建、查询和更新操作,特别强调了线段树的递归实现和字典树的前缀匹配特性。 每种数据结构都配有核心C++代码实现,涉及数组模拟、动态规划和树形结构等编程技巧,适合算法竞赛选手快速

weixin_43863957的博客 1179

光耦继电器电路分析

光耦电路的分析笔记

MingYue_SSS的博客 6873

SwingUtilities类中的invokeLater()和invokeAndWait()方法理解

      在理解SwingUtilities类中的.invokeLater()和invokeAndWait()两种方法之前,需要先了解清楚Swing线程机制。Swing程序通常包括三种类型的线程:①初始化线程(Initial Thread);②任务线程(Work Thread);③事件调度线程(Event Dispatch Thread,EDT)。      初始化线程主要负责启动程序的UI界面...

样young的博客 4735

STM32H7系列QSPI内存映射模式与MPU配置冲突分析

本文分析了STM32H7系列QSPI内存映射模式与MPU配置冲突导致系统卡死的问题。通过解析内存保护管理单元机制,提供了MPU配置调整方案,包括禁用MPU或精细配置QSPI区域权限,确保内存映射模式正常访问外部Flash,避免HardFault错误。

js777的博客 740

SwingUtilities中invokeLater,invokeAndWait的作用和区别

invokeLater,invokeAndWait是专门给Swing的线程安全准备的两个方法,Swing是线程不安全的,是单线程的设计,复杂的Swing交互一定要考虑多线程的问题。 因此只能从事件派发线程访问将要在屏幕上绘制的Swing组件。事件派发线程是调用paint和update等回调方法的线程,它还是事件监听器接口中定义的事件处理方法,例如,ActionListener中的 act

cuiyaoqiang的博客 3414

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

SwingUtilities中invokeLater和invokeAndWait的介绍

星期日 2007年08月05日SwingUtilities中invokeLater和invokeAndWait的介绍 SwingUtilities中invokeLater和invokeAndWait介绍   在Java中Swing是线程不安全的,是单线程的设计,这样的造成结果就是:只能从事件派发线程访问将要在屏幕上绘制的Swing组件。事件派发线程是调用paint和update等回

数据就是一切 1382

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

SwingUtilities中invokeLater和invokeAndWait介绍

SwingUtilities中invokeLater和invokeAndWait介绍 在Java中Swing是线程不安全的,是单线程的设计,这样的造成结果就是:只能从事件派发线程访问将要在屏幕上绘制的Swing组件。事件派发线程是调用paint和update等回调方法的线程,它还是事件监听器接口中定义的事件处理方法,例如,ActionListener中的actionPerformed方法在...

我有故事你有酒? 224

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

SwingUtilities.invokeLater 和SwingUtilities.invokeAndWait

SwingUtilities.invokeLater 和SwingUtilities.invokeAndWait invokeAndWait:这个程序必须等这个线程的东西执行完才能执行(存在等待)。 invokeLater:这个程序可以和线程对象可以并行,异步地执行。 一般应用于 界面上(JF)。 SwingUtilities.invokeLater : SwingU...

千寻的华尔兹的博客 430

java invokelater 以及invokeandwait

SwingUtilities中invokeLater和invokeAndWait介绍 在Java中Swing是线程不安全的,是单线程的设计,这样的造成结果就是:只能从事件派发线程访问将要在屏幕上绘制的Swing组件。事件派发线程是调用paint和update等回调方法的线程,它还是事件监听器接口中定义的事件处理方法,例如,ActionListener中的actionPerformed方法在事件...

weixin_30797027的博客 192

SwingUtilities中invokeLater和invokeAndWait介绍(转载)

SwingUtilities中invokeLater和invokeAndWait介绍   在Java中Swing是线程不安全的,是单线程的设计,这样的造成结果就是:只能从事件派发线程访问将要在屏幕上绘制的Swing组件。事件派发线程是调用paint和update等回调方法的线程,它还是事件监听器接口中定义的事件处理方法,例如,ActionListener中的actionPerformed方法在事件

whymin的专栏 435

面试题解答系列:java invokelater 以及invokeandwait

SwingUtilities中invokeLater和invokeAndWait介绍 在Java中Swing是线程不安全的,是单线程的设计,这样的造成结果就是:只能从事件派发线程访问将要在屏幕上绘制的Swing组件。事件派发线程是调用paint和update等回调方法的线程,它还是事件监听器接口中定义的事件处理方法,例如,ActionListener中的actionPerformed方法在事件派发...

AD_plus的博客 378

java多线程学习之14invokeLater()方法与invokeAndWait()的使用

invokeLater();与invokeAndWait();的使用:(这两个方法可以在"非"事件分派线程中被调用!)这两个方法都属于SwingUtilities类是两个静态成员方法(类方法!) —————————————————————————————————————————————————————————————————————————————— swing技术下有个工具类:SwingUtilities这个类很奇特: 首先SwingUtilities.isEventDispatchThread()当其返

zy103118的博客 1343
上一篇: SwingUtilities中invokeLater
下一篇: Http之Get/Post请求区别
legendmoheNote
博客等级 码龄16年 12粉丝 7原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值