我最近开始学习和探索 Java 中 GUI 编程的基础知识。
编程已经有一段时间了,我只做过后端工作或工作,因此我最接近的用户界面是命令控制台(我知道这很尴尬)。
我正在使用 Swing,据我所知,这意味着我也在使用 AWT。
我的问题是基于这段代码:
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new frame.setVisible(true);
}
} );
我已经研究这个问题有一段时间了,因为我想完全理解这段奇怪的代码,并且多次遇到“事件调度线程”这个术语。如果我错了,请纠正我,但据我了解;它与使用多个线程以及 Java Swing 如何解释这些线程有关。我还收集到上面的代码用于确保所有线程在创建窗口之前都是“安全的”,因此调用Later?
我读过:
“您只能从事件调度线程调用对框架进行操作的方法”
并且只有在某些情况下才能从 main 方法调用对框架进行操作的方法。
有人可以向我解释一下事件调度线程到底是什么吗?
它与多个执行线程有何关系以及从主方法调用这些线程如何不安全?另外为什么我们需要这个invokeLater?
我们不能像创建任何其他对象一样创建窗口吗?
我的研究遇到了一些障碍,因为我没有掌握这些关系和想法。
附带说明的是,我喜欢将我的知识建立在深入理解的基础上,因为我相信这会带来最好的整体结果,从而带来最好的项目。如果我深入了解某些东西是如何工作的,那么您可以有效地使用这些技巧和调整,而不是仅仅将它们重复到代码中,所以请不要害怕给我一些额外深入的解释并拓宽我的知识。
谢谢。
The 事件派发线程 https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html是一个由 AWT 管理的特殊线程。基本上,它是一个在无限循环中运行的线程,处理事件。
The java.awt.EventQueue.invokeLater https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/java/awt/EventQueue.html#invokeLater(java.lang.Runnable) and javax.swing.SwingUtilities.invokeLater https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/swing/SwingUtilities.html#invokeLater(java.lang.Runnable)方法是提供将在事件队列上运行的代码的一种方式。编写在多线程环境中安全的 UI 框架非常困难,因此 AWT 作者决定只允许在单个特殊线程上发生对 GUI 对象的操作。所有事件处理程序都将在此线程上执行,所有修改 GUI 的代码也应在此线程上运行。
现在,AWT 通常不会检查您是否没有从另一个线程发出 GUI 命令(C# 的 WPF 框架确实这样做),这意味着可以编写大量代码并且对此几乎不可知,并且不会遇到任何问题。但这可能会导致未定义的行为,因此最好的办法是始终确保 GUI 代码在事件调度线程上运行。invokeLater
提供了一种机制来做到这一点。
一个典型的例子是您需要运行长时间运行的操作,例如下载文件。因此,您启动一个线程来执行此操作,然后在完成后,您使用invokeLater
更新用户界面。如果你没有使用过invokeLater
相反,您只是直接更新 UI,则可能会出现竞争条件,并且可能会发生未定义的行为。
维基百科有更多信息 http://en.wikipedia.org/wiki/Event_dispatching_thread
另外,如果您好奇为什么 AWT 作者不只是使工具包成为多线程,here https://community.oracle.com/blogs/kgh/2004/10/19/multithreaded-toolkits-failed-dream是一篇好文章。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)