2009-10-15 76 views
2

我好奇,以下面的方法之间的差异来创建一个Swing窗口:Swing窗口可以初始化的方式有什么区别?

  1. 使用了java.awt.EventQueue.invokeLater()在main();
  2. 在main()中使用SwingUtilities.invokeLater();
  3. 根本不打扰线程,只需实例化JFrame子类并从main调用setVisible(true),而不将其包装到Runnable中;无论如何,这似乎工作。

谢谢。

回答

3

线程记住的事情是“似乎有效”与“在任何情况下都能正常工作”是不一样的。

基本规则是你不应该在事件线程之外创建Swing /操作组件,并且应用程序的主线程是“事件线程之外”。因此,在您的应用程序启动代码中,您应该使用在invokeLater()中创建主窗口。

如果你使用Swing编程,我会使用SwingUtilities版本的invokeLater()。尽管我认为在目前的实现中功能上只是调用另一个,但我想这可能在未来发生变化。

3

SwingUtilities.invokeLater只是叫EventQueue.invokeLater。后者是在Java 1.2中引入的。在此之前,Swing在重新粉刷一个窗户以进入EDT之前进行了一次黑客攻击。我建议java.awt.EventQueue是这种方法的合理位置,也是合理的调用方法。然而,Swing和AWT之间的关系是严重混乱的。

很少需要继承JFrame,这通常是不好的做法。但不好的做法是Swing的标准。像这样运行多线程可能会遇到问题,但您可能会在自己的计算机上使用它。你可以做的最糟糕的事情是EDT上的初始化和主线程上的一点(有一段时间50/50,FindBugs(所有程序)是否将在单个硬件线程机器上启动)。

+0

“很少有必要继承JFrame,它通常是不好的做法。” - 现在这让我感兴趣。 NetBeans在创建应用程序框架时为我自动执行此操作。你能否详细说明为什么这是一件坏事? – neuviemeporte 2009-10-16 00:28:06

+1

不太清楚继承JFrame的问题。如果你所需要的是JFrame的子类,那么创建一个JFrame的子类...... – 2009-10-16 00:39:47

+0

你非常非常少需要'JFrame'的*子类*。就像你很少需要一个Thread类的子类一样。 – 2009-10-16 00:49:28

相关问题