Закрыть JFrame из процесса JButton, оставшегося в живых

У меня есть класс, разработанный с помощью windowbuilderpro, который я хочу закрыть также с помощью JButton, а не с помощью стандартной кнопки X в окне, поэтому вот пример класса:

public class MainWindow {

public JFrame frame;

public MainWindow() {
    initialize();
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  }

public void show() {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                //Show the main Frame
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }   
        }
    });
}

Когда я закрываю окно с помощью кнопки X, окно закрывается правильно, и процесс завершается.

Когда я вместо этого закрываю JButton, у которого есть этот слушатель:

mntmExit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
               //Close the application main form
               frame.setVisible(false);
               frame.dispose();
            }
        });

окно кадра корректно закрывается, но процесс остается живым... Почему?

Процесс жив

Как вы можете видеть, существует поток AWT-Shutdown, который непрерывно запускается и завершается. Как я могу добиться такого же поведения кнопки X, которая закрывает также процесс приложения?

Примечания:

Система.выход(0); не подходит, потому что он завершает приложение также, если есть другой фоновый поток, а я этого не хочу. Класс MainWindow должен закрыть и освободить свой ресурс, то же поведение, что и при закрытии приложения с помощью кнопки X, которая закрывает экземпляр MainWindow, но если есть фоновый поток, он не убивает их, а ждет, пока они закончат свою работу...

Окружающая среда:

  • JDK 7
  • Затмение 3.7.1

person aleroot    schedule 14.10.2011    source источник
comment
Кое-что, что я должен был сказать раньше: - Чтобы быстрее получить помощь, опубликуйте SSCCE. В SSCCE незанятый таймер был бы очевиден. И поскольку я упоминаю код, не могли бы вы выбрать один из логических стилей отступа кода и придерживаться его в будущих сообщениях? Мне потребовалось больше времени, чтобы переформатировать и понять этот код, чем чтобы превратить его в работающий код.   -  person Andrew Thompson    schedule 14.10.2011


Ответы (3)


не уверен, что вам действительно нужно, это похоже на то, что вы снова и снова создаете новый JFrame, не делайте этого, создайте JFrame один раз и повторно используйте этот контейнер

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // do nothing

frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); // same as setVisible(false)

тогда для наглядности можно только позвонить frame.setVisible(true);

для более удобного переопределения WindowListener вы можете управлять некоторыми событиями

person mKorbel    schedule 14.10.2011
comment
Я создал экземпляр фрейма только один раз, почему, если я закрою форму с помощью кнопки X в заголовке окна, я получу правильное поведение, а вместо этого, если я закрою фрейм, вызывающий dispose, я получу другое поведение? - person aleroot; 14.10.2011
comment
реализует WindowListener, создает одну пустоту, которая разделяет действие от JButton с событиями от WindowListener, хммм реализует SystemTry с JPopumMenu, добавляет JMenuItem с JFrame#setVisible(true); - person mKorbel; 14.10.2011

Все потоки в этом коде останавливаются, когда активируется кнопка x или кнопка Exit. Вы получаете другое поведение?

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

public class MainWindow {

    public JFrame frame;
    JButton mntmExit = new JButton("Exit");

    public MainWindow() {
        frame = new JFrame("Close Me!");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        mntmExit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //Close the application main form
                frame.setVisible(false);
                frame.dispose();
            }
        });
        frame.add(mntmExit);
        frame.pack();
        show();
    }

    public void show() {
        //Show the main Frame
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                MainWindow mw = new MainWindow();
                mw.show();
            }
        });
    }
}
person Andrew Thompson    schedule 14.10.2011
comment
Да, когда я пытаюсь закрыть кадр с помощью кнопки «Выход», поток остается живым, как вы можете видеть на скриншоте, вместо этого, если я закрываю окно с помощью кнопки X в окне, приложение закрывается правильно, потому что другие потоки не активны. Я хочу добиться такого же поведения с помощью кнопки закрытия, которую я создал... Я использую JDK 7. - person aleroot; 14.10.2011
comment
Попробуйте это в JDK 6. Если он показывает другое поведение в (пока еще очень глючной) Java 7, это, вероятно, .. ошибка. - person Andrew Thompson; 14.10.2011
comment
Только что запускал эту программу со сборкой 1.7.0-b147 и сборкой 1.6.0_25-b06, обе на х64 и нормально закрываются. Просто подумал, что я бы добавил некоторую поддержку, что это может быть проблема с версией. - person pimaster; 14.10.2011
comment
Извините, моя вина. Я оставил таймер запущенным, и это вызвало проблему, необходимо вызвать timer.cancel(), чтобы приложение закрылось правильно, однако я реализовал решение, предложенное mKorbel. Спасибо ! - person aleroot; 14.10.2011
comment
@пимастер. Спасибо за ваш результат. OP может добавить в код какое-то свойство (например, версию) и использовать его в качестве основы для отчета об ошибке. - person Andrew Thompson; 14.10.2011

Просто добавьте одну строку:

System.exit(0);
person Balconsky    schedule 14.10.2011
comment
Система.выход(0); закройте приложение также, если в другом потоке есть запущенный фоновый процесс, который убивает мой фоновый поток !! Я не хочу этого делать! - person aleroot; 14.10.2011
comment
Когда я ответил на этот вопрос, aleroot не говорил о фоновом процессе, а отредактировал свой вопрос после моего ответа. - person Balconsky; 14.10.2011