今天早些时候我试图看看我是否可以回答这个问题。我意识到我并不完全理解Event Dispatch Thread
(EDT)。谷歌搜索既证实了这一点,又对此有所帮助,并澄清了我为什么不这样做。(这也可能与理解有关。)
该代码设置了一个 GUI,然后(如前面的问题)更新一个文本字段,直到取消设置一个标志。
我有几个问题/要求。
请解释为什么如果两个调用(to
swingInit
和doIt
)都在invokeLater
块之外(如图所示),下面的代码运行良好,因为这两个调用都会影响或查询 GUI,但都没有在 EDT 上执行(是吗?)。这不是招致失败吗?如果调用
swingInit
是 inside 和doIt
outside ,代码也会运行invokeLater
。所以swingInit
在 EDT 上执行,但不应该在doIt
EDT 上执行不是问题吗?(我很惊讶这行得通。我应该是吗?)我想我明白为什么如果
doIt
在里面invokeLater
不管它在哪里都会挂起swingInit
:目的invokeLater
只是初始化GUI(对吗?)。应该
doIt
只在 EDT 上启动(可能从发生的事件开始),但肯定不能在invokeLater
块内启动?
(EDT 概念的历史很有趣。并非总是如此。请参阅上面的“为什么我不理解它”的链接。)
import static java.awt.EventQueue.invokeLater;
import java.awt.event.*;
import javax.swing.*;
public class Whatever
{
static boolean flag = true;
static JTextField tf = new JTextField("Hi",20);
static JPanel p = new JPanel();
static JFrame f = new JFrame();
static JButton b = new JButton("End");
public static void main(String[] args)
{
swingInit();
invokeLater
(
new Runnable()
{
@Override
public void run()
{
// swingInit();
// doIt();
}
}
);
doIt();
}
static void swingInit()
{
b.addMouseListener
(
new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
flag = false;
JOptionPane.showMessageDialog(null,"Clicked... exiting");
System.exit(0);
}
}
);
p.add(tf);
p.add(b);
f.add(p);
f.setVisible(true);
f.pack();
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
static String getInfo(){
return "Hello... " + Math.random();
}
static void doIt(){
while(flag)
tf.setText(getInfo());
};
}