Вопрос

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

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

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

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

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

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

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

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

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

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 .

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

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

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

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

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

      ** Ниже приведен простейший пример (на основе 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);
         }
      }
      

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

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

    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    Не только закрывает JFrame, но и выключает все приложение, следовательно, «ВЫХОД ПРИ ЗАКРЫТИИ».

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

     System.exit(0);
    

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

    Лучший способ закрыть фрейм 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 " кнопка была нажата.

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

    use: setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE);

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

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

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

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

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

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

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

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

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

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

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

    Публикация того, что было в теле вопроса, в качестве ответа 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 (определено в WindowConstants) : ничего не делать; требуется, чтобы программа обрабатывала операцию в методе windowClosing зарегистрированного объекта WindowListener.

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

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

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

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

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

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

     setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top