我读了几本关于Java的书。在所有这些中,至少有一章教授GUI编程。在所有这些中,创建一个简单的表单应用程序遵循以下逻辑:
MyFrame.java
public class MyFrame extends JFrame
{
JButton button1;
public MyFrame()
{
button1 = new JButton("Click here.");
}
}
FrameTest.java:
public class FrameTest
{
public static void main(String[] args)
{
MyFrame myFrame = new MyFrame();
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setSize(600, 600);
myFrame.setVisible(true);
}
}
基本上,只需将JFrame子类化为创建表单并将其他组件声明为实例变量,并在构造函数中初始化这些组件。然后创建另一个测试类,在该类中实例化框架子类并调用它的一些方法使其可见。
但在并发课程中,我了解到我们有一个主线程,它在我们创建的每个应用程序中运行main()。据我所知,当我们使用Swing创建GUI应用程序时,我们有另一个线程(Event Dispatcher Thread)。因此,如果我没有记错,在每个基于Swing的GUI应用程序中至少有两个线程。这使得每个GUI应用程序都是多线程的。在我读过的一些文章和教程中,它说Swing不支持多线程,因此只能在Event Dispatcher Thread中创建和修改所有GUI组件,否则可能会出现线程干扰和内存不一致错误。
即使在维基百科(http://en.wikipedia.org/wiki/Swing_%28Java%29)中最简单的例子中,它也是通过invokeLater方法制作的。
那么哪一个是真正的方法?我哪里错了?
答案 0 :(得分:7)
任何UI / Swing组件的所有交互都必须在EDT的上下文中完成
启动应用程序时,在尝试创建/与任何Swing组件交互之前,应确保在EDT中执行。
简单地说,你应该使用像...这样的东西。
EventQueue.invokeLater(new Runnable() {
public void run() {
// Now in the event dispatching thread
}
});
如果需要运行长时间运行的任务或执行任何阻塞任务,则应在单独的线程中执行它。 SwingWorker
在大多数情况下是一个不错的选择,因为它提供了一些简单的机制来将代码重新同步到事件调度线程。
阅读
所以,简短的回答是,是的,所有基于Swing的代码都应该从EDT的上下文中访问/修改/交互
答案 1 :(得分:3)
所以如果我没有弄错的话,在每个基于Swing的GUI应用程序中 是至少两个线程
是。一个是主线程,另一个是EDT(事件调度线程)。
这使得每个GUI应用程序都成为多线程。
是。但在这种情况下,另一个线程不与GUI组件交互。
Swing不支持多线程因此所有GUI组件 应该只在Event Dispatcher Thread中创建和修改 否则线程干扰和内存不一致错误可能会 出现。
是的,绝对正确。这意味着一次只有一个Thread应该与给定的GUI组件交互。
Swing程序员处理以下类型的线程:
程序员不需要提供明确创建的代码 这些线程:它们由运行时或Swing提供 框架。程序员的工作是利用这些线程来创建 一个响应迅速,可维护的Swing程序。