Como fechar programaticamente um JFrame

Qual é a maneira correta de fechar um JFrame , como se o usuário tivesse pressionado o botão X ou pressionado Alt + F4 (no Windows)?

Eu tenho a minha operação de fechamento padrão definida do jeito que eu quero, via:

 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

Faz exatamente o que eu quero com os controles acima mencionados. Esta questão não é sobre isso.

O que eu realmente quero fazer é fazer com que a GUI se comporte da mesma maneira que pressionar o botão de fechar X faria com que ela se comportasse.

Suponha que eu estendesse o WindowAdaptor e depois adicionasse uma instância do meu adaptador como ouvinte via addWindowListener() . Eu gostaria de ver a mesma seqüência de chamadas através de windowDeactivated() , windowClosing() e windowClosed() como ocorreria com o botão X close. Não tanto rasgando a janela como dizendo para se rasgar, por assim dizer.

Se você quiser que a GUI se comporte como se você tivesse clicado no botão X fechar, então você precisa despachar um evento de fechamento de janela para a Window . O ExitAction do fechamento de um aplicativo permite que você adicione essa funcionalidade a um item de menu ou a qualquer componente que use Action s facilmente.

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

Não é muito complicado.

Se por Alt-F4 ou X você quer dizer “Saia da aplicação imediatamente sem considerar o que outras janelas ou threads estão rodando”, então System.exit(...) fará exatamente o que você quer de uma força bruta, muito brusca, e possivelmente moda problemática.

Se por Alt-F4 ou X você quer dizer ocultar a janela, então frame.setVisible(false) é como você “fecha” a janela. A janela continuará a consumir resources / memory, mas pode se tornar visível novamente muito rapidamente.

Se por Alt-F4 ou X você quer dizer ocultar a janela e descartar quaisquer resources que esteja consumindo, então o frame.dispose() é como você “fecha” a janela. Se o quadro foi a última janela visível e não houver nenhum outro segmento não-daemon em execução, o programa será encerrado. Se você mostrar a janela novamente, terá que reinicializar todos os resources nativos novamente (buffer de charts, identificadores de janela, etc).

dispose() pode estar mais próximo do comportamento que você realmente quer. Se o seu aplicativo tiver várias janelas abertas, você deseja que o Alt-F4 ou o X feche o aplicativo ou apenas feche a janela ativa?

O Java Swing Tutorial em Window Listeners pode ajudar a esclarecer as coisas para você.

Se você fez isso para garantir que o usuário não feche a janela:

 frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 

Então você deve mudar o seu método pullThePlug() para ser

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

Eu acho que esta é a única maneira que funciona bem com o WindowListener e JFrame.DO_NOTHING_ON_CLOSE .

Sair do processo de execução do Java é muito fácil, basicamente você precisa fazer apenas duas coisas simples:

  1. Chame o método java System.exit(...) no ponto de encerramento do aplicativo. Por exemplo, se seu aplicativo é baseado em frameworks, você pode adicionar o WindowAdapter ouvinte e chamar System.exit(...) dentro de seu método windowClosing(WindowEvent e) .

Nota: você deve chamar System.exit(...) caso contrário, seu programa está com erro envolvido.

  1. Evitando exceções de java inesperadas para garantir que o método de saída possa ser chamado sempre. Se você adicionar System.exit(...) no ponto direito, mas isso não significa que o método pode ser chamado sempre, porque exceções inesperadas do java podem impedir que o método seja chamado.

Isso está fortemente relacionado às suas habilidades de programação.

** A seguir está uma amostra mais simples (baseada em JFrame ) que mostra como chamar o método de saída

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

Aqui seria suas opções:

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

Não apenas para fechar o JFrame, mas também para acionar events WindowListener, tente isto:

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

setDefaultCloseOperation (WindowConstants.EXIT_ON_CLOSE);

Não só fecha o JFrame, mas o desligamento de todo o aplicativo, portanto “EXIT ON CLOSE”

Para conseguir o mesmo resultado você tem que efetivamente sair do aplicativo, para isso basta ligar

  System.exit(0); 

O efeito é exatamente o mesmo.

A melhor maneira de fechar um quadro Swing programaticamente é fazer com que ele se comporte como se o botão “X” fosse pressionado. Para fazer isso, você precisará implementar o WindowAdapter que atenda às suas necessidades e definir a operação de fechamento padrão do quadro para não fazer nada (DO_NOTHING_ON_CLOSE).

Inicialize seu quadro assim:

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

Você pode fechar o quadro programaticamente enviando-lhe o evento WINDOW_CLOSING, desta forma:

 WindowEvent closingEvent = new WindowEvent(targetFrame, WindowEvent.WINDOW_CLOSING); Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(closingEvent); 

Isso fechará o quadro como o botão “X” foi pressionado.

Este exemplo mostra como realizar a operação de fechamento da janela confirmada.

A janela tem um adaptador de janela que alterna a operação de fechamento padrão para EXIT_ON_CLOSE ou DO_NOTHING_ON_CLOSE dependendo da sua resposta no OptionDialog .

O método closeWindow do ConfirmedCloseWindow triggers um evento window close e pode ser usado em qualquer lugar, ou seja, como uma ação de um item de menu.

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

Com base nas respostas já fornecidas aqui, esta é a maneira que eu implementei:

 JFrame frame= new JFrame() frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // frame stuffs here ... frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING)); 

O JFrame faz o evento fechar e após o fechamento sai.

Se você realmente não quiser que seu aplicativo seja encerrado quando um JFrame for fechado,

use: setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

em vez de: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Aqui está uma sinopse da aparência da solução,

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

Esta resposta foi dada por Alex e eu gostaria de recomendá-lo. Funcionou para mim e outra coisa é simples e simples.

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

Você precisa inserir a chamada na fila de mensagens do AWT para que toda a synchronization ocorra corretamente, caso contrário, ela não enviará a sequência de events correta, especialmente em um programa multiencadeado. Quando isso for feito, você poderá manipular a sequência de events resultante exatamente como faria se o usuário clicasse no botão [x] de um JFrame decorado com SO suppled.

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

Postando o que estava no corpo da pergunta como resposta da CW.

Queria compartilhar os resultados, principalmente derivados do seguinte link do camickr. Basicamente eu preciso lançar um WindowEvent.WINDOW_CLOSING na fila de events do aplicativo. Aqui está uma sinopse do que a solução parece

 // 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(); 

Se você não quiser que seu aplicativo termine quando um JFrame for fechado, use: setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE)

em vez de: setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

Da documentação:

DO_NOTHING_ON_CLOSE (defined in WindowConstants) : não faça nada; Exija que o programa manipule a operação no método windowClosing de um object WindowListener registrado.

HIDE_ON_CLOSE (defined in WindowConstants) : oculta automaticamente o quadro após chamar qualquer object WindowListener registrado.

DISPOSE_ON_CLOSE (defined in WindowConstants) : oculta e descarta automaticamente o quadro após chamar qualquer object WindowListener registrado.

EXIT_ON_CLOSE (defined in JFrame) : Saia do aplicativo usando o método de saída do sistema. Use isso apenas em aplicativos.

ainda pode ser útil: você pode usar setVisible(false) no seu JFrame se quiser exibir o mesmo quadro novamente. Caso contrário, chame dispose() para remover todos os resources da canvas nativa.

copiado de Peter Lang

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

Eu tentei isso, escrever seu próprio código para o evento 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); } } 

Isso pergunta ao usuário se ele deseja sair do quadro ou do aplicativo.

  setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);