Как программно закрыть JFrame - PullRequest
233 голосов
/ 05 августа 2009

Как правильно получить закрытие JFrame, так же, как если бы пользователь нажал кнопку закрытия X или нажал Alt + F4 (вкл Windows)

Моя операция закрытия по умолчанию настроена так, как я хочу, через:

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Он делает именно то, что я хочу с вышеупомянутыми элементами управления. Этот вопрос не об этом.

Что я действительно хочу сделать, так это заставить графический интерфейс вести себя так же, как нажатие кнопки закрытия X приведет к его поведению.

Предположим, я должен был расширить WindowAdaptor, а затем добавить экземпляр моего адаптера в качестве прослушивателя через addWindowListener(). Я хотел бы видеть ту же последовательность вызовов через windowDeactivated(), windowClosing() и windowClosed(), как это происходит с кнопкой закрытия X. Не столько разорвать окно, сколько сказать так, чтобы оно разорвалось, так сказать.

Ответы [ 18 ]

298 голосов
/ 06 августа 2009

Если вы хотите, чтобы графический интерфейс вел себя так, как будто вы нажали кнопку закрытия X, вам нужно отправить событие закрытия окна на Window. ExitAction из Закрытие приложения позволяет добавить эту функцию к элементу меню или любому компоненту, который легко использует Action s.

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
124 голосов
/ 05 августа 2009
setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object

Не слишком сложно.

25 голосов
/ 05 августа 2009

Если под Alt-F4 или X вы имеете в виду «Немедленно выйти из приложения, безотносительно к тому, что работают другие окна или потоки», то System.exit(...) будет делать точно , что вы хотите, очень резко, грубая и, возможно, проблематичная мода.

Если под Alt-F4 или X вы подразумеваете скрытие окна, то frame.setVisible(false) - это то, как вы «закрываете» окно. Окно будет продолжать использовать ресурсы / память, но его можно будет снова быстро увидеть.

Если под Alt-F4 или X вы имеете в виду скрыть окно и утилизировать все ресурсы, которые оно потребляет, то frame.dispose() - это то, как вы «закрываете» окно. Если кадр был последним видимым окном и не запущены другие потоки, не являющиеся демонами, программа завершится. Если вы снова откроете окно, ему придется заново инициализировать все собственные ресурсы (графический буфер, дескрипторы окон и т. Д.).

dispose() может быть ближе всего к поведению, которое вы действительно хотите. Если в вашем приложении открыто несколько окон, хотите ли вы, чтобы Alt-F4 или X закрыли приложение или просто закрыли активное окно?

Учебник по Java Swing для оконных слушателей может помочь вам разобраться.

15 голосов
/ 28 марта 2011

Если вы сделали это, чтобы убедиться, что пользователь не может закрыть окно:

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

Тогда вам следует изменить pullThePlug() метод на

public void pullThePlug() {
    // this will make sure WindowListener.windowClosing() et al. will be called.
    WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
    Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);

    // this will hide and dispose the frame, so that the application quits by
    // itself if there is nothing else around. 
    setVisible(false);
    dispose();
    // if you have other similar frames around, you should dispose them, too.

    // finally, call this to really exit. 
    // i/o libraries such as WiiRemoteJ need this. 
    // also, this is what swing does for JFrame.EXIT_ON_CLOSE
    System.exit(0); 
}

Я обнаружил, что это единственный способ хорошо играть с WindowListener и JFrame.DO_NOTHING_ON_CLOSE.

8 голосов
/ 08 марта 2016

Выход из Java, запущенный процесс очень прост, в основном вам нужно сделать всего две простые вещи:

  1. Вызовите метод Java System.exit(...) в точке выхода приложения. Например, если ваше приложение основано на фреймах, вы можете добавить слушатель WindowAdapter и вызвать System.exit(...) внутри его метода windowClosing(WindowEvent e).

Примечание: вы должны позвонить System.exit(...), иначе ваша программа связана с ошибкой.

  1. Избегание непредвиденных исключений Java, чтобы всегда вызывать метод выхода. Если вы добавите System.exit(...) в нужную точку, но это не означает, что метод можно вызывать всегда, потому что непредвиденные исключения Java могут помешать вызову метода.

Это тесно связано с вашими навыками программирования.

** Ниже приведен простейший пример (на основе JFrame), в котором показано, как вызвать метод выхода

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

public class ExitApp extends JFrame
{
   public ExitApp()
   {
      addWindowListener(new WindowAdapter()
      {
         public void windowClosing(WindowEvent e)
         {
           dispose();
           System.exit(0); //calling the method is a must
         }
      });
   }

   public static void main(String[] args)
   {
      ExitApp app=new ExitApp();
      app.setBounds(133,100,532,400);
      app.setVisible(true);
   }
}
8 голосов
/ 22 января 2015

Вот ваши варианты:

System.exit(0); // stop program
frame.dispose(); // close window
frame.setVisible(false); // hide window
7 голосов
/ 09 января 2011

Не только для закрытия JFrame, но и для запуска событий WindowListener, попробуйте это:

myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
5 голосов
/ 05 августа 2009

setDefaultCloseOperation (WindowConstants.EXIT_ON_CLOSE);

Не только закрывает JFrame, но и закрывает все приложение, поэтому «EXIT ON CLOSE»

Для достижения того же результата вы должны эффективно выйти из приложения, для этого просто позвоните

 System.exit(0);

Эффект точно такой же.

4 голосов
/ 11 августа 2016

Если вы действительно не хотите, чтобы приложение закрывалось при закрытии JFrame,

использование: setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

вместо: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Вот краткий обзор того, как выглядит решение,

 myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
4 голосов
/ 25 июня 2011

Лучший способ закрыть рамку Swing программно - заставить ее вести себя так, как если бы нажата кнопка «X». Для этого вам нужно реализовать WindowAdapter, который соответствует вашим потребностям, и установить для операции закрытия по умолчанию фрейма ничего не делать (DO_NOTHING_ON_CLOSE).

Инициализируйте ваш кадр следующим образом:

private WindowAdapter windowAdapter = null;

private void initFrame() {

    this.windowAdapter = new WindowAdapter() {
        // WINDOW_CLOSING event handler
        @Override
        public void windowClosing(WindowEvent e) {
            super.windowClosing(e);
            // You can still stop closing if you want to
            int res = JOptionPane.showConfirmDialog(ClosableFrame.this, "Are you sure you want to close?", "Close?", JOptionPane.YES_NO_OPTION);
            if ( res == 0 ) {
                // dispose method issues the WINDOW_CLOSED event
                ClosableFrame.this.dispose();
            }
        }

        // WINDOW_CLOSED event handler
        @Override
        public void windowClosed(WindowEvent e) {
            super.windowClosed(e);
            // Close application if you want to with System.exit(0)
            // but don't forget to dispose of all resources 
            // like child frames, threads, ...
            // System.exit(0);
        }
    };

    // when you press "X" the WINDOW_CLOSING event is called but that is it
    // nothing else happens
    this.setDefaultCloseOperation(ClosableFrame.DO_NOTHING_ON_CLOSE);
    // don't forget this
    this.addWindowListener(this.windowAdapter);
}

Вы можете программно закрыть кадр, отправив ему событие WINDOW_CLOSING, например:

WindowEvent closingEvent = new WindowEvent(targetFrame, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(closingEvent);

Это закроет кадр, как была нажата кнопка «X».

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