2009-08-05 2 views
212

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

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

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

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

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

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

+10

В чем проблема с использованием утилизации? Так я всегда это делал. – job

+1

Да, jFrame.dispose() должен закрыть окно и очистить все до? –

+3

Потому что dispose не эквивалентен 1: 1 закрытию окна, щелкнув по [x]? – greenoldman

ответ

256

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

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

Нужно ли добавить this.jframe.addWindowListener (новый WindowAdapter() { @Override public void windowClosing (WindowEvent e) { e.getWindow(). Dispose(); } }); до вызова этого? Или он закроет окно? – momomo

+0

вопрос был о том, как закрыть рамку, этот принятый ответ, следовательно, отсутствует в этой части. Этот ответ просто вызывает потенциального слушателя, но ничего не говорит о его необходимости, чтобы адекватно ответить на этот вопрос. «Если вы хотите, чтобы GUI вел себя так, как будто вы нажали на кнопку X close». Нет, это не произойдет, если у вас нет слушателя, который также располагает фреймом. – momomo

+0

«Как программно закрыть JFrame» - если JFrame.EXIT_ON_CLOSE не установлен, он не будет закрыт.Во всяком случае, я просто указывал, что может потребоваться добавить к ответу, поскольку jframe.setDefaultCloseOperation (WindowConstants.DO_NOTHING_ON_CLOSE); фактически не закрывает его, вызывая это событие, несмотря на то, что пользователь обычно может закрыть окно на X, даже если DO_NOTHING_ON_CLOSE установлен, но увольнение этого события не будет. Увидеть разницу? – momomo

5

setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

не только закрывает JFrame, но на простои все приложения, следовательно, «EXIT ON CLOSE»

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

System.exit(0); 

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

+0

Что такое с голосом? : ( – OscarRyz

+4

-1: Не совсем то же самое: с 'JFrame.EXIT_ON_CLOSE',' WindowListener', которые были добавлены в фрейм, называются первыми. Я использую их для освобождения ресурсов аудиосистемы (реальный пример в моем случае) . –

0
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
+0

Это будет работать совместно с 'SetVisible (ложной)' ' .setVisible (ложь); .setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE).' – Abhijeet

24

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

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

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

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

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

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

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

+31

Но это не вызывает обработчики событий – Bombe

+6

Кроме того, если это будет Close, процесс остается в фоновом режиме. –

+0

Нет, если операция закрытия по умолчанию находится на EXIT_ON_CLOSE или прослушиватель кнопки выполняет любое необходимое закрытие ресурсов. –

6

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

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

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

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

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

4

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

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

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

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

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

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

// frame stuffs here ... 

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

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

2

Ставка ¥ особые пометки Для покупок необходима авторизация Ставка ¥ особые пометки Для покупок необходима авторизация Публикация что было в теме body как 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(); 
4

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

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

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

6

Выход из процесса, запущенного 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); 
    } 
} 
4

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

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

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

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

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

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

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

3

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

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

Какова ценность повторения ответа (с +90 голосами) и того, что он сработал для вас? Возможно, вы должны подтвердить, что это сработало для вас в комментарии к ответу, который вы повторили? –

+0

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

+0

Я понимаю, что вы говорите, но предположите, что каждый, кто использовал ответ, который работал, добавляет ответ, говоря, что другой ответ сработал для меня. Как это будет выглядеть? Сотни ответов являются повторением других ответов. IMO лучше поднять ответ, который сработал для вас, может оставить комментарий к ответу, если он добавит какую-либо ценность. –