Как программно закрыть JFrame
Каков правильный способ закрыть JFrame
, как если бы пользователь нажал кнопку закрытия X
или нажал Alt + F4 (в Windows)?
У меня есть настройка по умолчанию, установленная так, как я хочу, через:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Он делает именно то, что я хочу, с вышеупомянутыми элементами управления. Этот вопрос не об этом.
- Как нарисовать дерево, представляющее график подключенных узлов?
- Как рассчитать количество строк (и столбцов в каждой строке), которые текст принимает в JTextArea?
- Обнаружение нескольких нажатий клавиш в java
- «Заполнить» символы Юникода в ярлыках
- Как использовать TextAction
То, что я действительно хочу сделать, – это заставить графический интерфейс вести себя так же, как нажатие кнопки закрытия X
приведет к его поведению.
Предположим, я должен расширить WindowAdaptor
а затем добавить экземпляр моего адаптера в качестве слушателя через addWindowListener()
. Я хотел бы видеть ту же последовательность вызовов через windowDeactivated()
, windowClosing()
и windowClosed()
что и при нажатии кнопки закрытия X
Не так много разрывает окно, как говорит ему, чтобы так оторваться.
- Центрирование текста в JTextArea или JTextPane - горизонтальное выравнивание текста
- Какова связь между ContentPane и JPanel?
- Как сделать прозрачный JFrame, но оставить все остальное одинаковым?
- Терминал Java Linux в JPanel
- Пользовательская кнопка, не работающая с mac (ButtonUI)
- Является ли это правильным способом использования Java 2D Graphics API?
- Печать большого компонента Swing
- Графический рендеринг в строке заголовка
Если вы хотите, чтобы графический интерфейс работал так, как если бы вы нажали кнопку закрытия X
, вам нужно отправить событие закрытия windows в 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 или streamи запущены», то System.exit(...)
будет делать именно то , что вы хотите, в очень резкой, грубой силе, и, возможно, проблематично.
Если по Alt-F4 или X вы хотите скрыть окно, то frame.setVisible(false)
– это то, как вы «закрываете» окно. Окно будет продолжать потреблять ресурсы / память, но может быть сделано видимым снова очень быстро.
Если по Alt-F4 или X вы хотите скрыть окно и избавиться от любых ресурсов, которые он потребляет, то frame.dispose()
– это то, как вы «закрываете» окно. Если кадр был последним видимым окном, и нет других streamов не-daemon, программа завершит работу. Если вы снова покажете окно, ему придется повторно инициализировать все собственные ресурсы снова (графический буфер, дескрипторы окон и т. Д.).
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); }
Я нашел, что это единственный способ, который отлично играет с JFrame.DO_NOTHING_ON_CLOSE
и JFrame.DO_NOTHING_ON_CLOSE
.
Выход из запущенного Java процесса очень прост, в основном вам нужно сделать всего две простые вещи:
- Вызовите java метод
System.exit(...)
в точке выхода приложения. Например, если ваше приложение основано наWindowAdapter
, вы можете добавить listenerWindowAdapter
и вызватьSystem.exit(...)
внутри своегоwindowClosing(WindowEvent e)
.
Примечание: вы должны вызвать System.exit(...)
иначе ваша программа будет связана с ошибкой.
- Избегайте неожиданных исключений 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); } }
Здесь будут ваши варианты:
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, но и отключает все приложение, поэтому «EXIT ON CLOSE»
Чтобы добиться такого же результата, вам нужно эффективно выйти из приложения, потому что для этого просто позвоните
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».
В этом примере показано, как реализовать подтвержденную операцию закрытия windows.
В окне есть адаптер Window, который переключает операцию закрытия по умолчанию на EXIT_ON_CLOSE
или DO_NOTHING_ON_CLOSE
зависимости от вашего ответа в OptionDialog
.
Метод closeWindow
из ConfirmedCloseWindow
запускает событие closeWindow
windows и может использоваться где угодно, например, в качестве действия элемента меню
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 закрывается,
use: 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] для ОС, которая позаимствовала оформленный 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)
: автоматически скрывать и DISPOSE_ON_CLOSE (defined in WindowConstants)
кадр после вызова любых зарегистрированных объектов WindowListener.
EXIT_ON_CLOSE (defined in JFrame)
: выход из приложения с помощью метода выхода системы. Используйте это только в приложениях.
может по-прежнему быть полезным: вы можете использовать setVisible(false)
на вашем JFrame, если вы хотите снова отобразить тот же кадр. В противном случае вызовите dispose()
чтобы удалить все ресурсы собственного экрана.
Скопировано из Питера Ланга
Я попробовал это, напишите свой собственный код для события 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);