开发者

Why after creating a JFrame object and setting it as visible, the program will not end executing?

开发者 https://www.devze.com 2023-04-06 21:44 出处:网络
My program looks like this: import java.awt.*; import javax.swing.*; public class Main { public static void main开发者_Go百科(String[] args) {

My program looks like this:

import java.awt.*;
import javax.swing.*;

public class Main {
    public static void main开发者_Go百科(String[] args) {
        JFrame jf = new JFrame();
        jf.setSize(new Dimension(200, 200));
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);
    }
}

I'm just confused why after JVM's quitting from main(), my program does not end instantly? I noticed that if I remove the line "jf.setVisible(true);", it will end.

Is it implemented though techniques like garbage collecting or class destructors? I'm interested that if I want to write something similar, how could I do it.


The reason is that when you call setVisible(true) on the JFrame, behind the scenes a non-daemon thread is started, and the JVM will not exit until all non-daemon threads terminate.

Please have a look here for more on AWT/Swing Threading issues.
It states:

"There is at least one alive non-daemon thread while there is at least one displayable AWT or Swing component within the application (see Component.isDisplayable)."

While this is for Java 1.5, I think that it is still valid information.

Also, I believe that the Event Dispatch Thread or EDT is not a daemon thread, and so it is another thread associated with Swing that drives this.

Edit 1
This suggests that the EDT is in fact a non-Daemon thread:

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class IsEdtDaemon {
   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
             JFrame frame = new JFrame();
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setVisible(true);

             System.out.printf("Is the current thread the EDT thread: %b%n",  SwingUtilities.isEventDispatchThread());
             System.out.printf("Is our EDT Thread a daemon thread:    %b%n",  Thread.currentThread().isDaemon());
         }
      });
   }
}

The output from the code is:

Is the current thread the EDT thread: true
Is our EDT Thread a daemon thread: false


When you create the JFrame and make it visible you've created an implicit event listener that is now waiting for an action. If you hadn't set the default close action you would've needed to provide some other way for the application to "know" it can exit.


If you do not call jf.setVisible(true) then your program does construct the JFrame, sets it's dimensions and defines the default close operation, but never draws the JFrame on screen and so it exits. It wouldn't make any sense to create a JFrame if you do not want to ever make it visible.

The behavior one expects from a top-level container like JFrame, would be after setting it to visible to stay up and be used, until someone clicks on the close button which happens because of the jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setting.

Just think about what goes on with any application, i.e. your browser. It starts and stays up until you press the close button or exit the application in another way.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号