Почему после создания объекта JFrame и установки его в качестве видимого программа не прекратит выполнение? - PullRequest
3 голосов
/ 24 сентября 2011

Моя программа выглядит следующим образом:

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

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

Я просто сбит с толку, почему после выхода JVM из main () моя программа не заканчивается мгновенно?Я заметил, что если я удалю строку "jf.setVisible (true);", она закончится.

Реализовано ли это с помощью таких методов, как сбор мусора или деструкторы классов?Мне интересно, что если я хочу написать что-то подобное, как я могу это сделать.

Ответы [ 3 ]

9 голосов
/ 24 сентября 2011

Причина в том, что когда вы вызываете setVisible (true) в JFrame, за кулисами запускается поток, не являющийся демоном, и JVM не завершает работу до тех пор, пока не завершатся все потоки, не являющиеся демонами.

Пожалуйста, ознакомьтесь здесь с более подробной информацией по AWT / Swing Threading .
В нем говорится:

"Существует хотя бы один живой поток, не являющийся демоном, в то время как в приложении имеется хотя бы один отображаемый компонент AWT или Swing (см. Component.isDisplayable )."

Хотя это для Java 1.5, я думаю, что это все еще действительная информация.

Кроме того, я считаю, что поток диспетчеризации событий или EDT не является потоком демона, и поэтому это другой поток, связанный с Swing, который управляет этим.

Редактировать 1
Это говорит о том, что EDT на самом деле не является потоком Daemon:

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());
         }
      });
   }
}

Вывод из кода:

Является ли текущий поток потоком EDT: true
Является ли наша тема EDT потоком демона: false

0 голосов
/ 24 сентября 2011

Если вы не вызываете jf.setVisible(true), тогда ваша программа создает JFrame, устанавливает его размеры и определяет операцию закрытия по умолчанию, но никогда не рисует JFrame на экране и поэтому завершает работу.Не имеет смысла создавать JFrame, если вы не хотите, чтобы он был видимым.

Поведение, которое можно ожидать от контейнера верхнего уровня, такого как JFrame, будет происходить после установки его в видимое состояние, чтобы оно оставалось в рабочем состоянии и использовалось, пока кто-то не нажмет на кнопку закрытия, что происходит из-за настройки jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);.

Подумайте, что происходит с любым приложением, например с вашим браузером.Он запускается и остается до тех пор, пока вы не нажмете кнопку закрытия или не выйдете из приложения другим способом.

0 голосов
/ 24 сентября 2011

Когда вы создаете JFrame и делаете его видимым, вы создали неявный прослушиватель событий, который теперь ожидает действия.Если бы вы не установили действие закрытия по умолчанию, вам нужно было бы предоставить приложению другой способ «знать», что оно может выйти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...