使用Swing时的执行流程

时间:2012-02-05 13:35:41

标签: java swing workflow event-dispatch-thread

我刚刚开始掌握java中的GUI编程。这是一个简单的程序(来自O'Reilly的“Head First Java”),从表面上来看它很容易理解,但有一个方面我不遵循它。

import javax.swing.*;

public class Test {
    public static void main(String[] args) {

    JFrame frame=new JFrame();
    JButton button = new JButton("click me");

    frame.getContentPane().add(button); 
        frame.setSize(300,300);
    frame.setVisible(true);
    }
}

这个简单的程序在编译和运行时会打开一个窗口,上面有一个按钮。

我不明白的是执行流程正在发生什么。当我运行这个程序时,Test类的静态main方法运行,main()中的所有命令都被执行 - 那么为什么在窗口出现后进程终止呢?为什么我仍然坐在看似无限循环的东西上?什么是循环?

如果我添加行

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
然后我发现结果更加难以理解。当然,现在程序终止了 一旦我关上了窗户。但我再也不明白为什么。框架将在堆栈上,但我没有看到程序流的位置,只是堆栈上存在的东西不足以保持程序存活,当然?我遗漏了一些基本内容,据我所知,我正在阅读这本书。我对这一点感到有点惊讶 - “Head first Java”在指出微妙之处并解释真正正在发生什么之前一直很好,但似乎没有解决这一点(在至少不是我发现的。)

2 个答案:

答案 0 :(得分:4)

  

为什么在窗口出现后进程终止?

因为Java虚拟机仅在所有非守护程序线程完成后才退出。虽然不明显,但程序中实际上有两个线程:主线程和event dispatching thread,它执行与Swing GUI组件相关的所有操作。只要任何GUI组件可见,事件调度线程就会继续运行。

实际上,程序虽然可能有效但是错误,因为您正在从主线程创建和访问Swing组件。您应该在事件调度线程中执行所有GUI工作。也就是说,它应该是这样的:

public static void main(String[] args) {

  EventQueue.invokeLater(new Runnable() {
    JFrame frame=new JFrame();
    JButton button = new JButton("click me");

    frame.getContentPane().add(button); 
    frame.setSize(300,300);
    frame.setVisible(true);
  });
}

答案 1 :(得分:1)

当最后一个非恶魔线程死亡时,Java进程终止。通常只有一个main线程。当您显示Swing组件时,会启动其他非恶魔线程以进行事件调度和GUI击落。当最后一个顶级组件被释放时,它们终止。在您的示例中,main线程在离开main方法后死亡。您可以使用调试器或JDK工具中的jvisualvm来查看线程。

GUI流程的其余部分是事件驱动的。当你例如单击框架的关闭按钮,将生成一个事件,并将其发送到事件调度线程中的相应侦听器。

JFrame.EXIT_ON_CLOSE设置为默认关闭操作就像向帧中添加默认事件侦听器一样。这是一个相当苛刻的问题,它只关闭JVM而不考虑应用程序状态的其余部分。