Как программно закрыть JFrame

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

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

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

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

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

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

Ответ 1

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

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));

Ответ 2

setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object

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

Ответ 3

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

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

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

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

Java Swing Tutorial для Windows Listeners может помочь вам прояснить ситуацию.

Ответ 4

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

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.

Ответ 5

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

myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));

Ответ 6

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

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

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

  1. Избегайте неожиданных исключений java, чтобы убедиться, что метод exit можно вызвать всегда. Если вы добавите 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);
   }
}

Ответ 7

Лучший способ закрыть кадр 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".

Ответ 8

setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

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

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

 System.exit(0);

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

Ответ 9

В этом примере показано, как реализовать подтвержденную операцию закрытия окна.

В окне есть адаптер Window, который переключает операцию закрытия по умолчанию на EXIT_ON_CLOSE или DO_NOTHING_ON_CLOSE в зависимости от вашего ответа в OptionDialog.

Метод closeWindow ConfirmedCloseWindow запускает событие закрытого окна и может использоваться где угодно, например, в качестве действия пункта меню

public class WindowConfirmedCloseAdapter extends WindowAdapter {

    public void windowClosing(WindowEvent e) {

        Object options[] = {"Yes", "No"};

        int close = JOptionPane.showOptionDialog(e.getComponent(),
                "Really want to close this application?\n", "Attention",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.INFORMATION_MESSAGE,
                null,
                options,
                null);

        if(close == JOptionPane.YES_OPTION) {
           ((JFrame)e.getSource()).setDefaultCloseOperation(
                   JFrame.EXIT_ON_CLOSE);
        } else {
           ((JFrame)e.getSource()).setDefaultCloseOperation(
                   JFrame.DO_NOTHING_ON_CLOSE);
        }
    }
}

public class ConfirmedCloseWindow extends JFrame {

    public ConfirmedCloseWindow() {

        addWindowListener(new WindowConfirmedCloseAdapter());
    }

    private void closeWindow() {
        processWindowEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
    }
}

Ответ 10

Здесь будут ваши варианты:

System.exit(0); // stop program
frame.dispose(); // close window
frame.setVisible(false); // hide window

Ответ 11

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

use: setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

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

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

 myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));

Ответ 12

Вы должны вставить вызов в очередь сообщений AWT, чтобы все время было правильно, иначе оно не отправит правильную последовательность событий, особенно в многопоточной программе. Когда это будет сделано, вы можете обрабатывать результирующую последовательность событий точно так же, как если бы пользователь нажал кнопку [x] для ОС, которая позаимствовала декорированный JFrame.

public void closeWindow()
{
    if(awtWindow_ != null) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                awtWindow_.dispatchEvent(new WindowEvent(awtWindow_, WindowEvent.WINDOW_CLOSING));
            }
        });
    }
}

Ответ 13

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

JFrame frame= new JFrame()
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// frame stuffs here ...

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));

JFrame получает событие для закрытия и закрытия, завершает.

Ответ 14

Этот ответ дал Алекс, и я хотел бы порекомендовать его. Это сработало для меня, а другое - просто и просто.

setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object

Ответ 15

Проводка того, что было в теле вопроса как ответ CW.

Требуется поделиться результатами, в основном полученными из следующей ссылки camickr. В основном мне нужно выбросить WindowEvent.WINDOW_CLOSING в очередь событий приложения. Вот краткий обзор того, как выглядит решение

// closing down the window makes sense as a method, so here are
// the salient parts of what happens with the JFrame extending class ..

    public class FooWindow extends JFrame {
        public FooWindow() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBounds(5, 5, 400, 300);  // yeah yeah, this is an example ;P
            setVisible(true);
        }
        public void pullThePlug() {
                WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
        }
    }

// Here how that would be employed from elsewhere -

    // someplace the window gets created ..
    FooWindow fooey = new FooWindow();
    ...
    // and someplace else, you can close it thusly
    fooey.pullThePlug();

Ответ 16

Если вы не хотите, чтобы ваше приложение прекращалось при закрытии JFrame, использовать:   setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE)

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

Из документации:

DO_NOTHING_ON_CLOSE (defined in WindowConstants): ничего не делайте; требуют, чтобы программа обрабатывала операцию в методе windowClosing зарегистрированного объекта WindowListener.

HIDE_ON_CLOSE (defined in WindowConstants): автоматически скрыть кадр после вызова любых зарегистрированных объектов WindowListener.

DISPOSE_ON_CLOSE (defined in WindowConstants): автоматически скрывать и удалять кадр после вызова любых зарегистрированных объектов WindowListener.

EXIT_ON_CLOSE (defined in JFrame): выйдите из приложения, используя метод выхода из системы. Используйте это только в приложениях.

может оказаться полезным: Вы можете использовать setVisible(false) в своем JFrame, если хотите снова отобразить тот же фрейм. В противном случае вызовите dispose(), чтобы удалить все исходные ресурсы экрана.

скопирован из Peter Lang

fooobar.com/questions/31367/...

Ответ 17

Я пробовал это, напишу свой собственный код для события formWindowClosing().

 private void formWindowClosing(java.awt.event.WindowEvent evt) {                                   
    int selectedOption = JOptionPane.showConfirmDialog(null,
            "Do you want to exit?",
            "FrameToClose",
            JOptionPane.YES_NO_OPTION);
    if (selectedOption == JOptionPane.YES_OPTION) {
        setVisible(false);
        dispose();
    } else {
        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
    }
}    

Это спрашивает пользователя, хочет ли он выйти из кадра или приложения.

Ответ 18

 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);