为什么我的样板Java桌面应用程序JFrame在main方法中使用EventQueue.invokeLater?

时间:2011-09-16 02:25:39

标签: java swing

我正在使用最新的Eclipse和GWT Designer来用Java创建swing应用程序。 我的应用程序窗口中的主要功能(这是一个javax.swing.JFrame)在工具生成的auto中如下所示:

    /* launch the application */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                AppWindow window = new AppWindow();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

这似乎是围绕着这可能是一个很大的噪音:

public static void main(String[] args) {
            try {
                AppWindow window = new AppWindow();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }


}

我已经读过在某些情况下需要EventQueue.InvokeLater技术,而另一个问题则询问在何处使用它here

我的问题更简单;为什么在代码生成器中会自动执行此操作?为什么main应该快速返回并让事件队列稍后创建应用程序窗口?难道不会阻止这一点吗?为什么JFrame自动生成的设计器会执行此EventQueue?我试图在启动和显示表单方面看到一些不同,无论这个代码是以更简单的方式还是更难的方式完成,我只能暂时断定这有一些好处,这些好处在初学者制作的小型演示应用程序中不可见像我一样,也许在现实世界的大型复杂Jframe类中,这种延迟/排队策略有一些好处吗?

2 个答案:

答案 0 :(得分:7)

根据您的应用程序及其使用方式,可能会在调用EventQueue方法之前或期间在屏幕上绘制某些内容(因此使用main) 。应在Event Dispatch Thread上进行修改任何UI组件的调用,这包括将应用程序设置为可见。

因此,为了安全起见,在EDT上启动应用程序是一种很好的做法。

  

为什么在代码生成器中会自动执行此操作?

它不会受到伤害,它很容易产生,并且被认为是良好的做法。

  

为什么main应该快速返回并让事件队列稍后创建应用程序窗口?

有可能正在使用main的某个其他应用程序调用{​​{1}}方法,并且可能已在屏幕上绘制了某些内容。如果您直接在EDT中绘制应用程序,则您的应用程序可能正在更改某些正在由main上的某些内容处理的组件,并且可能已在屏幕上绘制。

所以为了安全起见,如果这种情况发生,你应该把它留给EDT来绘制你的应用程序,这样它就可以在它不会干扰任何其他事情的时候做到。

  

不会阻止这一点吗?

除非通过双击桌面图标启动用户启动的JVM进程之外的其他内容EDT,否则当main返回时,只要有某些内容,它就不会有所作为在屏幕上。

  

我只能暂时断定这有一些好处,这些好处在像我这样的初学者制作的小型演示应用程序中不可见

你是对的 - 大部分时间它可能不会有所作为,但我认为它们包括它因为它很容易生成和放大实施,它不会伤害,它将是良好做法的例证。

答案 1 :(得分:2)

1)为什么在try-catch-finally中构建Swing GUI,我看不出任何原因,分割创建非线程安全GUI和非线程安全代码到分离线程,

2)Swing不是线程安全的,然后在pack() + setVisible(true)

的所有情况下都是正确的
  • 最后一个GUI相关代码行

  • 包装到invokeLater

  • 忘记了一些代码示例的例子.Dypots,这个论坛,另一个论坛,确定这些代码有效,但风险无论什么/一切都可能发生

  • 正确的Swing GUI启动

例如

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            AppWindow window = new AppWindow();
            window.frame.setVisible(true);            
        }
    });
  }

3)是否有一些Serializable,Custom L&F然后(更好的是)包装到invokeAndWait