Pregunta

¿Cuál es la forma correcta de cerrar un JFrame , lo mismo que si el usuario hubiera presionado el botón de cierre X o presionado Alt + F4 (en Windows)?

Tengo mi operación de cierre predeterminada configurada de la manera que quiero, a través de:

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Hace exactamente lo que quiero con los controles antes mencionados. Esta pregunta no se trata de eso.

Lo que realmente quiero hacer es hacer que la GUI se comporte de la misma manera que presionar el botón de cierre X haría que se comportara.

Suponga que extendiera WindowAdaptor y luego agregue una instancia de mi adaptador como escucha a través de addWindowListener () . Me gustaría ver la misma secuencia de llamadas a través de windowDeactivated () , windowClosing () y windowClosed () como ocurriría con < code> X botón de cierre. No tanto romper la ventana como decirle que se rompa, por así decirlo.

¿Fue útil?

Solución

Si desea que la GUI se comporte como si hiciera clic en el botón de cierre X , debe enviar un evento de cierre de ventana a la Ventana . La ExitAction de Cerrar una aplicación le permite agregar esta funcionalidad a un elemento de menú o cualquier componente que use Action s fácilmente.

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

Otros consejos

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

No demasiado complicado.

Si con Alt-F4 o X te refieres a "Salir de la aplicación inmediatamente sin tener en cuenta qué otras ventanas o subprocesos se están ejecutando", entonces System.exit (...) hará exactamente lo que quieres de una manera muy brusca, con fuerza bruta y posiblemente problemática.

Si con Alt-F4 o X te refieres a ocultar la ventana, entonces frame.setVisible (false) es cómo " cierra " la ventana. La ventana continuará consumiendo recursos / memoria, pero puede volverse visible nuevamente muy rápidamente.

Si con Alt-F4 o X te refieres a ocultar la ventana y eliminar cualquier recurso que esté consumiendo, entonces frame.dispose () es cómo " cierra " la ventana. Si el marco era la última ventana visible y no hay otros subprocesos no daemon en ejecución, el programa se cerrará. Si vuelve a mostrar la ventana, tendrá que reinicializar todos los recursos nativos nuevamente (búfer de gráficos, identificadores de ventana, etc.).

dispose () podría estar más cerca del comportamiento que realmente desea. Si su aplicación tiene varias ventanas abiertas, ¿desea que Alt-F4 o X salgan de la aplicación o simplemente cierren la ventana activa?

El Java Swing Tutorial en Window Listeners puede ayudar a aclarar las cosas para usted.

Si ha hecho esto para asegurarse de que el usuario no pueda cerrar la ventana:

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

Entonces debe cambiar su método pullThePlug () para que sea

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

Encontré que esta es la única forma en que funciona bien con WindowListener y JFrame.DO_NOTHING_ON_CLOSE .

Estas serían sus opciones:

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

Salir del proceso de ejecución de Java es muy fácil, básicamente debes hacer solo dos cosas simples:

  1. Llame al método java System.exit (...) en el punto de cierre de la aplicación. Por ejemplo, si su aplicación está basada en marcos, puede agregar el receptor WindowAdapter y llamar a System.exit (...) dentro de su método windowClosing (WindowEvent e ) .

Nota: debe llamar a System.exit (...) ; de lo contrario, su programa tiene errores.

  1. Evitar excepciones inesperadas de Java para asegurarse de que siempre se pueda llamar al método de salida. Si agrega System.exit (...) en el punto correcto, pero no significa que se pueda llamar siempre al método, porque las excepciones inesperadas de Java pueden evitar que se llame al método.

Esto está fuertemente relacionado con tus habilidades de programación.

** A continuación se muestra una muestra más simple ( JFrame ) que le muestra cómo llamar al método de salida

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

No solo para cerrar JFrame sino también para activar eventos WindowListener, intente esto:

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

setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

No solo cierra el JFrame sino que cierra la aplicación completa, por lo tanto, "SALIR AL CERRAR"

Para lograr el mismo resultado, debe salir efectivamente de la aplicación, para eso simplemente llame

 System.exit(0);

El efecto es exactamente el mismo.

La mejor manera de cerrar un marco Swing mediante programación es hacer que se comporte como lo haría cuando la "X" Se presiona el botón. Para hacerlo, deberá implementar WindowAdapter que se adapte a sus necesidades y establecer la operación de cierre predeterminada del marco para que no haga nada (DO_NOTHING_ON_CLOSE).

Inicialice su marco de esta manera:

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

Puede cerrar el marco mediante programación enviándole el evento WINDOW_CLOSING, de esta manera:

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

Esto cerrará el marco como la "X" se presionó el botón.

Si realmente no desea que su aplicación finalice cuando se cierra un JFrame,

uso: setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

en lugar de: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Aquí hay una sinopsis de cómo se ve la solución,

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

Este ejemplo muestra cómo realizar la operación de cierre de ventana confirmada.

La ventana tiene un adaptador de ventana que cambia la operación de cierre predeterminada a EXIT_ON_CLOSE o DO_NOTHING_ON_CLOSE dependiendo de su respuesta en el OptionDialog .

El método closeWindow del ConfirmedCloseWindow activa un evento de cerrar ventana y puede usarse en cualquier lugar, es decir, como una acción de un elemento de menú

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

Basado en las respuestas ya proporcionadas aquí, esta es la forma en que lo implementé:

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

// frame stuffs here ...

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

El JFrame cierra el evento y, al cerrar, sale.

Esta respuesta fue dada por Alex y me gustaría recomendarla. Funcionó para mí y otra cosa es sencilla y muy simple.

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

Debe insertar la llamada en la cola de mensajes AWT para que todos los tiempos ocurran correctamente, de lo contrario no se enviará la secuencia de eventos correcta, especialmente en un programa de subprocesos múltiples. Una vez hecho esto, puede manejar la secuencia de eventos resultante exactamente como lo haría si el usuario hubiera hecho clic en el botón [x] para un JFrame decorado con sistema operativo.

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

He intentado esto, escriba su propio código para el 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);
    }
}    

Esto le pregunta al usuario si desea salir del Marco o la Aplicación.

Publicar lo que había en el cuerpo de la pregunta como respuesta de CW.

Quería compartir los resultados, principalmente derivados del siguiente enlace de camickr. Básicamente, necesito lanzar un WindowEvent.WINDOW_CLOSING en la cola de eventos de la aplicación. Aquí hay una sinopsis de cómo se ve la solución

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

Si no desea que su aplicación finalice cuando se cierra un JFrame, utilizar:     setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE)

en lugar de:     setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

De la documentación:

DO_NOTHING_ON_CLOSE (definido en WindowConstants) : no haga nada; requiere que el programa maneje la operación en el método windowClosing de un objeto WindowListener registrado.

HIDE_ON_CLOSE (definido en WindowConstants) : oculta automáticamente el marco después de invocar cualquier objeto registrado de WindowListener.

DISPOSE_ON_CLOSE (definido en WindowConstants) : oculta y desecha automáticamente el marco después de invocar cualquier objeto registrado de WindowListener.

EXIT_ON_CLOSE (definido en JFrame) : salga de la aplicación utilizando el método de salida del sistema. Use esto solo en aplicaciones.

aún podría ser útil: Puede usar setVisible (false) en su JFrame si desea mostrar el mismo marco nuevamente. De lo contrario, llame a dispose () para eliminar todos los recursos de la pantalla nativa.

copiado de Peter Lang

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

 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top