2016-04-04 10 views
0

Ich möchte ein Java-Fenster schließen, selbst wenn gerade eine Funktion ausgeführt wird - gibt es eine Möglichkeit, dies zu tun? Ich habe einige Funktionen, die unter bestimmten Bedingungen (z. B. von einer CD oder einem anderen nicht lokalen Ort) eine ganze Weile dauern und ich möchte diese Funktionen zwangsweise anhalten und das Programm vollständig beenden können. Ist das möglich? Und wie kann ich es tun?Wie erzwinge das Schließen eines Fensters in Java?

Mein Code zum Verlassen unter:

this.addWindowListener(new java.awt.event.WindowAdapter() { 
    @Override 
    public void windowClosing(java.awt.event.WindowEvent windowEvent) { 
     if (closeApplication()) { 
      System.exit(0); 
     } 
    } 
}); 

Und die closeApplication() Funktion:

private boolean closeApplication() { 
    final JFrame temp = this; 
    int exitDialogResult = JOptionPane.showConfirmDialog(temp, 
      "Are you sure you want to exit?", "Really Closing?", 
      JOptionPane.YES_NO_OPTION, 
      JOptionPane.QUESTION_MESSAGE); 
    if (exitDialogResult == JOptionPane.YES_OPTION) { 
      //code here to stop various processes    
      return true; 
     } 
    else { 
     return false; 
    } 
} 

Schnell bearbeiten zu klären: Wenn mein Programm eine lange Lauffunktion ausführt und ich versuche, Um das Fenster zu schließen, registriert der Fenster-Listener den Klick nicht einmal.

+0

['System.exit (x)'] (https: // docs.oracle.com/javase/8/docs/api/java/lang/System.html#exit-int-) hält die JVM an. Was stimmt damit nicht? – bcsb1001

+0

@ bcsb1001 Der Fenster-Listener wird überhaupt nicht getroffen - es ist ein Problem, tatsächlich auf diesen Aufruf zuzugreifen, anstatt ihn erst zu machen, nachdem das Close-Event ausgelöst wurde. – Charlotte

Antwort

3

Das Problem, mit dem Sie konfrontiert sind, liegt auf der Hand: Ihre Anwendungen werden während einer langen laufenden Hintergrundaufgabe "eingefroren", weil sie im Ereignisversand-Thread ausgeführt wird. Verwenden Sie SwingWorker. Auf diese Weise bleibt Ihre GUI reaktiv, während Ihre lange laufende Aufgabe im Hintergrundthread ausgeführt wird. Sie können System.exit() für die Beendigung verwenden, aber am sichersten wäre es zu warten, bis Ihre langwierige Aufgabe erledigt ist.

+1

Ich habe einen SwingWorker benutzt, danke für deine Hilfe! Ich weiß nicht viel über das Threading in Java, aber du hast mich in die richtige Richtung gelenkt, also danke :) – Charlotte

1

Es sieht so aus, als würden Sie Ihre lang laufenden Operationen im Ereignisversand-Thread ausführen. Dies ist der Thread, der von der GUI verwendet wird, um alle Ereignisse auszulösen. Wenn Sie diesen Thread blockieren, wird Ihre GUI blockiert. Der Schließvorgang eines JFrame ist einer dieser Vorgänge. Dies ist der Grund, warum es nicht ausgelöst wird, während eine lang andauernde Operation im GUI-Thread ausgeführt wird.

Um dies zu beheben, sollten Sie darüber nachdenken, was die lang andauernde Operation macht. In jedem Fall sollten Sie es auf einem Hintergrund-Thread verschieben:

  • Ist es eine Operation auszuführen, die jederzeit abgebrochen werden kann, ohne schlechte Dinge passiert? In diesem Fall können Sie die Operation in einen Daemon-Thread einfügen. Dies teilt der JVM mit, dass dieser Thread jederzeit beendet werden kann. Es sollte die JVM nicht am Leben erhalten. Ein Beispiel hierfür ist eine Operation, die Informationen von einer Web-API anfordert.

  • sonst Wenn schlimme Dinge passieren, wenn Sie die lang andauernde Operation zu irgendeinem Zeitpunkt beenden, sollten Sie die Operation in einen Nicht-Daemon-Thread einfügen. In diesem Fall ist es auch eine schlechte Idee, System.exit zu verwenden, um Ihre Anwendung herunterzufahren, da dies auch nur die Nicht-Daemon-Threads beenden wird. Sie müssen einen Mechanismus implementieren, der den Hintergrund-Thread elegant beendet oder darauf wartet, dass er beendet wird. Dies kann manchmal schwierig sein, aber es ist notwendig. Ein Beispiel für diese Art von Langzeitoperation ist das Schreiben in eine Datei: Wenn Sie diese Operation nur beenden, wird die Datei beschädigt.

Siehe auch What is Daemon thread in Java?

Wenn Sie eine ExecutorService für lang laufende Operationen verwenden, dann könnten Sie in der Methode ExecutorService::shutdown interessieren:

Leitet ein ordnungsgemäßes Abschalten, in dem zuvor übergebene Aufgaben werden ausgeführt, aber keine neuen Aufgaben werden akzeptiert.