我的Ex1如下:
main(String args[]) {
JFrame frame = new JFrame("Title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Press Here");
ContainerListener container = new ContainerAdapter() {
public void componentAdded(final ContainerEvent e) {
System.out.println("On the event thread? : " +
EventQueue.isDispatchThread());
}
};
frame.getContentPane().addContainerListener(container);
frame.add(button, BorderLayout.CENTER);
frame.setSize(200, 200);
System.out.println("I'm about to be realized: " +
EventQueue.isDispatchThread());
frame.setVisible(true);
}
我的结果是:在事件线程上? :FALSE |我即将意识到:虚假
其他Ex2:
public class GridBagLayoutTester
extends JPanel implements ActionListener{
public GridBagLayoutTester() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
JButton button = new JButton("Testing");
// do something...
button.addActionListener(this);
add(button, gbc);
}
public void actionPerformed(ActionEvent e) {
System.out.println("On the event thread? : " +
EventQueue.isDispatchThread());
}
public static void main(String[] args) {
JFrame frame = new JFrame("GridBagLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(new GridBagLayoutTester(), BorderLayout.CENTER);
frame.setSize(800, 600);
frame.pack();
frame.setVisible(true);
System.out.println("I'm about to be realized: " +
EventQueue.isDispatchThread());
}
}
结果是:我即将意识到:假|在事件线程? :TRUE
我的问题是为什么Ex1- componentAdded()在初始线程中运行,但Ex2- actionPerformed()在EDT中运行?
答案 0 :(得分:3)
关于Java中GUI应用程序的几个事实:
- 在 Java GUI 应用程序中,main()
方法短命,在安排GUI构建后在Event Dispatcher Thread
(EDT)退出。
- 因此EDT's
负责处理GUI 。
现在来到您的代码:
- 初始线程是main()
线程,EDT
是 GUI线程。
- 在EX1中,您强制GUI在main()
线程上运行,这是一种错误的方式,在使用GridBagLayoutTester
的EX2中扩展JPanel ,main()
线程通过将GUI的工作委派给EDT 获得早期机会。
- main()
方法来执行进一步处理GUI的EventQueue.invokeLater()
方法,这将帮助UI响应并避免处理任何非UI工作。
- 此外,Java拥有SwingUtilities
类,可以在UI
和Non-UI
工作UI
之间实现良好的同步分别是1}}和Non-UI
线程。
例如:正确的做法.......
public class Test extends JFrame{
public Test(){
this.setSize(300,300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args){
EventQueue.invokeLater(new Runnable(){
public void run(){
new Test().setVisible(true);
}
});
}
}
答案 1 :(得分:2)
main方法的第一行创建了一个JFrame类型的新对象。这个创建启动一个新线程(实际上它启动了多个线程) - 一个等待事件队列项的新线程。例如,这可以是鼠标点击。 回答你的问题:主线程 - 真正称为“主” - 正在调用主方法的10行代码。这应该在几毫秒内完成。之后主线程消失了,不再存在了。 但正如我之前所说,AWT / Swing库在内部创建了一个(是的,更多)线程,它基本上是一个无限循环检查用户输入。并且从该线程调用actionPerformed方法。
我的建议:
在main方法的第一行创建一个断点。
调试程序。
当调试器在第一行停止时(在创建JFrame之前)转到命令行并启动jconsole
转到标签主题
通知主题“主要”
执行单行(新JFrame)
注意线程“main”和线程共存“AWT - *”
按调试器播放,“主”将消失,但AWT将持续