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



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



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



setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


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



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



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

678   18  

18 ответов:

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

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object

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

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

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

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

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

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

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

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.

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

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

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

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

это сильно связано с вашими навыками программирования.

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

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

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

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

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

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

setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

не только закрывает JFrame, но и завершает работу всего приложения, следовательно, "выход на закрытие"

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

 System.exit(0);

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

лучший способ закрыть качели кадр программно, чтобы заставить его вести себя, как это было бы, когда кнопка "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".

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

окно имеет адаптер окна, который переключает операцию закрытия по умолчанию на 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));
    }
}

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

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

// frame stuffs here ...

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

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

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

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

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

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

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

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

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

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

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

размещение того, что было в теле вопроса, как 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's 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();

если вы не хотите, чтобы ваше приложение завершалось при закрытии 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() чтобы удалить все ресурсы собственного экрана.

скопировал из Питера Лэнг

https://stackoverflow.com/a/1944474/3782247

Я пробовал это, написать свой собственный код для 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);
    }
}    

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

 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

Comments

    Ничего не найдено.